diff options
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r-- | sys/dev/isp/isp.c | 456 |
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); } |