summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/isp/isp.c19
-rw-r--r--sys/dev/isp/isp_freebsd.c34
-rw-r--r--sys/dev/isp/isp_library.c147
-rw-r--r--sys/dev/isp/isp_library.h8
-rw-r--r--sys/dev/isp/isp_pci.c16
-rw-r--r--sys/dev/isp/isp_sbus.c8
-rw-r--r--sys/dev/isp/ispmbox.h5
-rw-r--r--sys/dev/isp/ispvar.h58
8 files changed, 186 insertions, 109 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 3f22d72..1945e4f 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -694,7 +694,7 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", mbs.param[0]);
+ isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
ISP_RESET0(isp);
return;
}
@@ -4417,7 +4417,7 @@ isp_start(XS_T *xs)
*tptr = 0x1999;
}
- if (isp_save_xs(isp, xs, &handle)) {
+ if (isp_allocate_xs(isp, xs, &handle)) {
isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
@@ -5163,8 +5163,8 @@ again:
}
}
- if ((sp->req_handle != ISP_SPCL_HANDLE) && (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) {
- isp_prt(isp, ISP_LOGERR, "bad request handle %d (type 0x%x)", sp->req_handle, etype);
+ if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
+ isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
@@ -5178,7 +5178,7 @@ again:
*/
if (etype != RQSTYPE_RESPONSE) {
isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
- } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED && sp->req_handle != ISP_SPCL_HANDLE) {
+ } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
}
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
@@ -5681,16 +5681,19 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
* commands that complete (with no apparent error) after
* we receive a LIP. This has been observed mostly on
* Local Loop topologies. To be safe, let's just mark
- * all active commands as dead.
+ * all active initiator commands as dead.
*/
if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
int i, j;
for (i = j = 0; i < isp->isp_maxcmds; i++) {
XS_T *xs;
- xs = isp->isp_xflist[i];
- if (xs == NULL) {
+ isp_hdl_t *hdp;
+
+ hdp = &isp->isp_xflist[i];
+ if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
continue;
}
+ xs = hdp->cmd;
if (XS_CHANNEL(xs) != chan) {
continue;
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 2861d7b..cd6ec09 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -1653,7 +1653,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb)
cto->ct_timeout = 10;
}
- if (isp_save_xs_tgt(isp, ccb, &handle)) {
+ if (isp_allocate_xs_tgt(isp, ccb, &handle)) {
xpt_print(ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
goto out;
@@ -3834,21 +3834,41 @@ isp_watchdog(void *arg)
isp = XS_ISP(xs);
handle = isp_find_handle(isp, xs);
- if (handle) {
+ if (handle != ISP_HANDLE_FREE) {
/*
- * Make sure the command is *really* dead before we
- * release the handle (and DMA resources) for reuse.
+ * Try and make sure the command is really dead before
+ * we release the handle (and DMA resources) for reuse.
+ *
+ * If we are successful in aborting the command then
+ * we're done here because we'll get the command returned
+ * back separately.
+ */
+ if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) {
+ return;
+ }
+
+ /*
+ * Note that after calling the above, the command may in
+ * fact have been completed.
*/
- (void) isp_control(isp, ISPCTL_ABORT_CMD, xs);
+ xs = isp_find_xs(isp, handle);
+
+ /*
+ * If the command no longer exists, then we won't
+ * be able to find the xs again with this handle.
+ */
+ if (xs == NULL) {
+ return;
+ }
/*
- * After this point, the comamnd is really dead.
+ * After this point, the command is really dead.
*/
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, handle);
}
isp_destroy_handle(isp, handle);
- xpt_print(xs->ccb_h.path, "watchdog timeout for handle 0x%x\n", handle);
+ isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle);
XS_SETERR(xs, CAM_CMD_TIMEOUT);
isp_done(xs);
}
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index acc2492..877303e 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -246,65 +246,70 @@ copy_and_sync:
}
int
-isp_save_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep)
+isp_allocate_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep)
{
- uint16_t i, j;
+ isp_hdl_t *hdp;
- for (j = isp->isp_lasthdls, i = 0; i < isp->isp_maxcmds; i++) {
- if (isp->isp_xflist[j] == NULL) {
- break;
- }
- if (++j == isp->isp_maxcmds) {
- j = 0;
- }
- }
- if (i == isp->isp_maxcmds) {
+ hdp = isp->isp_xffree;
+ if (hdp == NULL) {
return (-1);
}
- isp->isp_xflist[j] = xs;
- *handlep = j+1;
- if (++j == isp->isp_maxcmds) {
- j = 0;
- }
- isp->isp_lasthdls = (uint32_t)j;
+ isp->isp_xffree = hdp->cmd;
+ hdp->cmd = xs;
+ hdp->handle = (hdp - isp->isp_xflist);
+ hdp->handle |= (ISP_HANDLE_INITIATOR << ISP_HANDLE_USAGE_SHIFT);
+ hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
+ *handlep = hdp->handle;
return (0);
}
XS_T *
isp_find_xs(ispsoftc_t *isp, uint32_t handle)
{
- if (handle < 1 || handle > (uint32_t) isp->isp_maxcmds) {
+ if (!ISP_VALID_INI_HANDLE(isp, handle)) {
+ isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (NULL);
- } else {
- return (isp->isp_xflist[handle - 1]);
}
+ return (isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].cmd);
}
uint32_t
isp_find_handle(ispsoftc_t *isp, XS_T *xs)
{
- uint16_t i;
+ uint32_t i, foundhdl = ISP_HANDLE_FREE;
+
if (xs != NULL) {
for (i = 0; i < isp->isp_maxcmds; i++) {
- if (isp->isp_xflist[i] == xs) {
- return ((uint32_t) (i+1));
+ if (isp->isp_xflist[i].cmd != xs) {
+ continue;
}
+ foundhdl = isp->isp_xflist[i].handle;
+ break;
}
}
- return (0);
+ return (foundhdl);
}
uint32_t
-isp_handle_index(uint32_t handle)
+isp_handle_index(ispsoftc_t *isp, uint32_t handle)
{
- return (handle - 1);
+ if (!ISP_VALID_HANDLE(isp, handle)) {
+ return (handle & ISP_HANDLE_CMD_MASK);
+ } else {
+ isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
+ return (ISP_BAD_HANDLE_INDEX);
+ }
}
void
isp_destroy_handle(ispsoftc_t *isp, uint32_t handle)
{
- if (handle > 0 && handle <= (uint32_t) isp->isp_maxcmds) {
- isp->isp_xflist[handle - 1] = NULL;
+ if (!ISP_VALID_INI_HANDLE(isp, handle)) {
+ isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
+ } else {
+ isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE;
+ isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].cmd = isp->isp_xffree;
+ isp->isp_xffree = &isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)];
}
}
@@ -617,54 +622,48 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
void
isp_clear_commands(ispsoftc_t *isp)
{
- XS_T *xs;
- uint32_t tmp, handle;
+ uint32_t tmp;
+ isp_hdl_t *hdp;
#ifdef ISP_TARGET_MODE
isp_notify_t notify;
#endif
for (tmp = 0; isp->isp_xflist && tmp < isp->isp_maxcmds; tmp++) {
- xs = isp->isp_xflist[tmp];
- if (xs == NULL) {
- continue;
- }
- handle = isp_find_handle(isp, xs);
- if (handle == 0) {
+ XS_T *xs;
+
+ hdp = &isp->isp_xflist[tmp];
+ if (hdp->handle == ISP_HANDLE_FREE) {
continue;
}
+ xs = hdp->cmd;
if (XS_XFRLEN(xs)) {
- ISP_DMAFREE(isp, xs, handle);
+ ISP_DMAFREE(isp, xs, hdp->handle);
XS_SET_RESID(xs, XS_XFRLEN(xs));
} else {
XS_SET_RESID(xs, 0);
}
- isp_destroy_handle(isp, handle);
+ hdp->handle = 0;
+ hdp->cmd = NULL;
XS_SETERR(xs, HBA_BUSRESET);
isp_done(xs);
}
#ifdef ISP_TARGET_MODE
for (tmp = 0; isp->isp_tgtlist && tmp < isp->isp_maxcmds; tmp++) {
uint8_t local[QENTRY_LEN];
-
- xs = isp->isp_tgtlist[tmp];
- if (xs == NULL) {
- continue;
- }
- handle = isp_find_tgt_handle(isp, xs);
- if (handle == 0) {
+ hdp = &isp->isp_tgt_xflist[tmp];
+ if (hdp->handle == ISP_HANDLE_FREE) {
continue;
}
- ISP_DMAFREE(isp, xs, handle);
-
+ ISP_DMAFREE(isp, hdp->cmd, hdp->handle);
ISP_MEMZERO(local, QENTRY_LEN);
if (IS_24XX(isp)) {
ct7_entry_t *ctio = (ct7_entry_t *) local;
- ctio->ct_syshandle = handle;
+ ctio->ct_syshandle = hdp->handle;
ctio->ct_nphdl = CT_HBA_RESET;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
} else if (IS_FC(isp)) {
ct2_entry_t *ctio = (ct2_entry_t *) local;
- ctio->ct_syshandle = handle;
+ ctio->ct_syshandle = hdp->handle;
ctio->ct_status = CT_HBA_RESET;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
} else {
@@ -2229,59 +2228,59 @@ isp_send_tgt_cmd(ispsoftc_t *isp, void *fqe, void *segp, uint32_t nsegs, uint32_
}
int
-isp_save_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep)
+isp_allocate_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep)
{
- int i;
+ isp_hdl_t *hdp;
- for (i = 0; i < (int) isp->isp_maxcmds; i++) {
- if (isp->isp_tgtlist[i] == NULL) {
- break;
- }
- }
- if (i == isp->isp_maxcmds) {
+ hdp = isp->isp_tgtfree;
+ if (hdp == NULL) {
return (-1);
}
- isp->isp_tgtlist[i] = xs;
- *handlep = (i+1) | 0x8000;
+ isp->isp_tgtfree = hdp->cmd;
+ hdp->cmd = xs;
+ hdp->handle = (hdp - isp->isp_tgtlist);
+ hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT);
+ hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
+ *handlep = hdp->handle;
return (0);
}
void *
isp_find_xs_tgt(ispsoftc_t *isp, uint32_t handle)
{
- if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 || (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) {
- isp_prt(isp, ISP_LOGERR, "bad handle %u in isp_find_xs_tgt", handle);
+ if (!ISP_VALID_TGT_HANDLE(isp, handle)) {
+ isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (NULL);
- } else {
- return (isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1]);
}
+ return (isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd);
}
uint32_t
isp_find_tgt_handle(ispsoftc_t *isp, void *xs)
{
- int i;
+ uint32_t i, foundhdl = ISP_HANDLE_FREE;
+
if (xs != NULL) {
for (i = 0; i < isp->isp_maxcmds; i++) {
- if (isp->isp_tgtlist[i] == xs) {
- uint32_t handle = i;
- handle += 1;
- handle &= ISP_HANDLE_MASK;
- handle |= 0x8000;
- return (handle);
+ if (isp->isp_tgtlist[i].cmd != xs) {
+ continue;
}
+ foundhdl = isp->isp_tgtlist[i].handle;
+ break;
}
}
- return (0);
+ return (foundhdl);
}
void
isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle)
{
- if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 || (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) {
- isp_prt(isp, ISP_LOGERR, "bad handle in isp_destroy_tgt_handle");
+ if (!ISP_VALID_TGT_HANDLE(handle)) {
+ isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
} else {
- isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1] = NULL;
+ isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE;
+ isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd = isp->isp_tgtfree;
+ isp->isp_tgtfree = &isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)];
}
}
diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h
index 9a9e397..b055dd8 100644
--- a/sys/dev/isp/isp_library.h
+++ b/sys/dev/isp/isp_library.h
@@ -43,10 +43,10 @@ int isp_send_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t);
*
* These handles are associate with a command.
*/
-int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *);
+int isp_allocate_xs(ispsoftc_t *, XS_T *, uint32_t *);
XS_T * isp_find_xs(ispsoftc_t *, uint32_t);
uint32_t isp_find_handle(ispsoftc_t *, XS_T *);
-uint32_t isp_handle_index(uint32_t);
+uint32_t isp_handle_index(ispsoftc_t *, uint32_t);
void isp_destroy_handle(ispsoftc_t *, uint32_t);
/*
@@ -156,9 +156,7 @@ void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
int isp_send_tgt_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t, void *, uint32_t);
-#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
-
-int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *);
+int isp_allocate_xs_tgt(ispsoftc_t *, void *, uint32_t *);
void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 47dd350..4eb2e0c 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1516,17 +1516,21 @@ isp_pci_mbxdma(ispsoftc_t *isp)
return (1);
}
- len = sizeof (XS_T **) * isp->isp_maxcmds;
- isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
+ len = sizeof (isp_hdl_t) * isp->isp_maxcmds;
+ isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
if (isp->isp_xflist == NULL) {
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
ISP_LOCK(isp);
isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array");
return (1);
}
+ for (len = 0; len < isp->isp_maxcmds - 1; len++) {
+ isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
+ }
+ isp->isp_xffree = isp->isp_xflist;
#ifdef ISP_TARGET_MODE
- len = sizeof (void **) * isp->isp_maxcmds;
- isp->isp_tgtlist = (void **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
+ len = sizeof (isp_hdl_t *) * isp->isp_maxcmds;
+ isp->isp_tgtlist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
if (isp->isp_tgtlist == NULL) {
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
free(isp->isp_xflist, M_DEVBUF);
@@ -1534,6 +1538,10 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, "cannot alloc tgtlist array");
return (1);
}
+ for (len = 0; len < isp->isp_maxcmds - 1; len++) {
+ isp->isp_tgtlist[len].cmd = &isp->isp_tgtlist[len+1];
+ }
+ isp->isp_tgtfree = isp->isp_tgtlist;
#endif
/*
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index a50d0f2..e2dd78f 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -455,13 +455,17 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
return (1);
}
- len = sizeof (XS_T **) * isp->isp_maxcmds;
- isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
+ len = sizeof (isp_hdl_t *) * isp->isp_maxcmds;
+ isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
if (isp->isp_xflist == NULL) {
isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array");
ISP_LOCK(isp);
return (1);
}
+ for (len = 0; len < isp->isp_maxcmds - 1; len++) {
+ isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
+ }
+ isp->isp_xffree = isp->isp_xflist;
len = sizeof (bus_dmamap_t) * isp->isp_maxcmds;
if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_SBD(isp)), 1,
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index 2f9d152..eb3ab63 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -288,11 +288,6 @@
#define QENTRY_LEN 64
/*
- * Special Internal Handle for IOCBs
- */
-#define ISP_SPCL_HANDLE 0xa5dead5a
-
-/*
* Command Structure Definitions
*/
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index e568a1c..5c8508c 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -50,7 +50,7 @@
#include "ispmbox.h"
#endif
-#define ISP_CORE_VERSION_MAJOR 6
+#define ISP_CORE_VERSION_MAJOR 7
#define ISP_CORE_VERSION_MINOR 0
/*
@@ -288,6 +288,53 @@ typedef struct {
#define DOMAIN_CONTROLLER_BASE 0xFFFC00
#define DOMAIN_CONTROLLER_END 0xFFFCFF
+/*
+ * Command Handles
+ *
+ * Most QLogic initiator or target have 32 bit handles associated with them.
+ * We want to have a quick way to index back and forth between a local SCSI
+ * command context and what the firmware is passing back to us. We also
+ * want to avoid working on stale information. This structure handles both
+ * at the expense of some local memory.
+ *
+ * The handle is architected thusly:
+ *
+ * 0 means "free handle"
+ * bits 0..12 index commands
+ * bits 13..15 bits index usage
+ * bits 16..31 contain a rolling sequence
+ *
+ *
+ */
+typedef struct {
+ void * cmd; /* associated command context */
+ uint32_t handle; /* handle associated with this command */
+} isp_hdl_t;
+#define ISP_HANDLE_FREE 0x00000000
+#define ISP_HANDLE_CMD_MASK 0x00001fff
+#define ISP_HANDLE_USAGE_MASK 0x0000e000
+#define ISP_HANDLE_USAGE_SHIFT 13
+#define ISP_H2HT(hdl) ((hdl & ISP_HANDLE_USAGE_MASK) >> ISP_HANDLE_USAGE_SHIFT)
+# define ISP_HANDLE_NONE 0
+# define ISP_HANDLE_INITIATOR 1
+# define ISP_HANDLE_TARGET 2
+#define ISP_HANDLE_SEQ_MASK 0xffff0000
+#define ISP_HANDLE_SEQ_SHIFT 16
+#define ISP_H2SEQ(hdl) ((hdl & ISP_HANDLE_SEQ_MASK) >> ISP_HANDLE_SEQ_SHIFT)
+#define ISP_VALID_INI_HANDLE(c, hdl) \
+ (ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
+ ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_xflist[hdl & ISP_HANDLE_CMD_MASK].handle))
+#ifdef ISP_TARGET_MODE
+#define ISP_VALID_TGT_HANDLE(c, hdl) \
+ (ISP_H2HT(hdl) == ISP_HANDLE_TARGET && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
+ ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_tgtlist[hdl & ISP_HANDLE_CMD_MASK].handle))
+#define ISP_VALID_HANDLE(c, hdl) \
+ (ISP_VALID_INI_HANDLE((c), hdl) || ISP_VALID_TGT_HANDLE((c), hdl))
+#else
+#define ISP_VALID_HANDLE ISP_VALID_INI_HANDLE
+#endif
+#define ISP_BAD_HANDLE_INDEX 0xffffffff
+
/*
* FC Port Database entry.
@@ -562,11 +609,11 @@ struct ispsoftc {
isp_mboxbsy : 1, /* mailbox command active */
isp_state : 3,
isp_nactive : 16; /* how many commands active */
+ volatile mbreg_t isp_curmbx; /* currently active mailbox command */
volatile uint32_t isp_reqodx; /* index of last ISP pickup */
volatile uint32_t isp_reqidx; /* index of next request */
volatile uint32_t isp_residx; /* index of next result */
volatile uint32_t isp_resodx; /* index of next result */
- volatile uint32_t isp_lasthdls; /* last handle seed */
volatile uint32_t isp_obits; /* mailbox command output */
volatile uint32_t isp_serno; /* rolling serial number */
volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE];
@@ -575,18 +622,21 @@ struct ispsoftc {
volatile uint16_t isp_mbxwrk1;
volatile uint16_t isp_mbxwrk2;
volatile uint16_t isp_mbxwrk8;
+ volatile uint16_t isp_seqno; /* running sequence number */
void * isp_mbxworkp;
/*
* Active commands are stored here, indexed by handle functions.
*/
- XS_T **isp_xflist;
+ isp_hdl_t *isp_xflist;
+ isp_hdl_t *isp_xffree;
#ifdef ISP_TARGET_MODE
/*
* Active target commands are stored here, indexed by handle functions.
*/
- void **isp_tgtlist;
+ isp_hdl_t *isp_tgtlist;
+ isp_hdl_t *isp_tgtfree;
#endif
/*
OpenPOWER on IntegriCloud