diff options
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r-- | sys/dev/isp/isp.c | 135 |
1 files changed, 78 insertions, 57 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 88ea7de..2664d13 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -3078,20 +3078,31 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) fcp->isp_fabric_params = mbs.param[7]; fcp->isp_sns_hdl = NPH_SNS_ID; 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); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; + if (r != 0) + goto not_on_fabric; + r = isp_register_fc4_features_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; + if (r != 0) + goto not_on_fabric; + r = isp_register_port_name_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; + if (r != 0) + goto not_on_fabric; isp_register_node_name_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; } else { fcp->isp_sns_hdl = SNS_ID; r = isp_register_fc4_type(isp, chan); - if (r == 0 && fcp->role == ISP_ROLE_TARGET) + if (r != 0) + goto not_on_fabric; + if (fcp->role == ISP_ROLE_TARGET) isp_send_change_request(isp, chan); } - if (r) { - isp_prt(isp, ISP_LOGWARN|ISP_LOG_SANCFG, "%s: register fc4 type failed", __func__); - return (-1); - } } not_on_fabric: @@ -3505,65 +3516,66 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan) static int 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; - uint8_t q[QENTRY_LEN]; - } un; - isp_ct_pt_t *pt; - uint8_t *scp = fcp->isp_scratch; + isp_ct_pt_t pt; + void *reqp; + uint8_t resp[QENTRY_LEN]; /* * Build a Passthrough IOCB in memory. */ - pt = &un.plocal; - ISP_MEMZERO(un.q, QENTRY_LEN); - 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 = 10; - pt->ctp_rsp_cnt = 1; - 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 = 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 = 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]); + ISP_MEMZERO(&pt, sizeof(pt)); + pt.ctp_header.rqs_entry_count = 1; + pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; + pt.ctp_nphdl = fcp->isp_sns_hdl; + pt.ctp_cmd_cnt = 1; + pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan); + pt.ctp_time = 10; + pt.ctp_rsp_cnt = 1; + 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 = 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 = rsp_bcnt; - /* - * Execute the Passthrough IOCB. - */ - ISP_MEMZERO(&scp[ZTXOFF], QENTRY_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) { + /* Prepare space for response in memory */ + memset(resp, 0xff, sizeof(resp)); + pt.ctp_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL); + if (pt.ctp_handle == 0) { + isp_prt(isp, ISP_LOGERR, + "%s: CTP of Chan %d out of handles", __func__, chan); return (-1); } - MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan); + + /* Send request and wait for response. */ + reqp = isp_getrqentry(isp); + if (reqp == NULL) { + isp_prt(isp, ISP_LOGERR, + "%s: CTP of Chan %d out of rqent", __func__, chan); + isp_destroy_handle(isp, pt.ctp_handle); + return (-1); + } + isp_put_ct_pt(isp, &pt, (isp_ct_pt_t *)reqp); 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 (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) { + isp_print_bytes(isp, "CT IOCB request", QENTRY_LEN, reqp); + ISP_SYNC_REQUEST(isp); + if (msleep(resp, &isp->isp_lock, 0, "CTP", pt.ctp_time*hz) == EWOULDBLOCK) { + isp_prt(isp, ISP_LOGERR, + "%s: CTP of Chan %d timed out", __func__, chan); + isp_destroy_handle(isp, pt.ctp_handle); + return (-1); + } + if (isp->isp_dblev & ISP_LOGDEBUG1) + isp_print_bytes(isp, "CT IOCB response", QENTRY_LEN, resp); + + isp_get_ct_pt(isp, (isp_ct_pt_t *)resp, &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); + chan, pt.ctp_status); return (-1); } @@ -3931,7 +3943,13 @@ isp_send_change_request(ispsoftc_t *isp, int chan) mbs.param[1] = 0x03; mbs.param[9] = chan; isp_mboxcmd(isp, &mbs); - return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : -1); + if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { + return (0); + } else { + isp_prt(isp, ISP_LOGWARN, "Chan %d Send Change Request: 0x%x", + chan, mbs.param[0]); + return (-1); + } } static int @@ -3970,6 +3988,8 @@ isp_register_fc4_type(ispsoftc_t *isp, int chan) if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { return (0); } else { + isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", + chan, mbs.param[0]); return (-1); } } @@ -6140,6 +6160,7 @@ isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *opt } } return (1); + case RQSTYPE_CT_PASSTHRU: case RQSTYPE_VP_MODIFY: case RQSTYPE_VP_CTRL: case RQSTYPE_LOGIN: |