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.
This commit is contained in:
parent
8434f2dd55
commit
de1115eaf6
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2009-2015 Alexander Motin <mav@FreeBSD.org>
|
||||
.\" Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
.\" 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 reappear if they (temporarily)
|
||||
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.
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -117,7 +118,7 @@ static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
|
||||
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 cmd_bcnt, uint32_t rsp_bcnt)
|
||||
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 cmd_bcnt, uint32_t rsp_bcnt)
|
||||
/*
|
||||
* 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 cmd_bcnt, uint32_t rsp_bcnt)
|
||||
#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,12 +3577,146 @@ 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)
|
||||
{
|
||||
@ -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 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
}
|
||||
|
||||
/* 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,7 +3778,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
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) {
|
||||
@ -3648,7 +3788,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
} 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);
|
||||
@ -3780,6 +3920,20 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
|
||||
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;
|
||||
}
|
||||
|
||||
if (isp_login_device(isp, chan, portid, &pdb,
|
||||
&FCPARAM(isp, 0)->isp_lasthdl)) {
|
||||
if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -169,6 +170,8 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
|
||||
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, int chan)
|
||||
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);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
* 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_t *src, sns_gid_ft_req_t
|
||||
}
|
||||
|
||||
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_t *src, sns_gxn_id_req_t
|
||||
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_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);
|
||||
}
|
||||
|
||||
void
|
||||
isp_put_gxx_id_request(ispsoftc_t *isp, sns_gxx_id_req_t *src, sns_gxx_id_req_t *dst)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_get_gid_xx_response(ispsoftc_t *isp, sns_gid_xx_rsp_t *src, sns_gid_xx_rsp_t *dst, int nwords)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
int i, j;
|
||||
|
||||
void
|
||||
isp_get_gid_ft_response(ispsoftc_t *isp, sns_gid_ft_rsp_t *src, sns_gid_ft_rsp_t *dst, int nwords)
|
||||
{
|
||||
int i;
|
||||
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_rsp_t *src, sns_ga_nxt_rsp_t
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
* 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_ct_pt_t *);
|
||||
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 *);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
* 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) */
|
||||
@ -1606,6 +1608,22 @@ typedef struct {
|
||||
} sns_gid_ft_req_t;
|
||||
#define SNS_GID_FT_REQ_SIZE (sizeof (sns_gid_ft_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_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;
|
||||
@ -1654,20 +1672,26 @@ typedef struct {
|
||||
} sns_gxn_id_rsp_t;
|
||||
#define SNS_GXN_ID_RESP_SIZE (sizeof (sns_gxn_id_rsp_t))
|
||||
|
||||
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
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* $FreeBSD$ */
|
||||
/*-
|
||||
* Copyright (c) 2009-2017 Alexander Motin <mav@FreeBSD.org>
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user