From owner-svn-src-stable@freebsd.org Tue Aug 1 13:03:08 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 88094DABDE3; Tue, 1 Aug 2017 13:03:08 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 40A6476A37; Tue, 1 Aug 2017 13:03:08 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v71D378K035296; Tue, 1 Aug 2017 13:03:07 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v71D36Ko035289; Tue, 1 Aug 2017 13:03:06 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201708011303.v71D36Ko035289@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 1 Aug 2017 13:03:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r321870 - in stable/11: share/man/man4 sys/dev/isp X-SVN-Group: stable-11 X-SVN-Commit-Author: mav X-SVN-Commit-Paths: in stable/11: share/man/man4 sys/dev/isp X-SVN-Commit-Revision: 321870 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Aug 2017 13:03:08 -0000 Author: mav Date: Tue Aug 1 13:03:06 2017 New Revision: 321870 URL: https://svnweb.freebsd.org/changeset/base/321870 Log: MFC r320604, r320865: Switch fabric scans from GID_FT to GID_PT+GFF_ID/GFT_ID. Instead of using GID_FT SNS request to get list of registered FCP ports, use GID_PT to get list of all Nx_Ports, and then use GFF_ID and/or GFT_ID requests to find whether they are FCP and target capable. The problem with old approach is that GID_FT does not report ports without FC-4 type registered. In particular it was impossible to boot OS from FreeBSD FC target using QLogic FC BIOS, since one does not register FC-4 type even on new cards and so ignored by old code as incompatible. As a side bonus this allows initiator to skip pointless logins to other initiators by fetching that information from SNS instead. In case some switches do not implement GFF_ID/GFT_ID correctly, add sysctls to disable that functionality. I handled broken GFF_ID of my Brocade 200E, but there may be other switches with different bugs. Linux also uses GID_PT, but GFF_ID is disabled by default there, and GFT_ID is not supported. Sponsored by: iXsystems, Inc. Modified: stable/11/share/man/man4/isp.4 stable/11/sys/dev/isp/isp.c stable/11/sys/dev/isp/isp_freebsd.c stable/11/sys/dev/isp/isp_library.c stable/11/sys/dev/isp/isp_library.h stable/11/sys/dev/isp/ispmbox.h stable/11/sys/dev/isp/ispvar.h Directory Properties: stable/11/ (props changed) Modified: stable/11/share/man/man4/isp.4 ============================================================================== --- stable/11/share/man/man4/isp.4 Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/share/man/man4/isp.4 Tue Aug 1 13:03:06 2017 (r321870) @@ -1,4 +1,4 @@ -.\" Copyright (c) 2009-2015 Alexander Motin +.\" Copyright (c) 2009-2017 Alexander Motin .\" Copyright (c) 2006 Marcus Alves Grando .\" Copyright (c) 1998-2001 Matthew Jacob, for NASA/Ames Research Center .\" @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 20, 2016 +.Dd July 3, 2017 .Dt ISP 4 .Os .Sh NAME @@ -221,6 +221,15 @@ This value says how long to wait for devices to reappe disappear due to loop or fabric events. While this timeout is running, I/O to those devices will simply be held. +.It Va dev.isp.N.use_gff_id +.It Va dev.isp.N.use_gft_id +Setting those options to 0 allows to disable use of GFF_ID and GFT_ID SNS +requests during FC fabric scan. +It may be useful if switch does not implement them correctly, +preventing some devices from being found. +Disabling them may cause unneeded logins to ports not supporting target role +or even FCP at all. +The default is 1 (enabled). .It Va dev.isp.N.wwnn This is the readonly World Wide Node Name value for this port. .It Va dev.isp.N.wwpn @@ -239,7 +248,7 @@ The driver was written by .An Matthew Jacob originally for NetBSD at NASA/Ames Research Center. -Some later improvement was done by +Later improvement was done by .An Alexander Motin Aq Mt mav@FreeBSD.org . .Sh BUGS The driver currently ignores some NVRAM settings. Modified: stable/11/sys/dev/isp/isp.c ============================================================================== --- stable/11/sys/dev/isp/isp.c Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/sys/dev/isp/isp.c Tue Aug 1 13:03:06 2017 (r321870) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -117,7 +118,7 @@ static uint64_t isp_get_wwn(ispsoftc_t *, int, int, in static int isp_fclink_test(ispsoftc_t *, int, int); static int isp_pdb_sync(ispsoftc_t *, int); static int isp_scan_loop(ispsoftc_t *, int); -static int isp_gid_ft(ispsoftc_t *, int); +static int isp_gid_pt(ispsoftc_t *, int); static int isp_scan_fabric(ispsoftc_t *, int); static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *); static int isp_send_change_request(ispsoftc_t *, int); @@ -3496,7 +3497,7 @@ isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cm 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 %d CT pass-through returned 0x%x", chan, pt.ctp_status); return (-1); } @@ -3510,7 +3511,8 @@ isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cm /* * Scan the fabric for devices and add them to our port database. * - * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows. + * Use the GID_PT command to get list of all Nx_Port IDs SNS knows. + * Use GFF_ID and GFT_ID to check port type (FCP) and features (target). * * For 2100-23XX cards, we use the SNS mailbox command to pass simple name * server commands to the switch management server via the QLogic f/w. @@ -3521,15 +3523,14 @@ isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cm #define NGENT ((GIDLEN - 16) >> 2) static int -isp_gid_ft(ispsoftc_t *isp, int chan) +isp_gid_pt(ispsoftc_t *isp, int chan) { fcparam *fcp = FCPARAM(isp, chan); ct_hdr_t ct; - sns_gid_ft_req_t rq; - uint32_t *rp; + sns_gid_pt_req_t rq; uint8_t *scp = fcp->isp_scratch; - isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_FT", chan); + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan); if (FC_SCRATCH_ACQUIRE(isp, chan)) { isp_prt(isp, ISP_LOGERR, sacq); return (-1); @@ -3541,11 +3542,13 @@ isp_gid_ft(ispsoftc_t *isp, int chan) 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_cmd_resp = SNS_GID_PT; ct.ct_bcnt_resid = (GIDLEN - 16) >> 2; isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); - rp = (uint32_t *) &scp[sizeof(ct)]; - ISP_IOZPUT_32(isp, FC4_SCSI, rp); + scp[sizeof(ct)] = 0x7f; /* Port Type = Nx_Port */ + scp[sizeof(ct)+1] = 0; /* Domain_ID = any */ + scp[sizeof(ct)+2] = 0; /* Area_ID = any */ + scp[sizeof(ct)+3] = 0; /* Flags = no Area_ID */ if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) { FC_SCRATCH_RELEASE(isp, chan); @@ -3553,17 +3556,20 @@ isp_gid_ft(ispsoftc_t *isp, int chan) } } else { /* Build the SNS request and execute via firmware. */ - ISP_MEMZERO(&rq, SNS_GID_FT_REQ_SIZE); + ISP_MEMZERO(&rq, SNS_GID_PT_REQ_SIZE); rq.snscb_rblen = GIDLEN >> 1; rq.snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma); rq.snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma); rq.snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma); rq.snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma); rq.snscb_sblen = 6; - rq.snscb_cmd = SNS_GID_FT; + rq.snscb_cmd = SNS_GID_PT; rq.snscb_mword_div_2 = NGENT; - rq.snscb_fc4_type = FC4_SCSI; - isp_put_gid_ft_request(isp, &rq, (sns_gid_ft_req_t *)scp); + rq.snscb_port_type = 0x7f; /* Port Type = Nx_Port */ + rq.snscb_domain = 0; /* Domain_ID = any */ + rq.snscb_area = 0; /* Area_ID = any */ + rq.snscb_flags = 0; /* Flags = no Area_ID */ + isp_put_gid_pt_request(isp, &rq, (sns_gid_pt_req_t *)scp); if (isp_ct_sns(isp, chan, sizeof(rq), NGENT)) { FC_SCRATCH_RELEASE(isp, chan); @@ -3571,13 +3577,147 @@ isp_gid_ft(ispsoftc_t *isp, int chan) } } - isp_get_gid_ft_response(isp, (sns_gid_ft_rsp_t *)scp, - (sns_gid_ft_rsp_t *)fcp->isp_scanscratch, NGENT); + isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp, + (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT); FC_SCRATCH_RELEASE(isp, chan); return (0); } static int +isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid) +{ + fcparam *fcp = FCPARAM(isp, chan); + ct_hdr_t ct; + uint32_t *rp; + uint8_t *scp = fcp->isp_scratch; + sns_gff_id_rsp_t rsp; + int i, res = -1; + + if (!fcp->isp_use_gff_id) /* User may block GFF_ID use. */ + return (res); + + if (!IS_24XX(isp)) /* Old chips can't request GFF_ID. */ + return (res); + + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan); + if (FC_SCRATCH_ACQUIRE(isp, chan)) { + isp_prt(isp, ISP_LOGERR, sacq); + return (res); + } + + /* Build the CT command and execute via pass-through. */ + 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_GFF_ID; + ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4; + isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); + rp = (uint32_t *) &scp[sizeof(ct)]; + ISP_IOZPUT_32(isp, portid, rp); + + if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), + SNS_GFF_ID_RESP_SIZE)) { + FC_SCRATCH_RELEASE(isp, chan); + return (res); + } + + isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp); + if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) { + for (i = 0; i < 32; i++) { + if (rsp.snscb_fc4_features[i] != 0) { + res = 0; + break; + } + } + if (((rsp.snscb_fc4_features[FC4_SCSI / 8] >> + ((FC4_SCSI % 8) * 4)) & 0x01) != 0) + res = 1; + /* Workaround for broken Brocade firmware. */ + if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >> + ((FC4_SCSI % 8) * 4)) & 0x01) != 0) + res = 1; + } + FC_SCRATCH_RELEASE(isp, chan); + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res); + return (res); +} + +static int +isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid) +{ + fcparam *fcp = FCPARAM(isp, chan); + ct_hdr_t ct; + sns_gxx_id_req_t rq; + uint32_t *rp; + uint8_t *scp = fcp->isp_scratch; + sns_gft_id_rsp_t rsp; + int i, res = -1; + + if (!fcp->isp_use_gft_id) /* User may block GFT_ID use. */ + return (res); + + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan); + if (FC_SCRATCH_ACQUIRE(isp, chan)) { + isp_prt(isp, ISP_LOGERR, sacq); + return (res); + } + + if (IS_24XX(isp)) { + /* Build the CT command and execute via pass-through. */ + 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_GFT_ID; + ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4; + isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp); + rp = (uint32_t *) &scp[sizeof(ct)]; + ISP_IOZPUT_32(isp, portid, rp); + + if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), + SNS_GFT_ID_RESP_SIZE)) { + FC_SCRATCH_RELEASE(isp, chan); + return (res); + } + } else { + /* Build the SNS request and execute via firmware. */ + ISP_MEMZERO(&rq, SNS_GXX_ID_REQ_SIZE); + rq.snscb_rblen = SNS_GFT_ID_RESP_SIZE >> 1; + rq.snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma); + rq.snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma); + rq.snscb_sblen = 6; + rq.snscb_cmd = SNS_GFT_ID; + rq.snscb_mword_div_2 = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4; + rq.snscb_portid = portid; + isp_put_gxx_id_request(isp, &rq, (sns_gxx_id_req_t *)scp); + + if (isp_ct_sns(isp, chan, sizeof(rq), SNS_GFT_ID_RESP_SIZE)) { + FC_SCRATCH_RELEASE(isp, chan); + return (res); + } + } + + isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp); + if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) { + for (i = 0; i < 8; i++) { + if (rsp.snscb_fc4_types[i] != 0) { + res = 0; + break; + } + } + if (((rsp.snscb_fc4_types[FC4_SCSI / 32] >> + (FC4_SCSI % 32)) & 0x01) != 0) + res = 1; + } + FC_SCRATCH_RELEASE(isp, chan); + isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res); + return (res); +} + +static int isp_scan_fabric(ispsoftc_t *isp, int chan) { fcparam *fcp = FCPARAM(isp, chan); @@ -3586,7 +3726,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) uint16_t nphdl; isp_pdb_t pdb; int portidx, portlim, r; - sns_gid_ft_rsp_t *rs; + sns_gid_xx_rsp_t *rs; if (fcp->isp_loopstate < LOOP_LSCAN_DONE) return (-1); @@ -3627,7 +3767,7 @@ fail: } /* Get list of port IDs from SNS. */ - r = isp_gid_ft(isp, chan); + r = isp_gid_pt(isp, chan); if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) goto abort; if (r > 0) { @@ -3638,17 +3778,20 @@ fail: return (-1); } - rs = (sns_gid_ft_rsp_t *) fcp->isp_scanscratch; + rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch; if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) goto abort; if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) { int level; - if (rs->snscb_cthdr.ct_reason == 9 && rs->snscb_cthdr.ct_explanation == 7) { + /* FC-4 Type and Port Type not registered are not errors. */ + if (rs->snscb_cthdr.ct_reason == 9 && + (rs->snscb_cthdr.ct_explanation == 0x07 || + rs->snscb_cthdr.ct_explanation == 0x0a)) { level = ISP_LOG_SANCFG; } else { level = ISP_LOGWARN; } - isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT" + isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT" " (Reason=0x%x Expl=0x%x)", chan, rs->snscb_cthdr.ct_reason, rs->snscb_cthdr.ct_explanation); @@ -3777,6 +3920,20 @@ relogin: if ((fcp->role & ISP_ROLE_INITIATOR) == 0) { isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x is not logged in", chan, portid); + continue; + } + + r = isp_gff_id(isp, chan, portid); + if (r == 0) { + isp_prt(isp, ISP_LOG_SANCFG, + "Chan %d Port 0x%06x is not an FCP target", chan, portid); + continue; + } + if (r < 0) + r = isp_gft_id(isp, chan, portid); + if (r == 0) { + isp_prt(isp, ISP_LOG_SANCFG, + "Chan %d Port 0x%06x is not FCP", chan, portid); continue; } Modified: stable/11/sys/dev/isp/isp_freebsd.c ============================================================================== --- stable/11/sys/dev/isp/isp_freebsd.c Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/sys/dev/isp/isp_freebsd.c Tue Aug 1 13:03:06 2017 (r321870) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -169,6 +170,8 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq fc->path = path; fc->isp = isp; fc->ready = 1; + fcp->isp_use_gft_id = 1; + fcp->isp_use_gff_id = 1; callout_init_mtx(&fc->gdt, &isp->isp_lock, 0); TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc); @@ -235,6 +238,12 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "topo", CTLFLAG_RD, &fcp->isp_topo, 0, "Connection topology"); + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "use_gft_id", CTLFLAG_RWTUN, &fcp->isp_use_gft_id, 0, + "Use GFT_ID during fabric scan"); + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "use_gff_id", CTLFLAG_RWTUN, &fcp->isp_use_gff_id, 0, + "Use GFF_ID during fabric scan"); } return (0); } Modified: stable/11/sys/dev/isp/isp_library.c ============================================================================== --- stable/11/sys/dev/isp/isp_library.c Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/sys/dev/isp/isp_library.c Tue Aug 1 13:03:06 2017 (r321870) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -1742,7 +1743,7 @@ isp_put_gid_ft_request(ispsoftc_t *isp, sns_gid_ft_req } void -isp_put_gxn_id_request(ispsoftc_t *isp, sns_gxn_id_req_t *src, sns_gxn_id_req_t *dst) +isp_put_gid_pt_request(ispsoftc_t *isp, sns_gid_pt_req_t *src, sns_gid_pt_req_t *dst) { ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen); ISP_IOXPUT_16(isp, src->snscb_reserved0, &dst->snscb_reserved0); @@ -1753,48 +1754,46 @@ isp_put_gxn_id_request(ispsoftc_t *isp, sns_gxn_id_req ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen); ISP_IOXPUT_16(isp, src->snscb_reserved1, &dst->snscb_reserved1); ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd); - ISP_IOXPUT_16(isp, src->snscb_reserved2, &dst->snscb_reserved2); + ISP_IOXPUT_16(isp, src->snscb_mword_div_2, &dst->snscb_mword_div_2); ISP_IOXPUT_32(isp, src->snscb_reserved3, &dst->snscb_reserved3); - ISP_IOXPUT_32(isp, src->snscb_portid, &dst->snscb_portid); + ISP_IOXPUT_8(isp, src->snscb_port_type, &dst->snscb_port_type); + ISP_IOXPUT_8(isp, src->snscb_domain, &dst->snscb_domain); + ISP_IOXPUT_8(isp, src->snscb_area, &dst->snscb_area); + ISP_IOXPUT_8(isp, src->snscb_flags, &dst->snscb_flags); } -/* - * Generic SNS response - not particularly useful since the per-command data - * isn't always 16 bit words. - */ void -isp_get_sns_response(ispsoftc_t *isp, sns_scrsp_t *src, sns_scrsp_t *dst, int nwords) +isp_put_gxx_id_request(ispsoftc_t *isp, sns_gxx_id_req_t *src, sns_gxx_id_req_t *dst) { - int i; - isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); - ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type); - for (i = 0; i < 3; i++) { - ISP_IOXGET_8(isp, &src->snscb_port_id[i], - dst->snscb_port_id[i]); - } - for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_portname[i], - dst->snscb_portname[i]); - } - for (i = 0; i < nwords; i++) { - ISP_IOXGET_16(isp, &src->snscb_data[i], dst->snscb_data[i]); - } + ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen); + ISP_IOXPUT_16(isp, src->snscb_reserved0, &dst->snscb_reserved0); + ISP_IOXPUT_16(isp, src->snscb_addr[0], &dst->snscb_addr[0]); + ISP_IOXPUT_16(isp, src->snscb_addr[1], &dst->snscb_addr[1]); + ISP_IOXPUT_16(isp, src->snscb_addr[2], &dst->snscb_addr[2]); + ISP_IOXPUT_16(isp, src->snscb_addr[3], &dst->snscb_addr[3]); + ISP_IOXPUT_16(isp, src->snscb_sblen, &dst->snscb_sblen); + ISP_IOXPUT_16(isp, src->snscb_reserved1, &dst->snscb_reserved1); + ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd); + ISP_IOXPUT_16(isp, src->snscb_mword_div_2, &dst->snscb_mword_div_2); + ISP_IOXPUT_32(isp, src->snscb_reserved3, &dst->snscb_reserved3); + ISP_IOXPUT_32(isp, src->snscb_portid, &dst->snscb_portid); } void -isp_get_gid_ft_response(ispsoftc_t *isp, sns_gid_ft_rsp_t *src, sns_gid_ft_rsp_t *dst, int nwords) +isp_get_gid_xx_response(ispsoftc_t *isp, sns_gid_xx_rsp_t *src, sns_gid_xx_rsp_t *dst, int nwords) { - int i; + int i, j; + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); for (i = 0; i < nwords; i++) { - int j; - ISP_IOXGET_8(isp, &src->snscb_ports[i].control, dst->snscb_ports[i].control); + ISP_IOZGET_8(isp, &src->snscb_ports[i].control, + dst->snscb_ports[i].control); for (j = 0; j < 3; j++) { - ISP_IOXGET_8(isp, &src->snscb_ports[i].portid[j], dst->snscb_ports[i].portid[j]); + ISP_IOZGET_8(isp, &src->snscb_ports[i].portid[j], + dst->snscb_ports[i].portid[j]); } - if (dst->snscb_ports[i].control & 0x80) { + if (dst->snscb_ports[i].control & 0x80) break; - } } } @@ -1802,9 +1801,21 @@ void isp_get_gxn_id_response(ispsoftc_t *isp, sns_gxn_id_rsp_t *src, sns_gxn_id_rsp_t *dst) { int i; + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); + for (i = 0; i < 8; i++) + ISP_IOZGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]); +} + +void +isp_get_gft_id_response(ispsoftc_t *isp, sns_gft_id_rsp_t *src, sns_gft_id_rsp_t *dst) +{ + int i; + + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]); + ISP_IOZGET_32(isp, &src->snscb_fc4_types[i], + dst->snscb_fc4_types[i]); } } @@ -1812,9 +1823,11 @@ void isp_get_gff_id_response(ispsoftc_t *isp, sns_gff_id_rsp_t *src, sns_gff_id_rsp_t *dst) { int i; + isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); for (i = 0; i < 32; i++) { - ISP_IOXGET_32(isp, &src->snscb_fc4_features[i], dst->snscb_fc4_features[i]); + ISP_IOZGET_32(isp, &src->snscb_fc4_features[i], + dst->snscb_fc4_features[i]); } } @@ -1823,42 +1836,42 @@ isp_get_ga_nxt_response(ispsoftc_t *isp, sns_ga_nxt_rs { int i; isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr); - ISP_IOXGET_8(isp, &src->snscb_port_type, dst->snscb_port_type); + ISP_IOZGET_8(isp, &src->snscb_port_type, dst->snscb_port_type); for (i = 0; i < 3; i++) { - ISP_IOXGET_8(isp, &src->snscb_port_id[i], dst->snscb_port_id[i]); + ISP_IOZGET_8(isp, &src->snscb_port_id[i], dst->snscb_port_id[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_portname[i], dst->snscb_portname[i]); + ISP_IOZGET_8(isp, &src->snscb_portname[i], dst->snscb_portname[i]); } - ISP_IOXGET_8(isp, &src->snscb_pnlen, dst->snscb_pnlen); + ISP_IOZGET_8(isp, &src->snscb_pnlen, dst->snscb_pnlen); for (i = 0; i < 255; i++) { - ISP_IOXGET_8(isp, &src->snscb_pname[i], dst->snscb_pname[i]); + ISP_IOZGET_8(isp, &src->snscb_pname[i], dst->snscb_pname[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_nodename[i], dst->snscb_nodename[i]); + ISP_IOZGET_8(isp, &src->snscb_nodename[i], dst->snscb_nodename[i]); } - ISP_IOXGET_8(isp, &src->snscb_nnlen, dst->snscb_nnlen); + ISP_IOZGET_8(isp, &src->snscb_nnlen, dst->snscb_nnlen); for (i = 0; i < 255; i++) { - ISP_IOXGET_8(isp, &src->snscb_nname[i], dst->snscb_nname[i]); + ISP_IOZGET_8(isp, &src->snscb_nname[i], dst->snscb_nname[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_ipassoc[i], dst->snscb_ipassoc[i]); + ISP_IOZGET_8(isp, &src->snscb_ipassoc[i], dst->snscb_ipassoc[i]); } for (i = 0; i < 16; i++) { - ISP_IOXGET_8(isp, &src->snscb_ipaddr[i], dst->snscb_ipaddr[i]); + ISP_IOZGET_8(isp, &src->snscb_ipaddr[i], dst->snscb_ipaddr[i]); } for (i = 0; i < 4; i++) { - ISP_IOXGET_8(isp, &src->snscb_svc_class[i], dst->snscb_svc_class[i]); + ISP_IOZGET_8(isp, &src->snscb_svc_class[i], dst->snscb_svc_class[i]); } for (i = 0; i < 32; i++) { - ISP_IOXGET_8(isp, &src->snscb_fc4_types[i], dst->snscb_fc4_types[i]); + ISP_IOZGET_8(isp, &src->snscb_fc4_types[i], dst->snscb_fc4_types[i]); } for (i = 0; i < 8; i++) { - ISP_IOXGET_8(isp, &src->snscb_fpname[i], dst->snscb_fpname[i]); + ISP_IOZGET_8(isp, &src->snscb_fpname[i], dst->snscb_fpname[i]); } - ISP_IOXGET_8(isp, &src->snscb_reserved, dst->snscb_reserved); + ISP_IOZGET_8(isp, &src->snscb_reserved, dst->snscb_reserved); for (i = 0; i < 3; i++) { - ISP_IOXGET_8(isp, &src->snscb_hardaddr[i], dst->snscb_hardaddr[i]); + ISP_IOZGET_8(isp, &src->snscb_hardaddr[i], dst->snscb_hardaddr[i]); } } Modified: stable/11/sys/dev/isp/isp_library.h ============================================================================== --- stable/11/sys/dev/isp/isp_library.h Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/sys/dev/isp/isp_library.h Tue Aug 1 13:03:06 2017 (r321870) @@ -1,5 +1,6 @@ /* $FreeBSD$ */ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -127,10 +128,11 @@ void isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp void isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *); void isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *); void isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *, sns_gid_ft_req_t *); -void isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *, sns_gxn_id_req_t *); -void isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int); -void isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *, sns_gid_ft_rsp_t *, int); +void isp_put_gid_pt_request(ispsoftc_t *, sns_gid_pt_req_t *, sns_gid_pt_req_t *); +void isp_put_gxx_id_request(ispsoftc_t *, sns_gxx_id_req_t *, sns_gxx_id_req_t *); +void isp_get_gid_xx_response(ispsoftc_t *, sns_gid_xx_rsp_t *, sns_gid_xx_rsp_t *, int); void isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *, sns_gxn_id_rsp_t *); +void isp_get_gft_id_response(ispsoftc_t *, sns_gft_id_rsp_t *, sns_gft_id_rsp_t *); void isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *, sns_gff_id_rsp_t *); void isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *, sns_ga_nxt_rsp_t *); void isp_get_els(ispsoftc_t *, els_t *, els_t *); Modified: stable/11/sys/dev/isp/ispmbox.h ============================================================================== --- stable/11/sys/dev/isp/ispmbox.h Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/sys/dev/isp/ispmbox.h Tue Aug 1 13:03:06 2017 (r321870) @@ -1,5 +1,6 @@ /* $FreeBSD$ */ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -1551,6 +1552,7 @@ typedef struct { #define SNS_GA_NXT 0x100 #define SNS_GPN_ID 0x112 #define SNS_GNN_ID 0x113 +#define SNS_GFT_ID 0x117 #define SNS_GFF_ID 0x11F #define SNS_GID_FT 0x171 #define SNS_GID_PT 0x1A1 @@ -1580,18 +1582,18 @@ typedef struct { } sns_ga_nxt_req_t; #define SNS_GA_NXT_REQ_SIZE (sizeof (sns_ga_nxt_req_t)) -typedef struct { +typedef struct { /* Used for GFT_ID, GFF_ID, etc. */ uint16_t snscb_rblen; /* response buffer length (words) */ uint16_t snscb_reserved0; uint16_t snscb_addr[4]; /* response buffer address */ uint16_t snscb_sblen; /* subcommand buffer length (words) */ uint16_t snscb_reserved1; uint16_t snscb_cmd; - uint16_t snscb_reserved2; + uint16_t snscb_mword_div_2; uint32_t snscb_reserved3; uint32_t snscb_portid; -} sns_gxn_id_req_t; -#define SNS_GXN_ID_REQ_SIZE (sizeof (sns_gxn_id_req_t)) +} sns_gxx_id_req_t; +#define SNS_GXX_ID_REQ_SIZE (sizeof (sns_gxx_id_req_t)) typedef struct { uint16_t snscb_rblen; /* response buffer length (words) */ @@ -1613,6 +1615,22 @@ typedef struct { uint16_t snscb_sblen; /* subcommand buffer length (words) */ uint16_t snscb_reserved1; uint16_t snscb_cmd; + uint16_t snscb_mword_div_2; + uint32_t snscb_reserved3; + uint8_t snscb_port_type; + uint8_t snscb_domain; + uint8_t snscb_area; + uint8_t snscb_flags; +} sns_gid_pt_req_t; +#define SNS_GID_PT_REQ_SIZE (sizeof (sns_gid_pt_req_t)) + +typedef struct { + uint16_t snscb_rblen; /* response buffer length (words) */ + uint16_t snscb_reserved0; + uint16_t snscb_addr[4]; /* response buffer address */ + uint16_t snscb_sblen; /* subcommand buffer length (words) */ + uint16_t snscb_reserved1; + uint16_t snscb_cmd; uint16_t snscb_reserved2; uint32_t snscb_reserved3; uint32_t snscb_port; @@ -1656,18 +1674,24 @@ typedef struct { typedef struct { ct_hdr_t snscb_cthdr; + uint32_t snscb_fc4_types[8]; +} sns_gft_id_rsp_t; +#define SNS_GFT_ID_RESP_SIZE (sizeof (sns_gft_id_rsp_t)) + +typedef struct { + ct_hdr_t snscb_cthdr; uint32_t snscb_fc4_features[32]; } sns_gff_id_rsp_t; #define SNS_GFF_ID_RESP_SIZE (sizeof (sns_gff_id_rsp_t)) -typedef struct { +typedef struct { /* Used for GID_FT, GID_PT, etc. */ ct_hdr_t snscb_cthdr; struct { uint8_t control; uint8_t portid[3]; } snscb_ports[1]; -} sns_gid_ft_rsp_t; -#define SNS_GID_FT_RESP_SIZE(x) ((sizeof (sns_gid_ft_rsp_t)) + ((x - 1) << 2)) +} sns_gid_xx_rsp_t; +#define SNS_GID_XX_RESP_SIZE(x) ((sizeof (sns_gid_xx_rsp_t)) + ((x - 1) << 2)) /* * Other Misc Structures Modified: stable/11/sys/dev/isp/ispvar.h ============================================================================== --- stable/11/sys/dev/isp/ispvar.h Tue Aug 1 13:00:13 2017 (r321869) +++ stable/11/sys/dev/isp/ispvar.h Tue Aug 1 13:03:06 2017 (r321870) @@ -1,5 +1,6 @@ /* $FreeBSD$ */ /*- + * Copyright (c) 2009-2017 Alexander Motin * Copyright (c) 1997-2009 by Matthew Jacob * All rights reserved. * @@ -446,6 +447,8 @@ typedef struct { uint16_t isp_login_hdl; /* Logging in handle */ uint8_t isp_retry_delay; uint8_t isp_retry_count; + int isp_use_gft_id; /* Use GFT_ID */ + int isp_use_gff_id; /* Use GFF_ID */ /* * Current active WWNN/WWPN