Author: mav
Date: Mon Nov 30 21:38:05 2015
New Revision: 291511
URL: https://svnweb.freebsd.org/changeset/base/291511

Log:
  MFC r291000: Register our FC4 Features in SNS.

Modified:
  stable/10/sys/dev/isp/isp.c
  stable/10/sys/dev/isp/isp_library.c
  stable/10/sys/dev/isp/isp_library.h
  stable/10/sys/dev/isp/isp_stds.h
  stable/10/sys/dev/isp/ispmbox.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/isp/isp.c
==============================================================================
--- stable/10/sys/dev/isp/isp.c Mon Nov 30 21:37:22 2015        (r291510)
+++ stable/10/sys/dev/isp/isp.c Mon Nov 30 21:38:05 2015        (r291511)
@@ -125,6 +125,7 @@ static int isp_scan_fabric(ispsoftc_t *,
 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t 
*);
 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 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);
@@ -2927,6 +2928,8 @@ isp_fclink_test(ispsoftc_t *isp, int cha
                        }
                        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);
                } else {
                        fcp->isp_sns_hdl = SNS_ID;
                        r = isp_register_fc4_type(isp, chan);
@@ -4217,6 +4220,125 @@ isp_register_fc4_type_24xx(ispsoftc_t *i
        }
 }
 
+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;
+       uint8_t *scp = fcp->isp_scratch;
+
+       if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+               isp_prt(isp, ISP_LOGERR, sacq);
+               return (-1);
+       }
+
+       /*
+        * 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 = 1;
+       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_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;
+       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;
+       if (fcp->role & ISP_ROLE_TARGET)
+               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));
+
+       MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 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) {
+               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[IGPOFF], 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);
+               return (0);
+       } else {
+               isp_prt(isp, ISP_LOGWARN,
+                   "Chan %d Register FC4 Features: 0x%x", chan, 
ct->ct_cmd_resp);
+               return (-1);
+       }
+}
+
 static uint16_t
 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
 {

Modified: stable/10/sys/dev/isp/isp_library.c
==============================================================================
--- stable/10/sys/dev/isp/isp_library.c Mon Nov 30 21:37:22 2015        
(r291510)
+++ stable/10/sys/dev/isp/isp_library.c Mon Nov 30 21:38:05 2015        
(r291511)
@@ -2157,6 +2157,20 @@ isp_put_rft_id(ispsoftc_t *isp, rft_id_t
 }
 
 void
+isp_put_rff_id(ispsoftc_t *isp, rff_id_t *src, rff_id_t *dst)
+{
+       int i;
+
+       isp_put_ct_hdr(isp, &src->rffid_hdr, &dst->rffid_hdr);
+       ISP_IOZPUT_8(isp, src->rffid_reserved, &dst->rffid_reserved);
+       for (i = 0; i < 3; i++)
+               ISP_IOZPUT_8(isp, src->rffid_portid[i], &dst->rffid_portid[i]);
+       ISP_IOZPUT_16(isp, src->rffid_reserved2, &dst->rffid_reserved2);
+       ISP_IOZPUT_8(isp, src->rffid_fc4features, &dst->rffid_fc4features);
+       ISP_IOZPUT_8(isp, src->rffid_fc4type, &dst->rffid_fc4type);
+}
+
+void
 isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *src, ct_hdr_t *dst)
 {
        ISP_IOZGET_8(isp, &src->ct_revision, dst->ct_revision);

Modified: stable/10/sys/dev/isp/isp_library.h
==============================================================================
--- stable/10/sys/dev/isp/isp_library.h Mon Nov 30 21:37:22 2015        
(r291510)
+++ stable/10/sys/dev/isp/isp_library.h Mon Nov 30 21:38:05 2015        
(r291511)
@@ -148,6 +148,7 @@ void isp_get_fc_hdr(ispsoftc_t *, fc_hdr
 void isp_put_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
 void isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
 void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
+void isp_put_rff_id(ispsoftc_t *, rff_id_t *, rff_id_t *);
 void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
 void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
 void isp_put_fcp_rsp_iu(ispsoftc_t *isp, fcp_rsp_iu_t *, fcp_rsp_iu_t *);

Modified: stable/10/sys/dev/isp/isp_stds.h
==============================================================================
--- stable/10/sys/dev/isp/isp_stds.h    Mon Nov 30 21:37:22 2015        
(r291510)
+++ stable/10/sys/dev/isp/isp_stds.h    Mon Nov 30 21:38:05 2015        
(r291511)
@@ -139,6 +139,20 @@ typedef struct {
 } rft_id_t;
 
 /*
+ * RFF_ID Requet CT_IU
+ *
+ * Source: INCITS 463-2010 Generic Services 6 Section 5.2.5.34
+ */
+typedef struct {
+       ct_hdr_t        rffid_hdr;
+       uint8_t         rffid_reserved;
+       uint8_t         rffid_portid[3];
+       uint16_t        rffid_reserved2;
+       uint8_t         rffid_fc4features;
+       uint8_t         rffid_fc4type;
+} rff_id_t;
+
+/*
  * FCP Response IU and bits of interest
  * Source: NCITS T10, Project 1828D, Revision 02b (aka FCP4r02b)
  */

Modified: stable/10/sys/dev/isp/ispmbox.h
==============================================================================
--- stable/10/sys/dev/isp/ispmbox.h     Mon Nov 30 21:37:22 2015        
(r291510)
+++ stable/10/sys/dev/isp/ispmbox.h     Mon Nov 30 21:38:05 2015        
(r291511)
@@ -1513,6 +1513,7 @@ typedef struct {
 #define        SNS_GFF_ID      0x11F
 #define        SNS_GID_FT      0x171
 #define        SNS_RFT_ID      0x217
+#define        SNS_RFF_ID      0x21F
 typedef struct {
        uint16_t        snscb_rblen;    /* response buffer length (words) */
        uint16_t        snscb_reserved0;
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to