summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r--sys/dev/isp/isp.c456
1 files changed, 240 insertions, 216 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index d5c393b..2e69855 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -126,6 +126,8 @@ static int isp_send_change_request(ispsoftc_t *, int);
static int isp_register_fc4_type(ispsoftc_t *, int);
static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
static int isp_register_fc4_features_24xx(ispsoftc_t *, int);
+static int isp_register_port_name_24xx(ispsoftc_t *, int);
+static int isp_register_node_name_24xx(ispsoftc_t *, int);
static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
static int isp_fw_state(ispsoftc_t *, int);
static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
@@ -1970,10 +1972,12 @@ isp_fibre_init(ispsoftc_t *isp)
}
isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
- if (isp->isp_dblev & ISP_LOGDEBUG1)
- isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "isp_fibre_init",
+ sizeof(*icbp), fcp->isp_scratch);
+ }
/*
* Init the firmware
@@ -2238,16 +2242,16 @@ isp_fibre_init_2400(ispsoftc_t *isp)
DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
- }
-
if (FC_SCRATCH_ACQUIRE(isp, 0)) {
isp_prt(isp, ISP_LOGERR, sacq);
return;
}
ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "isp_fibre_init_2400",
+ sizeof (*icbp), fcp->isp_scratch);
+ }
/*
* Now fill in information about any additional channels
@@ -2393,6 +2397,8 @@ isp_fc_enable_vp(ispsoftc_t *isp, int chan)
return (EIO);
}
isp_put_vp_modify(isp, &vp, (vp_modify_t *)reqp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB VP_MODIFY", QENTRY_LEN, reqp);
ISP_SYNC_REQUEST(isp);
if (msleep(resp, &isp->isp_lock, 0, "VP_MODIFY", 5*hz) == EWOULDBLOCK) {
isp_prt(isp, ISP_LOGERR,
@@ -2400,6 +2406,8 @@ isp_fc_enable_vp(ispsoftc_t *isp, int chan)
isp_destroy_handle(isp, vp.vp_mod_hdl);
return (EIO);
}
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB VP_MODIFY response", QENTRY_LEN, resp);
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) {
@@ -2450,6 +2458,8 @@ isp_fc_disable_vp(ispsoftc_t *isp, int chan)
return (EIO);
}
isp_put_vp_ctrl_info(isp, &vp, (vp_ctrl_info_t *)reqp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB VP_CTRL", QENTRY_LEN, reqp);
ISP_SYNC_REQUEST(isp);
if (msleep(resp, &isp->isp_lock, 0, "VP_CTRL", 5*hz) == EWOULDBLOCK) {
isp_prt(isp, ISP_LOGERR,
@@ -2457,6 +2467,8 @@ isp_fc_disable_vp(ispsoftc_t *isp, int chan)
isp_destroy_handle(isp, vp.vp_ctrl_handle);
return (EIO);
}
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB VP_CTRL response", QENTRY_LEN, resp);
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) {
@@ -2600,9 +2612,9 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
isp_destroy_handle(isp, pl.plogx_handle);
return (-1);
}
- if (isp->isp_dblev & ISP_LOGDEBUG1)
- isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, &pl);
isp_put_plogx(isp, &pl, (isp_plogx_t *)reqp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, reqp);
ISP_SYNC_REQUEST(isp);
if (msleep(resp, &isp->isp_lock, 0, "PLOGX", 3 * ICB_LOGIN_TOV * hz)
== EWOULDBLOCK) {
@@ -2611,9 +2623,9 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags
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);
+ isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, resp);
+ isp_get_plogx(isp, (isp_plogx_t *)resp, &pl);
if (pl.plogx_status == PLOGX_STATUS_OK) {
return (0);
@@ -3073,6 +3085,8 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
r = isp_register_fc4_type_24xx(isp, chan);
if (r == 0)
isp_register_fc4_features_24xx(isp, chan);
+ isp_register_port_name_24xx(isp, chan);
+ isp_register_node_name_24xx(isp, chan);
} else {
fcp->isp_sns_hdl = SNS_ID;
r = isp_register_fc4_type(isp, chan);
@@ -3494,26 +3508,17 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan)
}
static int
-isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
+isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt)
{
mbreg_t mbs;
fcparam *fcp = FCPARAM(isp, chan);
union {
isp_ct_pt_t plocal;
- ct_hdr_t clocal;
uint8_t q[QENTRY_LEN];
} un;
isp_ct_pt_t *pt;
- ct_hdr_t *ct;
- uint32_t *rp;
uint8_t *scp = fcp->isp_scratch;
- 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.
*/
@@ -3527,39 +3532,21 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
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_rsp_bcnt = rsp_bcnt;
+ pt->ctp_cmd_bcnt = cmd_bcnt;
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[0].ds_count = cmd_bcnt;
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);
- }
- isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
+ pt->ctp_dataseg[1].ds_count = rsp_bcnt;
+ isp_put_ct_pt(isp, pt, (isp_ct_pt_t *)&scp[CTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT IOCB request", QENTRY_LEN, &scp[CTXOFF]);
/*
- * Build the CT header and command in memory.
- *
- * Note that the CT header has to end up as Big Endian format in memory.
+ * Execute the Passthrough IOCB.
*/
- ct = &un.clocal;
- ISP_MEMZERO(ct, sizeof (*ct));
- ct->ct_revision = CT_REVISION;
- ct->ct_fcs_type = CT_FC_TYPE_FC;
- ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
- ct->ct_cmd_resp = SNS_GID_FT;
- ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
-
- isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
- rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
- ISP_IOZPUT_32(isp, FC4_SCSI, rp);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "CT HDR + payload after put",
- sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
- }
ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
MBCMD_DEFAULT_TIMEOUT + pt->ctp_time * 1000000);
@@ -3574,18 +3561,56 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT IOCB response", QENTRY_LEN, &scp[ZTXOFF]);
pt = &un.plocal;
isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
- }
-
if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
isp_prt(isp, ISP_LOGWARN,
"Chan %d GID_FT CT Passthrough returned 0x%x",
chan, pt->ctp_status);
return (-1);
}
+
+ return (0);
+}
+
+static int
+isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ ct_hdr_t ct;
+ uint32_t *rp;
+ uint8_t *scp = fcp->isp_scratch;
+
+ 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 the CT header and command in memory.
+ */
+ ISP_MEMZERO(&ct, sizeof (ct));
+ ct.ct_revision = CT_REVISION;
+ ct.ct_fcs_type = CT_FC_TYPE_FC;
+ ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct.ct_cmd_resp = SNS_GID_FT;
+ ct.ct_bcnt_resid = (GIDLEN - 16) >> 2;
+ isp_put_ct_hdr(isp, &ct, (ct_hdr_t *) &scp[XTXOFF]);
+ rp = (uint32_t *) &scp[XTXOFF + sizeof(ct)];
+ ISP_IOZPUT_32(isp, FC4_SCSI, rp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "CT request",
+ sizeof(ct) + sizeof(uint32_t), &scp[XTXOFF]);
+ }
+
+ if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ return (-1);
+ }
+
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,
@@ -3957,16 +3982,9 @@ isp_register_fc4_type(ispsoftc_t *isp, int chan)
static int
isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
{
- mbreg_t mbs;
fcparam *fcp = FCPARAM(isp, chan);
- union {
- isp_ct_pt_t plocal;
- rft_id_t clocal;
- uint8_t q[QENTRY_LEN];
- } un;
- isp_ct_pt_t *pt;
ct_hdr_t *ct;
- rft_id_t *rp;
+ rft_id_t rp;
uint8_t *scp = fcp->isp_scratch;
if (FC_SCRATCH_ACQUIRE(isp, chan)) {
@@ -3975,110 +3993,48 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
}
/*
- * Build a Passthrough IOCB in memory.
- */
- ISP_MEMZERO(un.q, QENTRY_LEN);
- pt = &un.plocal;
- pt->ctp_header.rqs_entry_count = 1;
- pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
- pt->ctp_handle = 0xffffffff;
- pt->ctp_nphdl = fcp->isp_sns_hdl;
- pt->ctp_cmd_cnt = 1;
- pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
- 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);
- 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) {
- isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
- }
-
- /*
* Build the CT header and command in memory.
- *
- * Note that the CT header has to end up as Big Endian format in memory.
*/
- ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
- ct = &un.clocal.rftid_hdr;
+ ISP_MEMZERO(&rp, sizeof(rp));
+ ct = &rp.rftid_hdr;
ct->ct_revision = CT_REVISION;
ct->ct_fcs_type = CT_FC_TYPE_FC;
ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
ct->ct_cmd_resp = SNS_RFT_ID;
ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
- rp = &un.clocal;
- rp->rftid_portid[0] = fcp->isp_portid >> 16;
- rp->rftid_portid[1] = fcp->isp_portid >> 8;
- rp->rftid_portid[2] = fcp->isp_portid;
- rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
- isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
- }
-
- ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
+ rp.rftid_portid[0] = fcp->isp_portid >> 16;
+ rp.rftid_portid[1] = fcp->isp_portid >> 8;
+ rp.rftid_portid[2] = fcp->isp_portid;
+ rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
+ isp_put_rft_id(isp, &rp, (rft_id_t *)&scp[XTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT request", sizeof(rft_id_t), &scp[XTXOFF]);
- 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);
- mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
- MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
FC_SCRATCH_RELEASE(isp, chan);
return (-1);
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
- pt = &un.plocal;
- isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
- }
- if (pt->ctp_status) {
- FC_SCRATCH_RELEASE(isp, chan);
- isp_prt(isp, ISP_LOGWARN,
- "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
- chan, pt->ctp_status);
- return (1);
- }
isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
FC_SCRATCH_RELEASE(isp, chan);
-
if (ct->ct_cmd_resp == LS_RJT) {
isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
return (-1);
} else if (ct->ct_cmd_resp == LS_ACC) {
isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
- return (0);
} else {
isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
return (-1);
}
+ return (0);
}
static int
isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
{
- mbreg_t mbs;
fcparam *fcp = FCPARAM(isp, chan);
- union {
- isp_ct_pt_t plocal;
- rff_id_t clocal;
- uint8_t q[QENTRY_LEN];
- } un;
- isp_ct_pt_t *pt;
ct_hdr_t *ct;
- rff_id_t *rp;
+ rff_id_t rp;
uint8_t *scp = fcp->isp_scratch;
if (FC_SCRATCH_ACQUIRE(isp, chan)) {
@@ -4087,103 +4043,172 @@ isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
}
/*
- * Build a Passthrough IOCB in memory.
- */
- ISP_MEMZERO(un.q, QENTRY_LEN);
- pt = &un.plocal;
- pt->ctp_header.rqs_entry_count = 1;
- pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
- pt->ctp_handle = 0xffffffff;
- pt->ctp_nphdl = fcp->isp_sns_hdl;
- pt->ctp_cmd_cnt = 1;
- pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
- 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);
- 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) {
- isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
- }
-
- /*
* Build the CT header and command in memory.
- *
- * Note that the CT header has to end up as Big Endian format in memory.
*/
- ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
- ct = &un.clocal.rffid_hdr;
+ ISP_MEMZERO(&rp, sizeof(rp));
+ ct = &rp.rffid_hdr;
ct->ct_revision = CT_REVISION;
ct->ct_fcs_type = CT_FC_TYPE_FC;
ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
ct->ct_cmd_resp = SNS_RFF_ID;
ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
- rp = &un.clocal;
- rp->rffid_portid[0] = fcp->isp_portid >> 16;
- rp->rffid_portid[1] = fcp->isp_portid >> 8;
- rp->rffid_portid[2] = fcp->isp_portid;
- rp->rffid_fc4features = 0;
+ rp.rffid_portid[0] = fcp->isp_portid >> 16;
+ rp.rffid_portid[1] = fcp->isp_portid >> 8;
+ rp.rffid_portid[2] = fcp->isp_portid;
+ rp.rffid_fc4features = 0;
if (fcp->role & ISP_ROLE_TARGET)
- rp->rffid_fc4features |= 1;
+ rp.rffid_fc4features |= 1;
if (fcp->role & ISP_ROLE_INITIATOR)
- rp->rffid_fc4features |= 2;
- rp->rffid_fc4type = FC4_SCSI;
- isp_put_rff_id(isp, rp, (rff_id_t *) &scp[XTXOFF]);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
+ rp.rffid_fc4features |= 2;
+ rp.rffid_fc4type = FC4_SCSI;
+ isp_put_rff_id(isp, &rp, (rff_id_t *)&scp[XTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT request", sizeof(rft_id_t), &scp[XTXOFF]);
+
+ if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ return (-1);
+ }
+
+ isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
+ FC_SCRATCH_RELEASE(isp, chan);
+ if (ct->ct_cmd_resp == LS_RJT) {
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
+ "Chan %d Register FC4 Features rejected", chan);
+ return (-1);
+ } else if (ct->ct_cmd_resp == LS_ACC) {
+ isp_prt(isp, ISP_LOG_SANCFG,
+ "Chan %d Register FC4 Features accepted", chan);
+ } else {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
+ return (-1);
}
+ return (0);
+}
- ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
+static int
+isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ ct_hdr_t *ct;
+ rspn_id_t rp;
+ uint8_t *scp = fcp->isp_scratch;
+ int len;
- 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);
- mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
- MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
+
+ /*
+ * Build the CT header and command in memory.
+ */
+ ISP_MEMZERO(&rp, sizeof(rp));
+ ct = &rp.rspnid_hdr;
+ ct->ct_revision = CT_REVISION;
+ ct->ct_fcs_type = CT_FC_TYPE_FC;
+ ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct->ct_cmd_resp = SNS_RSPN_ID;
+ rp.rspnid_portid[0] = fcp->isp_portid >> 16;
+ rp.rspnid_portid[1] = fcp->isp_portid >> 8;
+ rp.rspnid_portid[2] = fcp->isp_portid;
+ rp.rspnid_length = 0;
+ len = offsetof(rspn_id_t, rspnid_name);
+ mtx_lock(&prison0.pr_mtx);
+ rp.rspnid_length += sprintf(&scp[XTXOFF + len + rp.rspnid_length],
+ "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
+ mtx_unlock(&prison0.pr_mtx);
+ rp.rspnid_length += sprintf(&scp[XTXOFF + len + rp.rspnid_length],
+ ":%s", device_get_nameunit(isp->isp_dev));
+ if (chan != 0) {
+ rp.rspnid_length += sprintf(&scp[XTXOFF + len +
+ rp.rspnid_length], "/%d", chan);
+ }
+ len += rp.rspnid_length;
+ ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
+ isp_put_rspn_id(isp, &rp, (rspn_id_t *)&scp[XTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT request", len, &scp[XTXOFF]);
+
+ if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
FC_SCRATCH_RELEASE(isp, chan);
return (-1);
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
- pt = &un.plocal;
- isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
+
+ isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
+ FC_SCRATCH_RELEASE(isp, chan);
+ if (ct->ct_cmd_resp == LS_RJT) {
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
+ "Chan %d Register Symbolic Port Name rejected", chan);
+ return (-1);
+ } else if (ct->ct_cmd_resp == LS_ACC) {
+ isp_prt(isp, ISP_LOG_SANCFG,
+ "Chan %d Register Symbolic Port Name accepted", chan);
+ } else {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
+ return (-1);
}
- if (pt->ctp_status) {
+ return (0);
+}
+
+static int
+isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ ct_hdr_t *ct;
+ rsnn_nn_t rp;
+ uint8_t *scp = fcp->isp_scratch;
+ int len;
+
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
+
+ /*
+ * Build the CT header and command in memory.
+ */
+ ISP_MEMZERO(&rp, sizeof(rp));
+ ct = &rp.rsnnnn_hdr;
+ ct->ct_revision = CT_REVISION;
+ ct->ct_fcs_type = CT_FC_TYPE_FC;
+ ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct->ct_cmd_resp = SNS_RSNN_NN;
+ MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
+ rp.rsnnnn_length = 0;
+ len = offsetof(rsnn_nn_t, rsnnnn_name);
+ mtx_lock(&prison0.pr_mtx);
+ rp.rsnnnn_length += sprintf(&scp[XTXOFF + len + rp.rsnnnn_length],
+ "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
+ mtx_unlock(&prison0.pr_mtx);
+ len += rp.rsnnnn_length;
+ ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
+ isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)&scp[XTXOFF]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_bytes(isp, "CT request", len, &scp[XTXOFF]);
+
+ if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
FC_SCRATCH_RELEASE(isp, chan);
- isp_prt(isp, ISP_LOGWARN,
- "Chan %d Register FC4 Features CT Passthrough returned 0x%x",
- chan, pt->ctp_status);
- return (1);
+ return (-1);
}
isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
FC_SCRATCH_RELEASE(isp, chan);
-
if (ct->ct_cmd_resp == LS_RJT) {
isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
- "Chan %d Register FC4 Features rejected", chan);
+ "Chan %d Register Symbolic Node Name rejected", chan);
return (-1);
} else if (ct->ct_cmd_resp == LS_ACC) {
isp_prt(isp, ISP_LOG_SANCFG,
- "Chan %d Register FC4 Features accepted", chan);
- return (0);
+ "Chan %d Register Symbolic Node Name accepted", chan);
} else {
isp_prt(isp, ISP_LOGWARN,
- "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
+ "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
return (-1);
}
+ return (0);
}
static uint16_t
@@ -5140,15 +5165,14 @@ again:
* Synchronize our view of this response queue entry.
*/
MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN, -1);
+ if (isp->isp_dblev & ISP_LOGDEBUG1)
+ isp_print_qentry(isp, "Response Queue Entry", oop, hp);
isp_get_hdr(isp, hp, &sp->req_header);
etype = sp->req_header.rqs_entry_type;
if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
- }
scsi_status = sp2->req_scsi_status;
completion_status = sp2->req_completion_status;
if ((scsi_status & 0xff) != 0)
@@ -5158,9 +5182,6 @@ again:
resid = sp2->req_resid;
} else if (etype == RQSTYPE_RESPONSE) {
isp_get_response(isp, (ispstatusreq_t *) hp, sp);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
- }
scsi_status = sp->req_scsi_status;
completion_status = sp->req_completion_status;
req_status_flags = sp->req_status_flags;
@@ -5169,9 +5190,6 @@ again:
} else if (etype == RQSTYPE_RIO1) {
isp_rio1_t *rio = (isp_rio1_t *) qe;
isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
- if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
- }
for (i = 0; i < rio->req_header.rqs_seqno; i++) {
isp_fastpost_complete(isp, rio->req_handles[i]);
}
@@ -5235,7 +5253,6 @@ again:
*/
if (etype != RQSTYPE_REQUEST) {
isp_prt(isp, ISP_LOGERR, notresp, etype, oop, optr, nlooked);
- isp_print_bytes(isp, "Request Queue Entry", QENTRY_LEN, sp);
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
last_etype = etype;
continue;
@@ -5250,7 +5267,8 @@ again:
if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
- isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
+ isp_print_qentry(isp, "unexpected continuation segment",
+ oop, hp);
last_etype = etype;
continue;
}
@@ -5261,19 +5279,23 @@ again:
*/
}
if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
- isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
+ isp_print_qentry(isp, "bad header flag",
+ oop, hp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
- isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
+ isp_print_qentry(isp, "bad request packet",
+ oop, hp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
- isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
+ isp_print_qentry(isp, "invalid entry count",
+ oop, hp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
- isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
+ isp_print_qentry(isp, "invalid IOCB ordering",
+ oop, hp);
last_etype = etype;
continue;
}
@@ -5431,7 +5453,8 @@ again:
XS_SAVE_SENSE(xs, snsp, totslen, slen);
} else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
- isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
+ isp_print_qentry(isp, "CC with no Sense",
+ oop, hp);
}
isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
break;
@@ -5457,7 +5480,8 @@ again:
XS_SET_RESID(xs, XS_XFRLEN(xs));
break;
default:
- isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
+ isp_print_qentry(isp, "Unhandled Response Type",
+ oop, hp);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
OpenPOWER on IntegriCloud