summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp.c565
-rw-r--r--sys/dev/isp/isp_freebsd.c20
-rw-r--r--sys/dev/isp/isp_freebsd.h56
-rw-r--r--sys/dev/isp/isp_library.c327
-rw-r--r--sys/dev/isp/isp_library.h15
-rw-r--r--sys/dev/isp/isp_pci.c297
-rw-r--r--sys/dev/isp/isp_sbus.c120
-rw-r--r--sys/dev/isp/isp_target.c4
-rw-r--r--sys/dev/isp/ispmbox.h2
-rw-r--r--sys/dev/isp/ispvar.h29
10 files changed, 678 insertions, 757 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index d394011..d5c393b 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -108,12 +108,12 @@ static void isp_fibre_init(ispsoftc_t *);
static void isp_fibre_init_2400(ispsoftc_t *);
static void isp_clear_portdb(ispsoftc_t *, int);
static void isp_mark_portdb(ispsoftc_t *, int);
-static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
+static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
-static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
-static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int, int);
-static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
+static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *);
+static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int);
+static void isp_dump_chip_portdb(ispsoftc_t *, int);
static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
static int isp_fclink_test(ispsoftc_t *, int, int);
static int isp_pdb_sync(ispsoftc_t *, int);
@@ -2142,19 +2142,41 @@ isp_fibre_init_2400(ispsoftc_t *isp)
if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
}
- icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
if (isp->isp_confopts & ISP_CFG_1GB) {
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
} else if (isp->isp_confopts & ISP_CFG_2GB) {
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
} else if (isp->isp_confopts & ISP_CFG_4GB) {
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
} else if (isp->isp_confopts & ISP_CFG_8GB) {
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
} else if (isp->isp_confopts & ISP_CFG_16GB) {
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
} else {
- icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
+ switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) {
+ case ICB2400_OPT3_RATE_4GB:
+ case ICB2400_OPT3_RATE_8GB:
+ case ICB2400_OPT3_RATE_16GB:
+ case ICB2400_OPT3_RATE_AUTO:
+ break;
+ case ICB2400_OPT3_RATE_2GB:
+ if (isp->isp_type <= ISP_HA_FC_2500)
+ break;
+ /*FALLTHROUGH*/
+ case ICB2400_OPT3_RATE_1GB:
+ if (isp->isp_type <= ISP_HA_FC_2400)
+ break;
+ /*FALLTHROUGH*/
+ default:
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
+ break;
+ }
}
icbp->icb_logintime = ICB_LOGIN_TOV;
@@ -2322,6 +2344,161 @@ isp_fibre_init_2400(ispsoftc_t *isp)
isp->isp_state = ISP_RUNSTATE;
}
+static int
+isp_fc_enable_vp(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ vp_modify_t vp;
+ void *reqp;
+ uint8_t resp[QENTRY_LEN];
+
+ /* Build a VP MODIFY command in memory */
+ ISP_MEMZERO(&vp, sizeof(vp));
+ vp.vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
+ vp.vp_mod_hdr.rqs_entry_count = 1;
+ vp.vp_mod_cnt = 1;
+ vp.vp_mod_idx0 = chan;
+ vp.vp_mod_cmd = VP_MODIFY_ENA;
+ vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
+ ICB2400_VPOPT_ENA_SNSLOGIN;
+ if (fcp->role & ISP_ROLE_INITIATOR)
+ vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
+ if ((fcp->role & ISP_ROLE_TARGET) == 0)
+ vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
+ if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
+ vp.vp_mod_ports[0].loopid = fcp->isp_loopid;
+ if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
+ vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS;
+ else
+ vp.vp_mod_ports[0].options |= ICB2400_VPOPT_PREV_ADDRESS;
+ }
+ MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn);
+ MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn);
+
+ /* Prepare space for response in memory */
+ memset(resp, 0xff, sizeof(resp));
+ vp.vp_mod_hdl = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
+ if (vp.vp_mod_hdl == 0) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_MODIFY of Chan %d out of handles", __func__, chan);
+ return (EIO);
+ }
+
+ /* Send request and wait for response. */
+ reqp = isp_getrqentry(isp);
+ if (reqp == NULL) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_MODIFY of Chan %d out of rqent", __func__, chan);
+ isp_destroy_handle(isp, vp.vp_mod_hdl);
+ return (EIO);
+ }
+ isp_put_vp_modify(isp, &vp, (vp_modify_t *)reqp);
+ ISP_SYNC_REQUEST(isp);
+ if (msleep(resp, &isp->isp_lock, 0, "VP_MODIFY", 5*hz) == EWOULDBLOCK) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_MODIFY of Chan %d timed out", __func__, chan);
+ isp_destroy_handle(isp, vp.vp_mod_hdl);
+ return (EIO);
+ }
+ isp_get_vp_modify(isp, (vp_modify_t *)resp, &vp);
+
+ if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_MODIFY of Chan %d failed with flags %x status %d",
+ __func__, chan, vp.vp_mod_hdr.rqs_flags, vp.vp_mod_status);
+ return (EIO);
+ }
+ return (0);
+}
+
+static int
+isp_fc_disable_vp(ispsoftc_t *isp, int chan)
+{
+ vp_ctrl_info_t vp;
+ void *reqp;
+ uint8_t resp[QENTRY_LEN];
+
+ /* Build a VP CTRL command in memory */
+ ISP_MEMZERO(&vp, sizeof(vp));
+ vp.vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL;
+ vp.vp_ctrl_hdr.rqs_entry_count = 1;
+ if (ISP_CAP_VP0(isp)) {
+ vp.vp_ctrl_status = 1;
+ } else {
+ vp.vp_ctrl_status = 0;
+ chan--; /* VP0 can not be controlled in this case. */
+ }
+ vp.vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL;
+ vp.vp_ctrl_vp_count = 1;
+ vp.vp_ctrl_idmap[chan / 16] |= (1 << chan % 16);
+
+ /* Prepare space for response in memory */
+ memset(resp, 0xff, sizeof(resp));
+ vp.vp_ctrl_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
+ if (vp.vp_ctrl_handle == 0) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_CTRL of Chan %d out of handles", __func__, chan);
+ return (EIO);
+ }
+
+ /* Send request and wait for response. */
+ reqp = isp_getrqentry(isp);
+ if (reqp == NULL) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_CTRL of Chan %d out of rqent", __func__, chan);
+ isp_destroy_handle(isp, vp.vp_ctrl_handle);
+ return (EIO);
+ }
+ isp_put_vp_ctrl_info(isp, &vp, (vp_ctrl_info_t *)reqp);
+ ISP_SYNC_REQUEST(isp);
+ if (msleep(resp, &isp->isp_lock, 0, "VP_CTRL", 5*hz) == EWOULDBLOCK) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_CTRL of Chan %d timed out", __func__, chan);
+ isp_destroy_handle(isp, vp.vp_ctrl_handle);
+ return (EIO);
+ }
+ isp_get_vp_ctrl_info(isp, (vp_ctrl_info_t *)resp, &vp);
+
+ if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: VP_CTRL of Chan %d failed with flags %x status %d %d",
+ __func__, chan, vp.vp_ctrl_hdr.rqs_flags,
+ vp.vp_ctrl_status, vp.vp_ctrl_index_fail);
+ return (EIO);
+ }
+ return (0);
+}
+
+static int
+isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ int i, was, res = 0;
+
+ if (chan >= isp->isp_nchan) {
+ isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
+ return (ENXIO);
+ }
+ if (fcp->role == new_role)
+ return (0);
+ for (was = 0, i = 0; i < isp->isp_nchan; i++) {
+ if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
+ was++;
+ }
+ if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
+ fcp->role = new_role;
+ return (isp_reinit(isp, 0));
+ }
+ if (fcp->role != ISP_ROLE_NONE) {
+ res = isp_fc_disable_vp(isp, chan);
+ isp_clear_portdb(isp, chan);
+ }
+ fcp->role = new_role;
+ if (fcp->role != ISP_ROLE_NONE)
+ res = isp_fc_enable_vp(isp, chan);
+ return (res);
+}
+
static void
isp_clear_portdb(ispsoftc_t *isp, int chan)
{
@@ -2373,13 +2550,11 @@ isp_mark_portdb(ispsoftc_t *isp, int chan)
* or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
*/
static int
-isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
+isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags)
{
- mbreg_t mbs;
- uint8_t q[QENTRY_LEN];
- isp_plogx_t *plp;
- fcparam *fcp;
- uint8_t *scp;
+ isp_plogx_t pl;
+ void *reqp;
+ uint8_t resp[QENTRY_LEN];
uint32_t sst, parm1;
int rval, lev;
const char *msg;
@@ -2399,63 +2574,58 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
}
}
- ISP_MEMZERO(q, QENTRY_LEN);
- plp = (isp_plogx_t *) q;
- plp->plogx_header.rqs_entry_count = 1;
- plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
- plp->plogx_handle = 0xffffffff;
- plp->plogx_nphdl = handle;
- plp->plogx_vphdl = chan;
- plp->plogx_portlo = portid;
- plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
- plp->plogx_flags = flags;
+ ISP_MEMZERO(&pl, sizeof(pl));
+ pl.plogx_header.rqs_entry_count = 1;
+ pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
+ pl.plogx_nphdl = handle;
+ pl.plogx_vphdl = chan;
+ pl.plogx_portlo = portid;
+ pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
+ pl.plogx_flags = flags;
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
- }
-
- if (gs == 0) {
- if (FC_SCRATCH_ACQUIRE(isp, chan)) {
- isp_prt(isp, ISP_LOGERR, sacq);
- return (-1);
- }
+ /* Prepare space for response in memory */
+ memset(resp, 0xff, sizeof(resp));
+ pl.plogx_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
+ if (pl.plogx_handle == 0) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: PLOGX of Chan %d out of handles", __func__, chan);
+ return (-1);
}
- fcp = FCPARAM(isp, chan);
- scp = fcp->isp_scratch;
- isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
- mbs.param[1] = QENTRY_LEN;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- rval = mbs.param[0];
- goto out;
+ /* Send request and wait for response. */
+ reqp = isp_getrqentry(isp);
+ if (reqp == NULL) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: PLOGX of Chan %d out of rqent", __func__, chan);
+ isp_destroy_handle(isp, pl.plogx_handle);
+ return (-1);
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
- scp += QENTRY_LEN;
- isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, &pl);
+ isp_put_plogx(isp, &pl, (isp_plogx_t *)reqp);
+ ISP_SYNC_REQUEST(isp);
+ if (msleep(resp, &isp->isp_lock, 0, "PLOGX", 3 * ICB_LOGIN_TOV * hz)
+ == EWOULDBLOCK) {
+ isp_prt(isp, ISP_LOGERR,
+ "%s: PLOGX of Chan %d timed out", __func__, chan);
+ isp_destroy_handle(isp, pl.plogx_handle);
+ return (-1);
}
+ isp_get_plogx(isp, (isp_plogx_t *)resp, &pl);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, &pl);
- if (plp->plogx_status == PLOGX_STATUS_OK) {
- rval = 0;
- goto out;
- } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
+ if (pl.plogx_status == PLOGX_STATUS_OK) {
+ return (0);
+ } else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) {
isp_prt(isp, ISP_LOGWARN,
"status 0x%x on port login IOCB channel %d",
- plp->plogx_status, chan);
- rval = -1;
- goto out;
+ pl.plogx_status, chan);
+ return (-1);
}
- sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
- parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
+ sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
+ parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16);
rval = -1;
lev = ISP_LOGERR;
@@ -2516,17 +2686,13 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
msg = "no FLOGI_ACC";
break;
default:
- ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
+ ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", pl.plogx_status, flags);
msg = buf;
break;
}
if (msg) {
isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
}
-out:
- if (gs == 0) {
- FC_SCRATCH_RELEASE(isp, chan);
- }
return (rval);
}
@@ -2596,7 +2762,7 @@ isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
}
static int
-isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
+isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb)
{
fcparam *fcp = FCPARAM(isp, chan);
mbreg_t mbs;
@@ -2620,18 +2786,14 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- if (dolock) {
- if (FC_SCRATCH_ACQUIRE(isp, chan)) {
- isp_prt(isp, ISP_LOGERR, sacq);
- return (-1);
- }
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un), chan);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- if (dolock) {
- FC_SCRATCH_RELEASE(isp, chan);
- }
+ FC_SCRATCH_RELEASE(isp, chan);
return (mbs.param[0] | (mbs.param[1] << 16));
}
if (IS_24XX(isp)) {
@@ -2647,9 +2809,7 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
un.bill.pdb_curstate);
if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
mbs.param[0] = MBOX_NOT_LOGGED_IN;
- if (dolock) {
- FC_SCRATCH_RELEASE(isp, chan);
- }
+ FC_SCRATCH_RELEASE(isp, chan);
return (mbs.param[0]);
}
} else {
@@ -2662,15 +2822,12 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
isp_prt(isp, ISP_LOGDEBUG1,
"Chan %d handle 0x%x Port 0x%06x", chan, id, pdb->portid);
}
- if (dolock) {
- FC_SCRATCH_RELEASE(isp, chan);
- }
+ FC_SCRATCH_RELEASE(isp, chan);
return (0);
}
static int
-isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num,
- int dolock, int loop)
+isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop)
{
fcparam *fcp = FCPARAM(isp, chan);
mbreg_t mbs;
@@ -2696,18 +2853,14 @@ isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num,
mbs.param[3] = DMA_WD3(fcp->isp_scdma);
mbs.param[6] = DMA_WD2(fcp->isp_scdma);
}
- if (dolock) {
- if (FC_SCRATCH_ACQUIRE(isp, chan)) {
- isp_prt(isp, ISP_LOGERR, sacq);
- return (-1);
- }
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- if (dolock) {
- FC_SCRATCH_RELEASE(isp, chan);
- }
+ FC_SCRATCH_RELEASE(isp, chan);
return (mbs.param[0] | (mbs.param[1] << 16));
}
elp1 = fcp->isp_scratch;
@@ -2735,13 +2888,12 @@ isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num,
handles[j++] = h;
}
*num = j;
- if (dolock)
- FC_SCRATCH_RELEASE(isp, chan);
+ FC_SCRATCH_RELEASE(isp, chan);
return (0);
}
static void
-isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
+isp_dump_chip_portdb(ispsoftc_t *isp, int chan)
{
isp_pdb_t pdb;
uint16_t lim, nphdl;
@@ -2753,7 +2905,7 @@ isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
lim = NPH_MAX;
}
for (nphdl = 0; nphdl != lim; nphdl++) {
- if (isp_getpdb(isp, chan, nphdl, &pdb, dolock)) {
+ if (isp_getpdb(isp, chan, nphdl, &pdb)) {
continue;
}
isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
@@ -2903,7 +3055,7 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
nphdl = IS_24XX(isp) ? NPH_FL_ID : FL_ID;
- r = isp_getpdb(isp, chan, nphdl, &pdb, 1);
+ r = isp_getpdb(isp, chan, nphdl, &pdb);
if (r != 0 || pdb.portid == 0) {
if (IS_2100(isp)) {
fcp->isp_topo = TOPO_NL_PORT;
@@ -3018,7 +3170,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
lp->portid,
PLOGX_FLG_CMD_LOGO |
PLOGX_FLG_IMPLICIT |
- PLOGX_FLG_FREE_NPHDL, 0);
+ PLOGX_FLG_FREE_NPHDL);
}
/*
* Note that we might come out of this with our state
@@ -3145,7 +3297,7 @@ isp_fix_portids(ispsoftc_t *isp, int chan)
if (VALID_PORT(lp->portid))
continue;
- r = isp_getpdb(isp, chan, lp->handle, &pdb, 1);
+ r = isp_getpdb(isp, chan, lp->handle, &pdb);
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
return;
if (r != 0) {
@@ -3174,7 +3326,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
fcparam *fcp = FCPARAM(isp, chan);
int idx, lim, r;
isp_pdb_t pdb;
- uint16_t handles[LOCAL_LOOP_LIM];
+ uint16_t *handles;
uint16_t handle;
if (fcp->isp_loopstate < LOOP_LTEST_DONE)
@@ -3196,8 +3348,9 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
return (0);
}
- lim = LOCAL_LOOP_LIM;
- r = isp_gethandles(isp, chan, handles, &lim, 1, 1);
+ handles = (uint16_t *)fcp->isp_scanscratch;
+ lim = ISP_FC_SCRLEN / 2;
+ r = isp_gethandles(isp, chan, handles, &lim, 1);
if (r != 0) {
isp_prt(isp, ISP_LOG_SANCFG,
"Chan %d Getting list of handles failed with %x", chan, r);
@@ -3247,7 +3400,7 @@ abort:
/*
* Get the port database entity for this index.
*/
- r = isp_getpdb(isp, chan, handle, &pdb, 1);
+ r = isp_getpdb(isp, chan, handle, &pdb);
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
goto abort;
if (r != 0) {
@@ -3276,20 +3429,10 @@ abort:
*
* For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
* mailbox command.
- *
- * The net result is to leave the list of Port IDs setting untranslated in
- * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
- * host order at OGPOFF.
*/
-
-/*
- * Take half of our scratch area to store Port IDs
- */
-#define GIDLEN (ISP_FC_SCRLEN >> 1)
+#define GIDLEN (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
#define NGENT ((GIDLEN - 16) >> 2)
-#define IGPOFF (0)
-#define OGPOFF (ISP_FC_SCRLEN >> 1)
#define XTXOFF (ISP_FC_SCRLEN - (3 * QENTRY_LEN)) /* CT request */
#define CTXOFF (ISP_FC_SCRLEN - (2 * QENTRY_LEN)) /* Request IOCB */
#define ZTXOFF (ISP_FC_SCRLEN - (1 * QENTRY_LEN)) /* Response IOCB */
@@ -3306,21 +3449,25 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan)
uint8_t *scp = fcp->isp_scratch;
mbreg_t mbs;
- isp_prt(isp, ISP_LOGDEBUG0, "Chan %d scanning fabric (GID_FT) via SNS", chan);
+ isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT via SNS", chan);
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
rq->snscb_rblen = GIDLEN >> 1;
- rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
- rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
- rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
- rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
+ rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma);
+ rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma);
+ rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma);
+ rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma);
rq->snscb_sblen = 6;
rq->snscb_cmd = SNS_GID_FT;
rq->snscb_mword_div_2 = NGENT;
rq->snscb_fc4_type = FC4_SCSI;
isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *)&scp[CTXOFF]);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
+ MEMORYBARRIER(isp, SYNC_SFORDEV, CTXOFF, SNS_GID_FT_REQ_SIZE, chan);
MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
mbs.param[0] = MBOX_SEND_SNS;
@@ -3337,6 +3484,12 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan)
return (-1);
}
}
+ MEMORYBARRIER(isp, SYNC_SFORCPU, 0, GIDLEN, chan);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT response", GIDLEN, scp);
+ isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp,
+ (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT);
+ FC_SCRATCH_RELEASE(isp, chan);
return (0);
}
@@ -3355,7 +3508,11 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
uint32_t *rp;
uint8_t *scp = fcp->isp_scratch;
- isp_prt(isp, ISP_LOGDEBUG0, "Chan %d scanning fabric (GID_FT) via CT", chan);
+ isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT via CT", chan);
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
/*
* Build a Passthrough IOCB in memory.
@@ -3368,15 +3525,15 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
pt->ctp_nphdl = fcp->isp_sns_hdl;
pt->ctp_cmd_cnt = 1;
pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
- pt->ctp_time = 30;
+ pt->ctp_time = 10;
pt->ctp_rsp_cnt = 1;
pt->ctp_rsp_bcnt = GIDLEN;
pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
- pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
- pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
+ pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
pt->ctp_dataseg[1].ds_count = GIDLEN;
if (isp->isp_dblev & ISP_LOGDEBUG1) {
isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
@@ -3404,7 +3561,8 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
}
ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
+ MBCMD_DEFAULT_TIMEOUT + pt->ctp_time * 1000000);
mbs.param[1] = QENTRY_LEN;
mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
@@ -3415,7 +3573,7 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return (-1);
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
+ MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
pt = &un.plocal;
isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
if (isp->isp_dblev & ISP_LOGDEBUG1) {
@@ -3424,14 +3582,15 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
isp_prt(isp, ISP_LOGWARN,
- "Chan %d ISP GID FT CT Passthrough returned 0x%x",
+ "Chan %d GID_FT CT Passthrough returned 0x%x",
chan, pt->ctp_status);
return (-1);
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "CT response", GIDLEN, &scp[IGPOFF]);
- }
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT response", GIDLEN, scp);
+ isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp,
+ (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT);
+ FC_SCRATCH_RELEASE(isp, chan);
return (0);
}
@@ -3444,7 +3603,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
uint16_t nphdl;
isp_pdb_t pdb;
int portidx, portlim, r;
- sns_gid_ft_rsp_t *rs0, *rs1;
+ sns_gid_ft_rsp_t *rs;
if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
return (-1);
@@ -3460,13 +3619,6 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
return (0);
}
- if (FC_SCRATCH_ACQUIRE(isp, chan)) {
- isp_prt(isp, ISP_LOGERR, sacq);
-fail:
- isp_prt(isp, ISP_LOG_SANCFG,
- "Chan %d FC fabric scan done (bad)", chan);
- return (-1);
- }
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
abort:
FC_SCRATCH_RELEASE(isp, chan);
@@ -3479,14 +3631,16 @@ abort:
* Make sure we still are logged into the fabric controller.
*/
nphdl = IS_24XX(isp) ? NPH_FL_ID : FL_ID;
- r = isp_getpdb(isp, chan, nphdl, &pdb, 0);
+ r = isp_getpdb(isp, chan, nphdl, &pdb);
if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
- isp_dump_chip_portdb(isp, chan, 0);
+ isp_dump_chip_portdb(isp, chan);
}
if (r) {
fcp->isp_loopstate = LOOP_LTEST_DONE;
- FC_SCRATCH_RELEASE(isp, chan);
- goto fail;
+fail:
+ isp_prt(isp, ISP_LOG_SANCFG,
+ "Chan %d FC fabric scan done (bad)", chan);
+ return (-1);
}
/* Get list of port IDs from SNS. */
@@ -3498,42 +3652,36 @@ abort:
goto abort;
if (r > 0) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
- FC_SCRATCH_RELEASE(isp, chan);
return (-1);
} else if (r < 0) {
fcp->isp_loopstate = LOOP_LTEST_DONE; /* try again */
- FC_SCRATCH_RELEASE(isp, chan);
return (-1);
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
- rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
- rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
- isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
+ rs = (sns_gid_ft_rsp_t *) fcp->isp_scanscratch;
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
goto abort;
- if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
+ if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) {
int level;
- if (rs1->snscb_cthdr.ct_reason == 9 && rs1->snscb_cthdr.ct_explanation == 7) {
+ if (rs->snscb_cthdr.ct_reason == 9 && rs->snscb_cthdr.ct_explanation == 7) {
level = ISP_LOG_SANCFG;
} else {
level = ISP_LOGWARN;
}
isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
" (Reason=0x%x Expl=0x%x)", chan,
- rs1->snscb_cthdr.ct_reason,
- rs1->snscb_cthdr.ct_explanation);
- FC_SCRATCH_RELEASE(isp, chan);
+ rs->snscb_cthdr.ct_reason,
+ rs->snscb_cthdr.ct_explanation);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (-1);
}
/* Check our buffer was big enough to get the full list. */
for (portidx = 0; portidx < NGENT-1; portidx++) {
- if (rs1->snscb_ports[portidx].control & 0x80)
+ if (rs->snscb_ports[portidx].control & 0x80)
break;
}
- if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
+ if ((rs->snscb_ports[portidx].control & 0x80) == 0) {
isp_prt(isp, ISP_LOGWARN,
"fabric too big for scratch area: increase ISP_FC_SCRLEN");
}
@@ -3546,24 +3694,24 @@ abort:
int npidx;
portid =
- ((rs1->snscb_ports[portidx].portid[0]) << 16) |
- ((rs1->snscb_ports[portidx].portid[1]) << 8) |
- ((rs1->snscb_ports[portidx].portid[2]));
+ ((rs->snscb_ports[portidx].portid[0]) << 16) |
+ ((rs->snscb_ports[portidx].portid[1]) << 8) |
+ ((rs->snscb_ports[portidx].portid[2]));
for (npidx = portidx + 1; npidx < portlim; npidx++) {
uint32_t new_portid =
- ((rs1->snscb_ports[npidx].portid[0]) << 16) |
- ((rs1->snscb_ports[npidx].portid[1]) << 8) |
- ((rs1->snscb_ports[npidx].portid[2]));
+ ((rs->snscb_ports[npidx].portid[0]) << 16) |
+ ((rs->snscb_ports[npidx].portid[1]) << 8) |
+ ((rs->snscb_ports[npidx].portid[2]));
if (new_portid == portid) {
break;
}
}
if (npidx < portlim) {
- rs1->snscb_ports[npidx].portid[0] = 0;
- rs1->snscb_ports[npidx].portid[1] = 0;
- rs1->snscb_ports[npidx].portid[2] = 0;
+ rs->snscb_ports[npidx].portid[0] = 0;
+ rs->snscb_ports[npidx].portid[1] = 0;
+ rs->snscb_ports[npidx].portid[2] = 0;
isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
}
}
@@ -3584,9 +3732,9 @@ abort:
*/
isp_mark_portdb(isp, chan);
for (portidx = 0; portidx < portlim; portidx++) {
- portid = ((rs1->snscb_ports[portidx].portid[0]) << 16) |
- ((rs1->snscb_ports[portidx].portid[1]) << 8) |
- ((rs1->snscb_ports[portidx].portid[2]));
+ portid = ((rs->snscb_ports[portidx].portid[0]) << 16) |
+ ((rs->snscb_ports[portidx].portid[1]) << 8) |
+ ((rs->snscb_ports[portidx].portid[2]));
isp_prt(isp, ISP_LOG_SANCFG,
"Chan %d Checking fabric port 0x%06x", chan, portid);
if (portid == 0) {
@@ -3608,7 +3756,6 @@ abort:
"Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
chan, lp->portid, lp->handle,
FC_PORTDB_TGT(isp, chan, lp), lp->state);
- FC_SCRATCH_RELEASE(isp, chan);
isp_dump_portdb(isp, chan);
goto fail;
}
@@ -3628,7 +3775,7 @@ abort:
* database entry for somebody further along to
* decide what to do (policy choice).
*/
- r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
+ r = isp_getpdb(isp, chan, lp->handle, &pdb);
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
goto abort;
if (r != 0) {
@@ -3662,7 +3809,6 @@ relogin:
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
goto abort;
- FC_SCRATCH_RELEASE(isp, chan);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
return (0);
@@ -3689,7 +3835,7 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint1
return (-1);
/* Check if this handle is free. */
- r = isp_getpdb(isp, chan, handle, p, 0);
+ r = isp_getpdb(isp, chan, handle, p);
if (r == 0) {
if (p->portid != portid) {
/* This handle is busy, try next one. */
@@ -3704,7 +3850,7 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint1
/*
* Now try and log into the device
*/
- r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
+ r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
if (r == 0) {
break;
} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
@@ -3713,12 +3859,12 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint1
* handle. We need to break that association. We used to try and just substitute the handle, but then
* failed to get any data via isp_getpdb (below).
*/
- if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
+ if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
}
if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
return (-1);
- r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
+ r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
if (r != 0)
i = lim;
break;
@@ -3742,7 +3888,7 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint1
* so we can crosscheck that it is still what we think it
* is and that we also have the role it plays
*/
- r = isp_getpdb(isp, chan, handle, p, 0);
+ r = isp_getpdb(isp, chan, handle, p);
if (r != 0) {
isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
return (-1);
@@ -3839,15 +3985,15 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
pt->ctp_nphdl = fcp->isp_sns_hdl;
pt->ctp_cmd_cnt = 1;
pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
- pt->ctp_time = 1;
+ pt->ctp_time = 4;
pt->ctp_rsp_cnt = 1;
pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
pt->ctp_cmd_bcnt = sizeof (rft_id_t);
pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
- pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
- pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
+ pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
if (isp->isp_dblev & ISP_LOGDEBUG1) {
@@ -3878,7 +4024,8 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
+ MBCMD_DEFAULT_TIMEOUT + pt->ctp_time * 1000000);
mbs.param[1] = QENTRY_LEN;
mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
@@ -3904,7 +4051,7 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
return (1);
}
- isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
+ isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
FC_SCRATCH_RELEASE(isp, chan);
if (ct->ct_cmd_resp == LS_RJT) {
@@ -3950,15 +4097,15 @@ isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
pt->ctp_nphdl = fcp->isp_sns_hdl;
pt->ctp_cmd_cnt = 1;
pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
- pt->ctp_time = 1;
+ pt->ctp_time = 4;
pt->ctp_rsp_cnt = 1;
pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
pt->ctp_cmd_bcnt = sizeof (rff_id_t);
pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
pt->ctp_dataseg[0].ds_count = sizeof (rff_id_t);
- pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
- pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
+ pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
if (isp->isp_dblev & ISP_LOGDEBUG1) {
@@ -3994,7 +4141,8 @@ isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
+ MBCMD_DEFAULT_TIMEOUT + pt->ctp_time * 1000000);
mbs.param[1] = QENTRY_LEN;
mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
@@ -4020,7 +4168,7 @@ isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
return (1);
}
- isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
+ isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
FC_SCRATCH_RELEASE(isp, chan);
if (ct->ct_cmd_resp == LS_RJT) {
@@ -4090,7 +4238,7 @@ int
isp_start(XS_T *xs)
{
ispsoftc_t *isp;
- uint32_t handle, cdblen;
+ uint32_t cdblen;
uint8_t local[QENTRY_LEN];
ispreq_t *reqp;
void *cdbp, *qep;
@@ -4381,21 +4529,18 @@ isp_start(XS_T *xs)
}
ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
- *tptr = XS_TIME(xs) / 1000;
- if (*tptr == 0 && XS_TIME(xs)) {
- *tptr = 1;
- }
+ *tptr = (XS_TIME(xs) + 999) / 1000;
if (IS_24XX(isp) && *tptr > 0x1999) {
*tptr = 0x1999;
}
- if (isp_allocate_xs(isp, xs, &handle)) {
+ /* Whew. Thankfully the same for type 7 requests */
+ reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
+ if (reqp->req_handle == 0) {
isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
- /* Whew. Thankfully the same for type 7 requests */
- reqp->req_handle = handle;
/*
* Set up DMA and/or do any platform dependent swizzling of the request entry
@@ -4405,7 +4550,7 @@ isp_start(XS_T *xs)
*/
dmaresult = ISP_DMASETUP(isp, xs, reqp);
if (dmaresult != CMD_QUEUED) {
- isp_destroy_handle(isp, handle);
+ isp_destroy_handle(isp, reqp->req_handle);
/*
* dmasetup sets actual error in packet, and
* return what we were given to return.
@@ -4490,13 +4635,14 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
tmf->tmf_header.rqs_entry_count = 1;
tmf->tmf_nphdl = lp->handle;
tmf->tmf_delay = 2;
- tmf->tmf_timeout = 2;
+ tmf->tmf_timeout = 4;
tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
tmf->tmf_tidlo = lp->portid;
tmf->tmf_tidhi = lp->portid >> 16;
tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
+ MBCMD_DEFAULT_TIMEOUT + tmf->tmf_timeout * 1000000);
mbs.param[1] = QENTRY_LEN;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
@@ -4710,7 +4856,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
tgt = va_arg(ap, int);
pdb = va_arg(ap, isp_pdb_t *);
va_end(ap);
- return (isp_getpdb(isp, chan, tgt, pdb, 1));
+ return (isp_getpdb(isp, chan, tgt, pdb));
}
break;
@@ -4758,11 +4904,11 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
va_end(ap);
if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
- return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
+ return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
}
do {
isp_next_handle(isp, &p->handle);
- r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
+ r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
if ((r & 0xffff) == MBOX_PORT_ID_USED) {
p->handle = r >> 16;
r = 0;
@@ -5133,12 +5279,6 @@ again:
}
}
- 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 */
- last_etype = etype;
- continue;
- }
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
uint8_t ts = completion_status & 0xff;
@@ -5952,6 +6092,8 @@ isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *opt
{
isp_ridacq_t rid;
int chan, c;
+ uint32_t hdl;
+ void *ptr;
switch (type) {
case RQSTYPE_STATUS_CONT:
@@ -5993,6 +6135,17 @@ isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *opt
}
}
return (1);
+ case RQSTYPE_VP_MODIFY:
+ case RQSTYPE_VP_CTRL:
+ case RQSTYPE_LOGIN:
+ ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
+ ptr = isp_find_xs(isp, hdl);
+ if (ptr != NULL) {
+ isp_destroy_handle(isp, hdl);
+ memcpy(ptr, hp, QENTRY_LEN);
+ wakeup(ptr);
+ }
+ return (1);
case RQSTYPE_ATIO:
case RQSTYPE_CTIO:
case RQSTYPE_ENABLE_LUN:
@@ -6879,7 +7032,7 @@ static const uint32_t mbpfc[] = {
ISP_FC_OPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf), /* 0x20: MBOX_GET_LOOP_ID */
ISP_FC_OPMAP(0x00, 0x00), /* 0x21: */
- ISP_FC_OPMAP(0x01, 0x07), /* 0x22: MBOX_GET_RETRY_COUNT */
+ ISP_FC_OPMAP(0x03, 0x4b), /* 0x22: MBOX_GET_TIMEOUT_PARAMS */
ISP_FC_OPMAP(0x00, 0x00), /* 0x23: */
ISP_FC_OPMAP(0x00, 0x00), /* 0x24: */
ISP_FC_OPMAP(0x00, 0x00), /* 0x25: */
@@ -6895,7 +7048,7 @@ static const uint32_t mbpfc[] = {
ISP_FC_OPMAP(0x00, 0x00), /* 0x2f: */
ISP_FC_OPMAP(0x00, 0x00), /* 0x30: */
ISP_FC_OPMAP(0x00, 0x00), /* 0x31: */
- ISP_FC_OPMAP(0x07, 0x07), /* 0x32: MBOX_SET_RETRY_COUNT */
+ ISP_FC_OPMAP(0x4b, 0x4b), /* 0x32: MBOX_SET_TIMEOUT_PARAMS */
ISP_FC_OPMAP(0x00, 0x00), /* 0x33: */
ISP_FC_OPMAP(0x00, 0x00), /* 0x34: */
ISP_FC_OPMAP(0x00, 0x00), /* 0x35: */
@@ -7632,6 +7785,7 @@ isp_setdfltfcparm(ispsoftc_t *isp, int chan)
fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
}
fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
+ fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
} else {
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
@@ -7644,6 +7798,7 @@ isp_setdfltfcparm(ispsoftc_t *isp, int chan)
* extended options from NVRAM
*/
fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
+ fcp->isp_zfwoptions |= ICBZOPT_RATE_AUTO;
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 35ca7fe..e38ae45 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -632,7 +632,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
tmf->tmf_header.rqs_entry_count = 1;
tmf->tmf_nphdl = lp->handle;
tmf->tmf_delay = 2;
- tmf->tmf_timeout = 2;
+ tmf->tmf_timeout = 4;
tmf->tmf_tidlo = lp->portid;
tmf->tmf_tidhi = lp->portid >> 16;
tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
@@ -668,7 +668,8 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
ISP_UNLOCK(isp);
break;
}
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
+ MBCMD_DEFAULT_TIMEOUT + tmf->tmf_timeout * 1000000);
mbs.param[1] = QENTRY_LEN;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
@@ -1403,7 +1404,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
cto->ct_iid_hi = atp->portid >> 16;
cto->ct_oxid = atp->oxid;
cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb));
- cto->ct_timeout = 120;
+ cto->ct_timeout = (XS_TIME(ccb) + 999) / 1000;
cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT;
/*
@@ -1555,7 +1556,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
cto->ct_lun = ccb->ccb_h.target_lun;
}
}
- cto->ct_timeout = 10;
+ cto->ct_timeout = (XS_TIME(ccb) + 999) / 1000;
cto->ct_rxid = cso->tag_id;
/*
@@ -1693,7 +1694,8 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
- if (isp_allocate_xs_tgt(isp, ccb, &handle)) {
+ handle = isp_allocate_handle(isp, ccb, ISP_HANDLE_TARGET);
+ if (handle == 0) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
isp_free_pcmd(isp, ccb);
@@ -1722,7 +1724,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
if (dmaresult != CMD_QUEUED) {
- isp_destroy_tgt_handle(isp, handle);
+ isp_destroy_handle(isp, handle);
isp_free_pcmd(isp, ccb);
if (dmaresult == CMD_EAGAIN) {
TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
@@ -2379,12 +2381,12 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
uint32_t handle, moved_data = 0, data_requested;
handle = ((ct2_entry_t *)arg)->ct_syshandle;
- ccb = isp_find_xs_tgt(isp, handle);
+ ccb = isp_find_xs(isp, handle);
if (ccb == NULL) {
isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
return;
}
- isp_destroy_tgt_handle(isp, handle);
+ isp_destroy_handle(isp, handle);
data_requested = PISP_PCMD(ccb)->datalen;
isp_free_pcmd(isp, ccb);
if (isp->isp_nactive) {
@@ -3320,7 +3322,7 @@ isp_loop_dead(ispsoftc_t *isp, int chan)
for (i = 0; i < isp->isp_maxcmds; i++) {
struct ccb_scsiio *xs;
- if (!ISP_VALID_HANDLE(isp, isp->isp_xflist[i].handle)) {
+ if (ISP_H2HT(isp->isp_xflist[i].handle) != ISP_HANDLE_INITIATOR) {
continue;
}
if ((xs = isp->isp_xflist[i].cmd) == NULL) {
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 9a9093a..7702ee6 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -225,8 +225,7 @@ struct isp_fc {
struct cam_path *path;
struct ispsoftc *isp;
struct proc *kproc;
- bus_dma_tag_t tdmat;
- bus_dmamap_t tdmap;
+ bus_dmamap_t scmap;
uint64_t def_wwpn;
uint64_t def_wwnn;
time_t loop_down_time;
@@ -285,13 +284,18 @@ struct isposinfo {
const struct firmware * fw;
/*
- * DMA related sdtuff
+ * DMA related stuff
*/
struct resource * regs;
struct resource * regs2;
bus_dma_tag_t dmat;
- bus_dma_tag_t cdmat;
- bus_dmamap_t cdmap;
+ bus_dma_tag_t reqdmat;
+ bus_dma_tag_t respdmat;
+ bus_dma_tag_t atiodmat;
+ bus_dma_tag_t scdmat;
+ bus_dmamap_t reqmap;
+ bus_dmamap_t respmap;
+ bus_dmamap_t atiomap;
/*
* Command and transaction related related stuff
@@ -406,62 +410,60 @@ struct isposinfo {
#define MEMORYBARRIER(isp, type, offset, size, chan) \
switch (type) { \
+case SYNC_REQUEST: \
+ bus_dmamap_sync(isp->isp_osinfo.reqdmat, \
+ isp->isp_osinfo.reqmap, BUS_DMASYNC_PREWRITE); \
+ break; \
+case SYNC_RESULT: \
+ bus_dmamap_sync(isp->isp_osinfo.respdmat, \
+ isp->isp_osinfo.respmap, BUS_DMASYNC_POSTREAD); \
+ break; \
case SYNC_SFORDEV: \
{ \
struct isp_fc *fc = ISP_FC_PC(isp, chan); \
- bus_dmamap_sync(fc->tdmat, fc->tdmap, \
+ bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap, \
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); \
break; \
} \
-case SYNC_REQUEST: \
- bus_dmamap_sync(isp->isp_osinfo.cdmat, \
- isp->isp_osinfo.cdmap, \
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); \
- break; \
case SYNC_SFORCPU: \
{ \
struct isp_fc *fc = ISP_FC_PC(isp, chan); \
- bus_dmamap_sync(fc->tdmat, fc->tdmap, \
+ bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap, \
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); \
break; \
} \
-case SYNC_RESULT: \
- bus_dmamap_sync(isp->isp_osinfo.cdmat, \
- isp->isp_osinfo.cdmap, \
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); \
- break; \
case SYNC_REG: \
bus_barrier(isp->isp_osinfo.regs, offset, size, \
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); \
break; \
+case SYNC_ATIOQ: \
+ bus_dmamap_sync(isp->isp_osinfo.atiodmat, \
+ isp->isp_osinfo.atiomap, BUS_DMASYNC_POSTREAD); \
+ break; \
default: \
break; \
}
#define MEMORYBARRIERW(isp, type, offset, size, chan) \
switch (type) { \
+case SYNC_REQUEST: \
+ bus_dmamap_sync(isp->isp_osinfo.reqdmat, \
+ isp->isp_osinfo.reqmap, BUS_DMASYNC_PREWRITE); \
+ break; \
case SYNC_SFORDEV: \
{ \
struct isp_fc *fc = ISP_FC_PC(isp, chan); \
- bus_dmamap_sync(fc->tdmat, fc->tdmap, \
+ bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap, \
BUS_DMASYNC_PREWRITE); \
break; \
} \
-case SYNC_REQUEST: \
- bus_dmamap_sync(isp->isp_osinfo.cdmat, \
- isp->isp_osinfo.cdmap, BUS_DMASYNC_PREWRITE); \
- break; \
case SYNC_SFORCPU: \
{ \
struct isp_fc *fc = ISP_FC_PC(isp, chan); \
- bus_dmamap_sync(fc->tdmat, fc->tdmap, \
+ bus_dmamap_sync(isp->isp_osinfo.scdmat, fc->scmap, \
BUS_DMASYNC_POSTWRITE); \
break; \
} \
-case SYNC_RESULT: \
- bus_dmamap_sync(isp->isp_osinfo.cdmat, \
- isp->isp_osinfo.cdmap, BUS_DMASYNC_POSTWRITE); \
- break; \
case SYNC_REG: \
bus_barrier(isp->isp_osinfo.regs, offset, size, \
BUS_SPACE_BARRIER_WRITE); \
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index ec99244..78c7f6f 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -247,28 +247,26 @@ copy_and_sync:
return (CMD_QUEUED);
}
-int
-isp_allocate_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep)
+uint32_t
+isp_allocate_handle(ispsoftc_t *isp, void *xs, int type)
{
isp_hdl_t *hdp;
hdp = isp->isp_xffree;
- if (hdp == NULL) {
- return (-1);
- }
+ if (hdp == NULL)
+ return (ISP_HANDLE_FREE);
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 |= (type << ISP_HANDLE_USAGE_SHIFT);
hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
- *handlep = hdp->handle;
- return (0);
+ return (hdp->handle);
}
-XS_T *
+void *
isp_find_xs(ispsoftc_t *isp, uint32_t handle)
{
- if (!ISP_VALID_INI_HANDLE(isp, handle)) {
+ if (!ISP_VALID_HANDLE(isp, handle)) {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (NULL);
}
@@ -276,7 +274,7 @@ isp_find_xs(ispsoftc_t *isp, uint32_t handle)
}
uint32_t
-isp_find_handle(ispsoftc_t *isp, XS_T *xs)
+isp_find_handle(ispsoftc_t *isp, void *xs)
{
uint32_t i, foundhdl = ISP_HANDLE_FREE;
@@ -292,21 +290,10 @@ isp_find_handle(ispsoftc_t *isp, XS_T *xs)
return (foundhdl);
}
-uint32_t
-isp_handle_index(ispsoftc_t *isp, uint32_t handle)
-{
- if (!ISP_VALID_HANDLE(isp, handle)) {
- isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
- return (ISP_BAD_HANDLE_INDEX);
- } else {
- return (handle & ISP_HANDLE_CMD_MASK);
- }
-}
-
void
isp_destroy_handle(ispsoftc_t *isp, uint32_t handle)
{
- if (!ISP_VALID_INI_HANDLE(isp, handle)) {
+ if (!ISP_VALID_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;
@@ -573,168 +560,6 @@ isp_fc_toponame(fcparam *fcp)
}
}
-static int
-isp_fc_enable_vp(ispsoftc_t *isp, int chan)
-{
- fcparam *fcp = FCPARAM(isp, chan);
- mbreg_t mbs;
- vp_modify_t *vp;
- uint8_t qe[QENTRY_LEN], *scp;
-
- ISP_MEMZERO(qe, QENTRY_LEN);
- if (FC_SCRATCH_ACQUIRE(isp, chan)) {
- return (EBUSY);
- }
- scp = fcp->isp_scratch;
-
- /*
- * Build a VP MODIFY command in memory
- */
- vp = (vp_modify_t *) qe;
- vp->vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
- vp->vp_mod_hdr.rqs_entry_count = 1;
- vp->vp_mod_cnt = 1;
- vp->vp_mod_idx0 = chan;
- vp->vp_mod_cmd = VP_MODIFY_ENA;
- vp->vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
- ICB2400_VPOPT_ENA_SNSLOGIN;
- if (fcp->role & ISP_ROLE_INITIATOR) {
- vp->vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
- }
- if ((fcp->role & ISP_ROLE_TARGET) == 0) {
- vp->vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
- }
- if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
- vp->vp_mod_ports[0].loopid = fcp->isp_loopid;
- if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
- vp->vp_mod_ports[0].options |=
- ICB2400_VPOPT_HARD_ADDRESS;
- else
- vp->vp_mod_ports[0].options |=
- ICB2400_VPOPT_PREV_ADDRESS;
- }
- MAKE_NODE_NAME_FROM_WWN(vp->vp_mod_ports[0].wwpn, fcp->isp_wwpn);
- MAKE_NODE_NAME_FROM_WWN(vp->vp_mod_ports[0].wwnn, fcp->isp_wwnn);
- isp_put_vp_modify(isp, vp, (vp_modify_t *) scp);
-
- /*
- * Build a EXEC IOCB A64 command that points to the VP MODIFY command
- */
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 0);
- mbs.param[1] = QENTRY_LEN;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN, chan);
- isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- FC_SCRATCH_RELEASE(isp, chan);
- return (EIO);
- }
- MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
- isp_get_vp_modify(isp, (vp_modify_t *)&scp[QENTRY_LEN], vp);
-
- FC_SCRATCH_RELEASE(isp, chan);
-
- if (vp->vp_mod_status != VP_STS_OK) {
- isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of Chan %d failed with status %d", __func__, chan, vp->vp_mod_status);
- return (EIO);
- }
- return (0);
-}
-
-static int
-isp_fc_disable_vp(ispsoftc_t *isp, int chan)
-{
- fcparam *fcp = FCPARAM(isp, chan);
- mbreg_t mbs;
- vp_ctrl_info_t *vp;
- uint8_t qe[QENTRY_LEN], *scp;
-
- ISP_MEMZERO(qe, QENTRY_LEN);
- if (FC_SCRATCH_ACQUIRE(isp, chan)) {
- return (EBUSY);
- }
- scp = fcp->isp_scratch;
-
- /*
- * Build a VP CTRL command in memory
- */
- vp = (vp_ctrl_info_t *) qe;
- vp->vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL;
- vp->vp_ctrl_hdr.rqs_entry_count = 1;
- if (ISP_CAP_VP0(isp)) {
- vp->vp_ctrl_status = 1;
- } else {
- vp->vp_ctrl_status = 0;
- chan--; /* VP0 can not be controlled in this case. */
- }
- vp->vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL;
- vp->vp_ctrl_vp_count = 1;
- vp->vp_ctrl_idmap[chan / 16] |= (1 << chan % 16);
- isp_put_vp_ctrl_info(isp, vp, (vp_ctrl_info_t *) scp);
-
- /*
- * Build a EXEC IOCB A64 command that points to the VP CTRL command
- */
- MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 0);
- mbs.param[1] = QENTRY_LEN;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN, chan);
- isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- FC_SCRATCH_RELEASE(isp, chan);
- return (EIO);
- }
- MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
- isp_get_vp_ctrl_info(isp, (vp_ctrl_info_t *)&scp[QENTRY_LEN], vp);
-
- FC_SCRATCH_RELEASE(isp, chan);
-
- if (vp->vp_ctrl_status != 0) {
- isp_prt(isp, ISP_LOGERR,
- "%s: VP_CTRL of Chan %d failed with status %d %d",
- __func__, chan, vp->vp_ctrl_status, vp->vp_ctrl_index_fail);
- return (EIO);
- }
- return (0);
-}
-
-/*
- * Change Roles
- */
-int
-isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
-{
- fcparam *fcp = FCPARAM(isp, chan);
- int i, was, res = 0;
-
- if (chan >= isp->isp_nchan) {
- isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
- return (ENXIO);
- }
- if (fcp->role == new_role)
- return (0);
- for (was = 0, i = 0; i < isp->isp_nchan; i++) {
- if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
- was++;
- }
- if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
- fcp->role = new_role;
- return (isp_reinit(isp, 0));
- }
- if (fcp->role != ISP_ROLE_NONE)
- res = isp_fc_disable_vp(isp, chan);
- fcp->role = new_role;
- if (fcp->role != ISP_ROLE_NONE)
- res = isp_fc_enable_vp(isp, chan);
- return (res);
-}
-
void
isp_clear_commands(ispsoftc_t *isp)
{
@@ -745,46 +570,49 @@ isp_clear_commands(ispsoftc_t *isp)
#endif
for (tmp = 0; isp->isp_xflist && tmp < isp->isp_maxcmds; tmp++) {
- 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, hdp->handle);
- XS_SET_RESID(xs, XS_XFRLEN(xs));
- } else {
- XS_SET_RESID(xs, 0);
+ switch (ISP_H2HT(hdp->handle)) {
+ case ISP_HANDLE_INITIATOR: {
+ XS_T *xs = hdp->cmd;
+ if (XS_XFRLEN(xs)) {
+ ISP_DMAFREE(isp, xs, hdp->handle);
+ XS_SET_RESID(xs, XS_XFRLEN(xs));
+ } else {
+ XS_SET_RESID(xs, 0);
+ }
+ isp_destroy_handle(isp, hdp->handle);
+ XS_SETERR(xs, HBA_BUSRESET);
+ isp_done(xs);
+ break;
}
- 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];
- hdp = &isp->isp_tgtlist[tmp];
- if (hdp->handle == ISP_HANDLE_FREE) {
- continue;
+ case ISP_HANDLE_TARGET: {
+ uint8_t local[QENTRY_LEN];
+ 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 = hdp->handle;
+ ctio->ct_nphdl = CT_HBA_RESET;
+ ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
+ } else {
+ ct2_entry_t *ctio = (ct2_entry_t *) local;
+ ctio->ct_syshandle = hdp->handle;
+ ctio->ct_status = CT_HBA_RESET;
+ ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
+ }
+ isp_async(isp, ISPASYNC_TARGET_ACTION, local);
+ break;
}
- 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 = hdp->handle;
- ctio->ct_nphdl = CT_HBA_RESET;
- ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
- } else {
- ct2_entry_t *ctio = (ct2_entry_t *) local;
- ctio->ct_syshandle = hdp->handle;
- ctio->ct_status = CT_HBA_RESET;
- ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
+#endif
+ case ISP_HANDLE_CTRL:
+ wakeup(hdp->cmd);
+ isp_destroy_handle(isp, hdp->handle);
+ break;
}
- isp_async(isp, ISPASYNC_TARGET_ACTION, local);
}
+#ifdef ISP_TARGET_MODE
for (tmp = 0; tmp < isp->isp_nchan; tmp++) {
ISP_MEMZERO(&notify, sizeof (isp_notify_t));
notify.nt_ncode = NT_HBA_RESET;
@@ -2385,69 +2213,6 @@ isp_send_tgt_cmd(ispsoftc_t *isp, void *fqe, void *segp, uint32_t nsegs, uint32_
return (CMD_QUEUED);
}
-int
-isp_allocate_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep)
-{
- isp_hdl_t *hdp;
-
- hdp = isp->isp_tgtfree;
- if (hdp == NULL) {
- return (-1);
- }
- isp->isp_tgtfree = hdp->cmd;
- hdp->cmd = xs;
- hdp->handle = (hdp - isp->isp_tgtlist);
- hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT);
- /*
- * Target handles for SCSI cards are only 16 bits, so
- * sequence number protection will be ommitted.
- */
- if (IS_FC(isp)) {
- 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 (!ISP_VALID_TGT_HANDLE(isp, handle)) {
- isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
- return (NULL);
- }
- return (isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd);
-}
-
-uint32_t
-isp_find_tgt_handle(ispsoftc_t *isp, void *xs)
-{
- uint32_t i, foundhdl = ISP_HANDLE_FREE;
-
- if (xs != NULL) {
- for (i = 0; i < isp->isp_maxcmds; i++) {
- if (isp->isp_tgtlist[i].cmd != xs) {
- continue;
- }
- foundhdl = isp->isp_tgtlist[i].handle;
- break;
- }
- }
- return (foundhdl);
-}
-
-void
-isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle)
-{
- if (!ISP_VALID_TGT_HANDLE(isp, handle)) {
- isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
- } else {
- 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)];
- }
-}
-
#endif
/*
diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h
index efe4e0e..922a98b 100644
--- a/sys/dev/isp/isp_library.h
+++ b/sys/dev/isp/isp_library.h
@@ -43,10 +43,9 @@ int isp_send_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t, i
*
* These handles are associate with a command.
*/
-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(ispsoftc_t *, uint32_t);
+uint32_t isp_allocate_handle(ispsoftc_t *, void *, int);
+void *isp_find_xs(ispsoftc_t *, uint32_t);
+uint32_t isp_find_handle(ispsoftc_t *, void *);
void isp_destroy_handle(ispsoftc_t *, uint32_t);
/*
@@ -72,9 +71,6 @@ const char *isp_fc_fw_statename(int);
const char *isp_fc_loop_statename(int);
const char *isp_fc_toponame(fcparam *);
-int isp_fc_change_role(ispsoftc_t *, int, int);
-
-
/*
* Cleanup
*/
@@ -165,11 +161,6 @@ void isp_put_fcp_rsp_iu(ispsoftc_t *isp, fcp_rsp_iu_t *, fcp_rsp_iu_t *);
#endif
int isp_send_tgt_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_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);
#endif
int isp_find_pdb_empty(ispsoftc_t *, int, fcportdb_t **);
int isp_find_pdb_by_wwpn(ispsoftc_t *, int, uint64_t, fcportdb_t **);
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index d30f6cb..11386ee 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1539,78 +1539,17 @@ isp_pci_wr_reg_2600(ispsoftc_t *isp, int regoff, uint32_t val)
struct imush {
- ispsoftc_t *isp;
- caddr_t vbase;
- int chan;
+ bus_addr_t maddr;
int error;
};
-static void imc(void *, bus_dma_segment_t *, int, int);
-static void imc1(void *, bus_dma_segment_t *, int, int);
-
static void
imc(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
struct imush *imushp = (struct imush *) arg;
- isp_ecmd_t *ecmd;
-
- if (error) {
- imushp->error = error;
- return;
- }
- if (nseg != 1) {
- imushp->error = EINVAL;
- return;
- }
- isp_prt(imushp->isp, ISP_LOGDEBUG0, "request/result area @ 0x%jx/0x%jx", (uintmax_t) segs->ds_addr, (uintmax_t) segs->ds_len);
-
- imushp->isp->isp_rquest = imushp->vbase;
- imushp->isp->isp_rquest_dma = segs->ds_addr;
- segs->ds_addr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(imushp->isp));
- imushp->vbase += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(imushp->isp));
-
- imushp->isp->isp_result_dma = segs->ds_addr;
- imushp->isp->isp_result = imushp->vbase;
- segs->ds_addr += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(imushp->isp));
- imushp->vbase += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(imushp->isp));
-
- if (imushp->isp->isp_type >= ISP_HA_FC_2200) {
- imushp->isp->isp_osinfo.ecmd_dma = segs->ds_addr;
- imushp->isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)imushp->vbase;
- imushp->isp->isp_osinfo.ecmd_base = imushp->isp->isp_osinfo.ecmd_free;
- for (ecmd = imushp->isp->isp_osinfo.ecmd_free; ecmd < &imushp->isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) {
- if (ecmd == &imushp->isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) {
- ecmd->next = NULL;
- } else {
- ecmd->next = ecmd + 1;
- }
- }
- }
-#ifdef ISP_TARGET_MODE
- segs->ds_addr += (N_XCMDS * XCMD_SIZE);
- imushp->vbase += (N_XCMDS * XCMD_SIZE);
- if (IS_24XX(imushp->isp)) {
- imushp->isp->isp_atioq_dma = segs->ds_addr;
- imushp->isp->isp_atioq = imushp->vbase;
- }
-#endif
-}
-static void
-imc1(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct imush *imushp = (struct imush *) arg;
- if (error) {
- imushp->error = error;
- return;
- }
- if (nseg != 1) {
- imushp->error = EINVAL;
- return;
- }
- isp_prt(imushp->isp, ISP_LOGDEBUG0, "scdma @ 0x%jx/0x%jx", (uintmax_t) segs->ds_addr, (uintmax_t) segs->ds_len);
- FCPARAM(imushp->isp, imushp->chan)->isp_scdma = segs->ds_addr;
- FCPARAM(imushp->isp, imushp->chan)->isp_scratch = imushp->vbase;
+ if (!(imushp->error = error))
+ imushp->maddr = segs[0].ds_addr;
}
static int
@@ -1623,6 +1562,7 @@ isp_pci_mbxdma(ispsoftc_t *isp)
bus_addr_t llim; /* low limit of unavailable dma */
bus_addr_t hlim; /* high limit of unavailable dma */
struct imush im;
+ isp_ecmd_t *ecmd;
/*
* Already been here? If so, leave...
@@ -1684,97 +1624,129 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
}
isp->isp_xffree = isp->isp_xflist;
-#ifdef ISP_TARGET_MODE
- 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);
- ISP_LOCK(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
/*
- * Allocate and map the request and result queues (and ATIO queue
- * if we're a 2400 supporting target mode), and a region for
- * external dma addressable command/status structures (23XX and
- * later).
+ * Allocate and map the request queue and a region for external
+ * DMA addressable command/status structures (22XX and later).
*/
len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
- len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
-#ifdef ISP_TARGET_MODE
- if (IS_24XX(isp)) {
- len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
- }
-#endif
- if (isp->isp_type >= ISP_HA_FC_2200) {
+ if (isp->isp_type >= ISP_HA_FC_2200)
len += (N_XCMDS * XCMD_SIZE);
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ len, 1, len, 0, &isp->isp_osinfo.reqdmat)) {
+ isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag");
+ goto bad1;
+ }
+ if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base,
+ BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) {
+ isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory");
+ bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ goto bad1;
+ }
+ isp->isp_rquest = base;
+ im.error = 0;
+ if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap,
+ base, len, imc, &im, 0) || im.error) {
+ isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error);
+ goto bad1;
+ }
+ isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx",
+ (uintmax_t)im.maddr, (uintmax_t)len);
+ isp->isp_rquest_dma = im.maddr;
+ base += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ im.maddr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ if (isp->isp_type >= ISP_HA_FC_2200) {
+ isp->isp_osinfo.ecmd_dma = im.maddr;
+ isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)base;
+ isp->isp_osinfo.ecmd_base = isp->isp_osinfo.ecmd_free;
+ for (ecmd = isp->isp_osinfo.ecmd_free;
+ ecmd < &isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) {
+ if (ecmd == &isp->isp_osinfo.ecmd_free[N_XCMDS - 1])
+ ecmd->next = NULL;
+ else
+ ecmd->next = ecmd + 1;
+ }
}
/*
- * Create a tag for the control spaces. We don't always need this
- * to be 32 bits, but we do this for simplicity and speed's sake.
+ * Allocate and map the result queue.
*/
- if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, len, 1, slim, 0, &isp->isp_osinfo.cdmat)) {
- isp_prt(isp, ISP_LOGERR, "cannot create a dma tag for control spaces");
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- free(isp->isp_xflist, M_DEVBUF);
-#ifdef ISP_TARGET_MODE
- free(isp->isp_tgtlist, M_DEVBUF);
-#endif
- ISP_LOCK(isp);
- return (1);
+ len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ len, 1, len, 0, &isp->isp_osinfo.respdmat)) {
+ isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag");
+ goto bad1;
+ }
+ if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base,
+ BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) {
+ isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory");
+ bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
+ goto bad1;
+ }
+ isp->isp_result = base;
+ im.error = 0;
+ if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap,
+ base, len, imc, &im, 0) || im.error) {
+ isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error);
+ goto bad1;
}
+ isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx",
+ (uintmax_t)im.maddr, (uintmax_t)len);
+ isp->isp_result_dma = im.maddr;
- if (bus_dmamem_alloc(isp->isp_osinfo.cdmat, (void **)&base, BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &isp->isp_osinfo.cdmap) != 0) {
- isp_prt(isp, ISP_LOGERR, "cannot allocate %d bytes of CCB memory", len);
- bus_dma_tag_destroy(isp->isp_osinfo.cdmat);
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
- free(isp->isp_tgtlist, M_DEVBUF);
-#endif
- ISP_LOCK(isp);
- return (1);
- }
-
- im.isp = isp;
- im.chan = 0;
- im.vbase = base;
- im.error = 0;
-
- bus_dmamap_load(isp->isp_osinfo.cdmat, isp->isp_osinfo.cdmap, base, len, imc, &im, 0);
- if (im.error) {
- isp_prt(isp, ISP_LOGERR, "error %d loading dma map for control areas", im.error);
- goto bad;
+ /*
+ * Allocate and map ATIO queue on 24xx with target mode.
+ */
+ if (IS_24XX(isp)) {
+ len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, slim,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ len, 1, len, 0, &isp->isp_osinfo.atiodmat)) {
+ isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag");
+ goto bad1;
+ }
+ if (bus_dmamem_alloc(isp->isp_osinfo.atiodmat, (void **)&base,
+ BUS_DMA_COHERENT, &isp->isp_osinfo.atiomap) != 0) {
+ isp_prt(isp, ISP_LOGERR, "cannot allocate ATIO DMA memory");
+ bus_dma_tag_destroy(isp->isp_osinfo.atiodmat);
+ goto bad1;
+ }
+ isp->isp_atioq = base;
+ im.error = 0;
+ if (bus_dmamap_load(isp->isp_osinfo.atiodmat, isp->isp_osinfo.atiomap,
+ base, len, imc, &im, 0) || im.error) {
+ isp_prt(isp, ISP_LOGERR, "error loading ATIO DMA map %d", im.error);
+ goto bad;
+ }
+ isp_prt(isp, ISP_LOGDEBUG0, "ATIO area @ 0x%jx/0x%jx",
+ (uintmax_t)im.maddr, (uintmax_t)len);
+ isp->isp_atioq_dma = im.maddr;
}
+#endif
if (IS_FC(isp)) {
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, 64, slim,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ ISP_FC_SCRLEN, 1, ISP_FC_SCRLEN, 0, &isp->isp_osinfo.scdmat)) {
+ goto bad;
+ }
for (cmap = 0; cmap < isp->isp_nchan; cmap++) {
struct isp_fc *fc = ISP_FC_PC(isp, cmap);
- if (isp_dma_tag_create(isp->isp_osinfo.dmat, 64, slim, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, ISP_FC_SCRLEN, 1, slim, 0, &fc->tdmat)) {
- goto bad;
- }
- if (bus_dmamem_alloc(fc->tdmat, (void **)&base, BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &fc->tdmap) != 0) {
- bus_dma_tag_destroy(fc->tdmat);
+ if (bus_dmamem_alloc(isp->isp_osinfo.scdmat,
+ (void **)&base, BUS_DMA_COHERENT, &fc->scmap) != 0)
goto bad;
- }
- im.isp = isp;
- im.chan = cmap;
- im.vbase = base;
+ FCPARAM(isp, cmap)->isp_scratch = base;
im.error = 0;
- bus_dmamap_load(fc->tdmat, fc->tdmap, base, ISP_FC_SCRLEN, imc1, &im, 0);
- if (im.error) {
- bus_dmamem_free(fc->tdmat, base, fc->tdmap);
- bus_dma_tag_destroy(fc->tdmat);
+ if (bus_dmamap_load(isp->isp_osinfo.scdmat, fc->scmap,
+ base, ISP_FC_SCRLEN, imc, &im, 0) || im.error) {
+ bus_dmamem_free(isp->isp_osinfo.scdmat,
+ base, fc->scmap);
goto bad;
}
+ FCPARAM(isp, cmap)->isp_scdma = im.maddr;
if (!IS_2100(isp)) {
for (i = 0; i < INITIAL_NEXUS_COUNT; i++) {
struct isp_nexus *n = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -1815,25 +1787,52 @@ isp_pci_mbxdma(ispsoftc_t *isp)
return (0);
bad:
- while (--cmap >= 0) {
- struct isp_fc *fc = ISP_FC_PC(isp, cmap);
- bus_dmamap_unload(fc->tdmat, fc->tdmap);
- bus_dmamem_free(fc->tdmat, base, fc->tdmap);
- bus_dma_tag_destroy(fc->tdmat);
- while (fc->nexus_free_list) {
- struct isp_nexus *n = fc->nexus_free_list;
- fc->nexus_free_list = n->next;
- free(n, M_DEVBUF);
+ if (IS_FC(isp)) {
+ while (--cmap >= 0) {
+ struct isp_fc *fc = ISP_FC_PC(isp, cmap);
+ bus_dmamap_unload(isp->isp_osinfo.scdmat, fc->scmap);
+ bus_dmamem_free(isp->isp_osinfo.scdmat, base, fc->scmap);
+ while (fc->nexus_free_list) {
+ struct isp_nexus *n = fc->nexus_free_list;
+ fc->nexus_free_list = n->next;
+ free(n, M_DEVBUF);
+ }
}
+ bus_dma_tag_destroy(isp->isp_osinfo.scdmat);
+ }
+bad1:
+ if (isp->isp_rquest_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.reqdmat,
+ isp->isp_osinfo.reqmap);
+ }
+ if (isp->isp_rquest != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest,
+ isp->isp_osinfo.reqmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ }
+ if (isp->isp_result_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.respdmat,
+ isp->isp_osinfo.respmap);
+ }
+ if (isp->isp_result != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result,
+ isp->isp_osinfo.respmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
}
- if (isp->isp_rquest_dma != 0)
- bus_dmamap_unload(isp->isp_osinfo.cdmat, isp->isp_osinfo.cdmap);
- bus_dmamem_free(isp->isp_osinfo.cdmat, base, isp->isp_osinfo.cdmap);
- bus_dma_tag_destroy(isp->isp_osinfo.cdmat);
- free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
- free(isp->isp_tgtlist, M_DEVBUF);
+ if (IS_24XX(isp)) {
+ if (isp->isp_atioq_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.atiodmat,
+ isp->isp_osinfo.atiomap);
+ }
+ if (isp->isp_atioq != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_atioq,
+ isp->isp_osinfo.atiomap);
+ bus_dma_tag_destroy(isp->isp_osinfo.atiodmat);
+ }
+ }
#endif
+ free(isp->isp_xflist, M_DEVBUF);
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
isp->isp_rquest = NULL;
ISP_LOCK(isp);
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index 2abfc64..f1ca83c 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -413,7 +413,7 @@ isp_sbus_wr_reg(ispsoftc_t *isp, int regoff, uint32_t val)
}
struct imush {
- ispsoftc_t *isp;
+ bus_addr_t maddr;
int error;
};
@@ -423,16 +423,9 @@ static void
imc(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
struct imush *imushp = (struct imush *) arg;
- if (error) {
- imushp->error = error;
- } else {
- ispsoftc_t *isp =imushp->isp;
- bus_addr_t addr = segs->ds_addr;
- isp->isp_rquest_dma = addr;
- addr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
- isp->isp_result_dma = addr;
- }
+ if (!(imushp->error = error))
+ imushp->maddr = segs[0].ds_addr;
}
static int
@@ -479,40 +472,62 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
BUS_SPACE_MAXADDR_32BIT, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT,
ISP_NSEG_MAX, BUS_SPACE_MAXADDR_24BIT, 0, &isp->isp_osinfo.dmat)) {
isp_prt(isp, ISP_LOGERR, "could not create master dma tag");
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- free(isp->isp_xflist, M_DEVBUF);
- ISP_LOCK(isp);
- return(1);
+ goto bad;
}
/*
- * Allocate and map the request, result queues, plus FC scratch area.
+ * Allocate and map the request queue.
*/
len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
- len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
-
- if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN,
- BUS_SPACE_MAXADDR_24BIT+1, BUS_SPACE_MAXADDR_32BIT,
- BUS_SPACE_MAXADDR_32BIT, NULL, NULL, len, 1,
- BUS_SPACE_MAXADDR_24BIT, 0, &isp->isp_osinfo.cdmat)) {
- isp_prt(isp, ISP_LOGERR,
- "cannot create a dma tag for control spaces");
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- free(isp->isp_xflist, M_DEVBUF);
- ISP_LOCK(isp);
- return (1);
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, BUS_SPACE_MAXADDR_24BIT+1,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ len, 1, len, 0, &isp->isp_osinfo.reqdmat)) {
+ isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag");
+ goto bad;
+ }
+ if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base,
+ BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) {
+ isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory");
+ bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ goto bad;
+ }
+ im.error = 0;
+ if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap,
+ base, len, imc, &im, 0) || im.error) {
+ isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error);
+ goto bad;
}
+ isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx",
+ (uintmax_t)im.maddr, (uintmax_t)len);
+ isp->isp_rquest = base;
+ isp->isp_rquest_dma = im.maddr;
- if (bus_dmamem_alloc(isp->isp_osinfo.cdmat, (void **)&base, BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
- &isp->isp_osinfo.cdmap) != 0) {
- isp_prt(isp, ISP_LOGERR,
- "cannot allocate %d bytes of CCB memory", len);
- bus_dma_tag_destroy(isp->isp_osinfo.cdmat);
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- free(isp->isp_xflist, M_DEVBUF);
- ISP_LOCK(isp);
- return (1);
+ /*
+ * Allocate and map the result queue.
+ */
+ len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ if (isp_dma_tag_create(isp->isp_osinfo.dmat, QENTRY_LEN, BUS_SPACE_MAXADDR_24BIT+1,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ len, 1, len, 0, &isp->isp_osinfo.respdmat)) {
+ isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag");
+ goto bad;
}
+ if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base,
+ BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) {
+ isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory");
+ bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
+ goto bad;
+ }
+ im.error = 0;
+ if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap,
+ base, len, imc, &im, 0) || im.error) {
+ isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error);
+ goto bad;
+ }
+ isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx",
+ (uintmax_t)im.maddr, (uintmax_t)len);
+ isp->isp_result = base;
+ isp->isp_result_dma = im.maddr;
for (i = 0; i < isp->isp_maxcmds; i++) {
struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i];
@@ -534,25 +549,28 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
}
}
isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0];
-
- im.isp = isp;
- im.error = 0;
- bus_dmamap_load(isp->isp_osinfo.cdmat, isp->isp_osinfo.cdmap, base, len, imc, &im, 0);
- if (im.error) {
- isp_prt(isp, ISP_LOGERR,
- "error %d loading dma map for control areas", im.error);
- goto bad;
- }
-
- isp->isp_rquest = base;
- base += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
- isp->isp_result = base;
ISP_LOCK(isp);
return (0);
bad:
- bus_dmamem_free(isp->isp_osinfo.cdmat, base, isp->isp_osinfo.cdmap);
- bus_dma_tag_destroy(isp->isp_osinfo.cdmat);
+ if (isp->isp_rquest_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.reqdmat,
+ isp->isp_osinfo.reqmap);
+ }
+ if (isp->isp_rquest != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest,
+ isp->isp_osinfo.reqmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ }
+ if (isp->isp_result_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.respdmat,
+ isp->isp_osinfo.respmap);
+ }
+ if (isp->isp_result != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result,
+ isp->isp_osinfo.respmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
+ }
free(isp->isp_xflist, M_DEVBUF);
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
isp->isp_rquest = NULL;
diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c
index c6e48fe..c6af888 100644
--- a/sys/dev/isp/isp_target.c
+++ b/sys/dev/isp/isp_target.c
@@ -1094,7 +1094,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
char *fmsg = NULL;
if (ct->ct_syshandle) {
- xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
+ xs = isp_find_xs(isp, ct->ct_syshandle);
if (xs == NULL) {
pl = ISP_LOGALL;
}
@@ -1249,7 +1249,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
char *fmsg = NULL;
if (ct->ct_syshandle) {
- xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
+ xs = isp_find_xs(isp, ct->ct_syshandle);
if (xs == NULL) {
pl = ISP_LOGALL;
}
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index a89228b..5a1306f 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -1086,7 +1086,7 @@ typedef struct {
#define ICB_DFLT_RDELAY 5
#define ICB_DFLT_RCOUNT 3
-#define ICB_LOGIN_TOV 30
+#define ICB_LOGIN_TOV 10
#define ICB_LUN_ENABLE_TOV 15
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 0c42642..a7184e2 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -77,7 +77,7 @@ struct ispmdvec {
*/
#define MAX_TARGETS 16
#ifndef MAX_FC_TARG
-#define MAX_FC_TARG 256
+#define MAX_FC_TARG 1024
#endif
#define ISP_MAX_TARGETS(isp) (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
#define ISP_MAX_LUNS(isp) (isp)->isp_maxluns
@@ -315,21 +315,16 @@ typedef struct {
# define ISP_HANDLE_NONE 0
# define ISP_HANDLE_INITIATOR 1
# define ISP_HANDLE_TARGET 2
+# define ISP_HANDLE_CTRL 3
#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
+ ((ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR || \
+ ISP_H2HT(hdl) == ISP_HANDLE_TARGET || \
+ ISP_H2HT(hdl) == ISP_HANDLE_CTRL) && \
+ ((hdl) & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
+ (hdl) == ((c)->isp_xflist[(hdl) & ISP_HANDLE_CMD_MASK].handle))
#define ISP_BAD_HANDLE_INDEX 0xffffffff
@@ -477,6 +472,8 @@ typedef struct {
*/
void * isp_scratch;
XS_DMA_ADDR_T isp_scdma;
+
+ uint8_t isp_scanscratch[ISP_FC_SCRLEN];
} fcparam;
#define FW_CONFIG_WAIT 0
@@ -598,14 +595,6 @@ struct ispsoftc {
isp_hdl_t *isp_xflist;
isp_hdl_t *isp_xffree;
-#ifdef ISP_TARGET_MODE
- /*
- * Active target commands are stored here, indexed by handle functions.
- */
- isp_hdl_t *isp_tgtlist;
- isp_hdl_t *isp_tgtfree;
-#endif
-
/*
* request/result queue pointers and DMA handles for them.
*/
OpenPOWER on IntegriCloud