svn commit: r298961 - stable/10/sys/dev/isp
Alexander Motin
mav at FreeBSD.org
Tue May 3 07:56:43 UTC 2016
Author: mav
Date: Tue May 3 07:56:42 2016
New Revision: 298961
URL: https://svnweb.freebsd.org/changeset/base/298961
Log:
MFC r297741: Reduce code duplication when executing Passthrough IOCB.
Modified:
stable/10/sys/dev/isp/isp.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/isp/isp.c
==============================================================================
--- stable/10/sys/dev/isp/isp.c Tue May 3 07:52:06 2016 (r298960)
+++ stable/10/sys/dev/isp/isp.c Tue May 3 07:56:42 2016 (r298961)
@@ -3494,26 +3494,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 +3518,21 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp,
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 +3547,58 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp,
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.
+ *
+ * Note that the CT header has to end up as Big Endian format 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 +3970,9 @@ isp_register_fc4_type(ispsoftc_t *isp, i
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 +3981,50 @@ isp_register_fc4_type_24xx(ispsoftc_t *i
}
/*
- * 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,90 +4033,37 @@ isp_register_fc4_features_24xx(ispsoftc_
}
/*
- * 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]);
- }
-
- ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
+ 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]);
- 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 Features 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 Features rejected", chan);
@@ -4178,12 +4071,12 @@ isp_register_fc4_features_24xx(ispsoftc_
} else if (ct->ct_cmd_resp == LS_ACC) {
isp_prt(isp, ISP_LOG_SANCFG,
"Chan %d Register FC4 Features accepted", chan);
- return (0);
} else {
isp_prt(isp, ISP_LOGWARN,
"Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
return (-1);
}
+ return (0);
}
static uint16_t
More information about the svn-src-stable-10
mailing list