Fix bus dma segment count to be based off of MAXPHYS, not BUS_SPACE_MAXSIZE.

Grumble. I've seen better documented architectures out of Redmond.

Redo fabric evaluation to not use GET ALL NEXT (GA_NXT). Switches seem
to be trying to wriggle out of supporting this well. Instead, use
GID_FT to get a list of Port IDs and then use GPN_ID/GNN_ID to find the
port and node wwn. This should make working on fabrics a bit cleaner and
more stable.

This also caused some cleanup of SNS subcommand canonicalization so that
we can actually check for FS_ACC and FS_RJT, and if we get an FS_RJT,
print out the reason and explanation codes.

We'll keep the old GA_NXT method around if people want to uncomment a
controlling definition in ispvar.h.

This also had us clean up ISPASYNC_FABRICDEV to use a local lportdb argument
and to have the caller explicitly say that a device is at the end of the
fabric list.

MFC after:	1 week
This commit is contained in:
Matt Jacob 2002-04-04 23:46:01 +00:00
parent 635435f4f6
commit 029f13c671
7 changed files with 681 additions and 162 deletions

View File

@ -96,6 +96,8 @@ static const char pskip[] =
"SCSI phase skipped for target %d.%d.%d";
static const char topology[] =
"Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
static const char swrej[] =
"Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
static const char finmsg[] =
"(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
static const char sc0[] =
@ -127,7 +129,8 @@ static int isp_fclink_test(struct ispsoftc *, int);
static char *isp2100_fw_statename(int);
static int isp_pdb_sync(struct ispsoftc *);
static int isp_scan_loop(struct ispsoftc *);
static int isp_scan_fabric(struct ispsoftc *);
static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
static int isp_scan_fabric(struct ispsoftc *, int);
static void isp_register_fc4_type(struct ispsoftc *);
static void isp_fw_state(struct ispsoftc *);
static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
@ -2298,21 +2301,69 @@ isp_scan_loop(struct ispsoftc *isp)
return (0);
}
#ifndef HICAP_MAX
#define HICAP_MAX 256
#endif
static int
isp_scan_fabric(struct ispsoftc *isp)
isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
{
isp_mboxcmd(isp, mbp, MBLOGNONE);
if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
}
if (mbp->param[0] == MBOX_COMMAND_ERROR) {
char tbuf[16];
char *m;
switch (mbp->param[1]) {
case 1:
m = "No Loop";
break;
case 2:
m = "Failed to allocate IOCB buffer";
break;
case 3:
m = "Failed to allocate XCB buffer";
break;
case 4:
m = "timeout or transmit failed";
break;
case 5:
m = "no fabric loop";
break;
case 6:
m = "remote device not a target";
break;
default:
SNPRINTF(tbuf, sizeof tbuf, "%x",
mbp->param[1]);
m = tbuf;
break;
}
isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
}
return (-1);
}
if (FCPARAM(isp)->isp_fwstate != FW_READY ||
FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
return (-1);
}
return(0);
}
#ifdef ISP_USE_GA_NXT
static int
isp_scan_fabric(struct ispsoftc *isp, int ftype)
{
fcparam *fcp = isp->isp_param;
u_int32_t portid, first_portid, last_portid;
int hicap, first_portid_seen, last_port_same;
int hicap, last_port_same;
if (fcp->isp_onfabric == 0) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
FC_SCRATCH_ACQUIRE(isp);
/*
* Since Port IDs are 24 bits, we can check against having seen
@ -2323,28 +2374,28 @@ isp_scan_fabric(struct ispsoftc *isp)
first_portid = portid = fcp->isp_portid;
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
for (first_portid_seen = hicap = 0; hicap < HICAP_MAX; hicap++) {
for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
mbreg_t mbs;
sns_screq_t *rq;
sns_ganrsp_t *rs0, *rs1;
u_int8_t sc[SNS_GAN_REQ_SIZE];
sns_ga_nxt_rsp_t *rs0, *rs1;
struct lportdb lcl;
u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
rq = (sns_screq_t *)sc;
MEMZERO((void *) rq, SNS_GAN_REQ_SIZE);
rq->snscb_rblen = SNS_GAN_RESP_SIZE >> 1;
MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
rq->snscb_sblen = 6;
rq->snscb_data[0] = SNS_GAN;
rq->snscb_data[0] = SNS_GA_NXT;
rq->snscb_data[4] = portid & 0xffff;
rq->snscb_data[5] = (portid >> 16) & 0xff;
FC_SCRATCH_ACQUIRE(isp);
isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GAN_REQ_SIZE);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GAN_REQ_SIZE >> 1;
mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
@ -2352,59 +2403,80 @@ isp_scan_fabric(struct ispsoftc *isp)
*/
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC) {
if (isp_fabric_mbox_cmd(isp, &mbs)) {
if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
fcp->isp_loopstate = LOOP_PDB_RCVD;
}
if (mbs.param[0] == MBOX_COMMAND_ERROR) {
char tbuf[16];
char *m;
switch (mbs.param[1]) {
case 1:
m = "No Loop";
break;
case 2:
m = "Failed to allocate IOCB buffer";
break;
case 3:
m = "Failed to allocate XCB buffer";
break;
case 4:
m = "timeout or transmit failed";
break;
case 5:
m = "no fabric loop";
break;
case 6:
m = "remote device not a target";
break;
default:
SNPRINTF(tbuf, sizeof tbuf, "%x",
mbs.param[1]);
m = tbuf;
break;
}
isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
}
return (-1);
}
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GAN_RESP_SIZE);
rs1 = (sns_ganrsp_t *) fcp->isp_scratch;
rs0 = (sns_ganrsp_t *) ((u_int8_t *)fcp->isp_scratch + 0x100);
isp_get_gan_response(isp, rs0, rs1);
FC_SCRATCH_RELEASE(isp);
portid = (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
rs1 = (sns_ga_nxt_rsp_t *) sc;
rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
isp_get_ga_nxt_response(isp, rs0, rs1);
if (rs1->snscb_cthdr.ct_response != FS_ACC) {
isp_prt(isp, ISP_LOGWARN, swrej, "GA_NXT",
rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation, portid);
FC_SCRATCH_RELEASE(isp);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
portid =
(((u_int32_t) rs1->snscb_port_id[0]) << 16) |
(((u_int32_t) rs1->snscb_port_id[1]) << 8) |
(((u_int32_t) rs1->snscb_port_id[2]));
(void) isp_async(isp, ISPASYNC_FABRIC_DEV, rs1);
/*
* Okay, we now have information about a fabric object.
* If it is the type we're interested in, tell the outer layers
* about it. The outer layer needs to know: Port ID, WWNN,
* WWPN, FC4 type, and port type.
*
* The lportdb structure is adequate for this.
*/
MEMZERO(&lcl, sizeof (lcl));
lcl.port_type = rs1->snscb_port_type;
lcl.fc4_type = ftype;
lcl.portid = portid;
lcl.node_wwn =
(((u_int64_t)rs1->snscb_nodename[0]) << 56) |
(((u_int64_t)rs1->snscb_nodename[1]) << 48) |
(((u_int64_t)rs1->snscb_nodename[2]) << 40) |
(((u_int64_t)rs1->snscb_nodename[3]) << 32) |
(((u_int64_t)rs1->snscb_nodename[4]) << 24) |
(((u_int64_t)rs1->snscb_nodename[5]) << 16) |
(((u_int64_t)rs1->snscb_nodename[6]) << 8) |
(((u_int64_t)rs1->snscb_nodename[7]));
lcl.port_wwn =
(((u_int64_t)rs1->snscb_portname[0]) << 56) |
(((u_int64_t)rs1->snscb_portname[1]) << 48) |
(((u_int64_t)rs1->snscb_portname[2]) << 40) |
(((u_int64_t)rs1->snscb_portname[3]) << 32) |
(((u_int64_t)rs1->snscb_portname[4]) << 24) |
(((u_int64_t)rs1->snscb_portname[5]) << 16) |
(((u_int64_t)rs1->snscb_portname[6]) << 8) |
(((u_int64_t)rs1->snscb_portname[7]));
/*
* Does this fabric object support the type we want?
* If not, skip it.
*/
if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
if (first_portid == portid) {
lcl.last_fabric_dev = 1;
} else {
lcl.last_fabric_dev = 0;
}
(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
} else {
isp_prt(isp, ISP_LOGDEBUG0,
"PortID 0x%x doesn't support FC4 type 0x%x",
portid, ftype);
}
if (first_portid == portid) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
FC_SCRATCH_RELEASE(isp);
return (0);
}
if (portid == last_portid) {
@ -2414,47 +2486,285 @@ isp_scan_fabric(struct ispsoftc *isp)
break;
}
} else {
last_port_same = 0 ;
last_portid = portid;
}
}
if (hicap >= 65535) {
isp_prt(isp, ISP_LOGWARN, "fabric too big (> 65535)");
FC_SCRATCH_RELEASE(isp);
if (hicap >= GA_NXT_MAX) {
isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
}
/*
* We either have a broken name server or a huge fabric if we get here.
*/
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
#else
#define GIDLEN ((ISP2100_SCRLEN >> 1) + 16)
#define NGENT ((GIDLEN - 16) >> 2)
#define IGPOFF (ISP2100_SCRLEN - GIDLEN)
#define GXOFF (256)
static int
isp_scan_fabric(struct ispsoftc *isp, int ftype)
{
fcparam *fcp = FCPARAM(isp);
mbreg_t mbs;
u_int8_t sc[GIDLEN]; /* XXX USE ->tport */
int i;
sns_gid_ft_req_t *rq;
sns_gid_ft_rsp_t *rs0, *rs1;
if (fcp->isp_onfabric == 0) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
FC_SCRATCH_ACQUIRE(isp);
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
rq = (sns_gid_ft_req_t *)sc;
MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
rq->snscb_rblen = GIDLEN >> 1;
rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
rq->snscb_sblen = 6;
rq->snscb_cmd = SNS_GID_FT;
rq->snscb_mword_div_2 = NGENT;
rq->snscb_fc4_type = ftype;
isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
* Leave 4 and 5 alone
*/
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
if (isp_fabric_mbox_cmd(isp, &mbs)) {
if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
fcp->isp_loopstate = LOOP_PDB_RCVD;
}
FC_SCRATCH_RELEASE(isp);
return (-1);
}
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
rs1 = (sns_gid_ft_rsp_t *) sc;
rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
if (rs1->snscb_cthdr.ct_response != FS_ACC) {
isp_prt(isp, ISP_LOGWARN, swrej, "GID_FT",
rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation, 0);
FC_SCRATCH_RELEASE(isp);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
/*
* Okay, we now have a list of Port IDs for this class of device.
* Go through the list and for each one get the WWPN/WWNN for it
* and tell the outer layers about it. The outer layer needs to
* know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
*
* The lportdb structure is adequate for this.
*/
i = -1;
do {
sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
struct lportdb lcl;
i++;
MEMZERO(&lcl, sizeof (lcl));
lcl.fc4_type = ftype;
lcl.portid =
(((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
(((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
(((u_int32_t) rs1->snscb_ports[i].portid[2]));
MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
gq->snscb_sblen = 6;
gq->snscb_cmd = SNS_GPN_ID;
gq->snscb_portid = lcl.portid;
isp_put_gxn_id_request(isp, gq,
(sns_gxn_id_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
* Leave 4 and 5 alone
*/
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
if (isp_fabric_mbox_cmd(isp, &mbs)) {
if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
fcp->isp_loopstate = LOOP_PDB_RCVD;
}
FC_SCRATCH_RELEASE(isp);
return (-1);
}
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
isp_get_gxn_id_response(isp, gs0, gs1);
if (gs1->snscb_cthdr.ct_response != FS_ACC) {
isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation, lcl.portid);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
continue;
}
lcl.port_wwn =
(((u_int64_t)gs1->snscb_wwn[0]) << 56) |
(((u_int64_t)gs1->snscb_wwn[1]) << 48) |
(((u_int64_t)gs1->snscb_wwn[2]) << 40) |
(((u_int64_t)gs1->snscb_wwn[3]) << 32) |
(((u_int64_t)gs1->snscb_wwn[4]) << 24) |
(((u_int64_t)gs1->snscb_wwn[5]) << 16) |
(((u_int64_t)gs1->snscb_wwn[6]) << 8) |
(((u_int64_t)gs1->snscb_wwn[7]));
MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
gq->snscb_sblen = 6;
gq->snscb_cmd = SNS_GNN_ID;
gq->snscb_portid = lcl.portid;
isp_put_gxn_id_request(isp, gq,
(sns_gxn_id_req_t *) fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
* Leave 4 and 5 alone
*/
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
if (isp_fabric_mbox_cmd(isp, &mbs)) {
if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
fcp->isp_loopstate = LOOP_PDB_RCVD;
}
FC_SCRATCH_RELEASE(isp);
return (-1);
}
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
isp_get_gxn_id_response(isp, gs0, gs1);
if (gs1->snscb_cthdr.ct_response != FS_ACC) {
isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation, lcl.portid);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
continue;
}
lcl.node_wwn =
(((u_int64_t)gs1->snscb_wwn[0]) << 56) |
(((u_int64_t)gs1->snscb_wwn[1]) << 48) |
(((u_int64_t)gs1->snscb_wwn[2]) << 40) |
(((u_int64_t)gs1->snscb_wwn[3]) << 32) |
(((u_int64_t)gs1->snscb_wwn[4]) << 24) |
(((u_int64_t)gs1->snscb_wwn[5]) << 16) |
(((u_int64_t)gs1->snscb_wwn[6]) << 8) |
(((u_int64_t)gs1->snscb_wwn[7]));
/*
* XXX: Argh! I saw some PDF which I now can't find that
* XXX: had proposed that the bottom nibble of CONTROL
* XXX: would have the SCSI-FCP role flags, which would
* XXX: be *awesome*.
*
lcl.roles = rs1->snscb_port[i].control & 0xf;
*/
/*
* If we really want to know what kind of port type this is,
* we have to run another CT command. Otherwise, we'll leave
* it as undefined.
*
lcl.port_type = 0;
*/
if (rs1->snscb_ports[i].control & 0x80) {
lcl.last_fabric_dev = 1;
} else {
lcl.last_fabric_dev = 0;
}
(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
} while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
/*
* If we're not at the last entry, our list isn't big enough.
*/
if ((rs1->snscb_ports[i].control & 0x80) == 0) {
isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
}
FC_SCRATCH_RELEASE(isp);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
#endif
static void
isp_register_fc4_type(struct ispsoftc *isp)
{
fcparam *fcp = isp->isp_param;
u_int8_t local[SNS_RFT_REQ_SIZE];
u_int8_t local[SNS_RFT_ID_REQ_SIZE];
sns_screq_t *reqp = (sns_screq_t *) local;
mbreg_t mbs;
MEMZERO((void *) reqp, SNS_RFT_REQ_SIZE);
reqp->snscb_rblen = SNS_RFT_RESP_SIZE >> 1;
MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
reqp->snscb_sblen = 22;
reqp->snscb_data[0] = SNS_RFT;
reqp->snscb_data[0] = SNS_RFT_ID;
reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
reqp->snscb_data[6] = 0x100; /* SCS - FCP */
reqp->snscb_data[6] = (1 << FC4_SCSI);
#if 0
reqp->snscb_data[6] |= 20; /* ISO/IEC 8802-2 LLC/SNAP */
reqp->snscb_data[6] |= (1 << FC4_IP); /* ISO/IEC 8802-2 LLC/SNAP */
#endif
FC_SCRATCH_ACQUIRE(isp);
isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
mbs.param[0] = MBOX_SEND_SNS;
mbs.param[1] = SNS_RFT_REQ_SIZE >> 1;
mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
/*
@ -2652,7 +2962,7 @@ isp_start(XS_T *xs)
* out and try again later if this doesn't work.
*/
if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
if (isp_scan_fabric(isp)) {
if (isp_scan_fabric(isp, FC4_SCSI)) {
return (CMD_RQLATER);
}
if (fcp->isp_fwstate != FW_READY ||
@ -2951,7 +3261,8 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
case ISPCTL_SCAN_FABRIC:
if (IS_FC(isp)) {
return (isp_scan_fabric(isp));
int ftype = (arg)? *((int *) arg) : FC4_SCSI;
return (isp_scan_fabric(isp, ftype));
}
break;

View File

@ -2734,43 +2734,13 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
break;
case ISPASYNC_FABRIC_DEV:
{
int target, lrange;
struct lportdb *lp = NULL;
char *pt;
sns_ganrsp_t *resp = (sns_ganrsp_t *) arg;
u_int32_t portid;
u_int64_t wwpn, wwnn;
int target, base, lim;
fcparam *fcp = isp->isp_param;
struct lportdb *lp = NULL;
struct lportdb *clp = (struct lportdb *) arg;
char *pt;
portid =
(((u_int32_t) resp->snscb_port_id[0]) << 16) |
(((u_int32_t) resp->snscb_port_id[1]) << 8) |
(((u_int32_t) resp->snscb_port_id[2]));
wwpn =
(((u_int64_t)resp->snscb_portname[0]) << 56) |
(((u_int64_t)resp->snscb_portname[1]) << 48) |
(((u_int64_t)resp->snscb_portname[2]) << 40) |
(((u_int64_t)resp->snscb_portname[3]) << 32) |
(((u_int64_t)resp->snscb_portname[4]) << 24) |
(((u_int64_t)resp->snscb_portname[5]) << 16) |
(((u_int64_t)resp->snscb_portname[6]) << 8) |
(((u_int64_t)resp->snscb_portname[7]));
wwnn =
(((u_int64_t)resp->snscb_nodename[0]) << 56) |
(((u_int64_t)resp->snscb_nodename[1]) << 48) |
(((u_int64_t)resp->snscb_nodename[2]) << 40) |
(((u_int64_t)resp->snscb_nodename[3]) << 32) |
(((u_int64_t)resp->snscb_nodename[4]) << 24) |
(((u_int64_t)resp->snscb_nodename[5]) << 16) |
(((u_int64_t)resp->snscb_nodename[6]) << 8) |
(((u_int64_t)resp->snscb_nodename[7]));
if (portid == 0 || wwpn == 0) {
break;
}
switch (resp->snscb_port_type) {
switch (clp->port_type) {
case 1:
pt = " N_Port";
break;
@ -2793,40 +2763,66 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
pt = " E_port";
break;
default:
pt = "?";
pt = " ";
break;
}
isp_prt(isp, ISP_LOGINFO,
"%s @ 0x%x, Node 0x%08x%08x Port %08x%08x",
pt, portid, ((u_int32_t) (wwnn >> 32)), ((u_int32_t) wwnn),
((u_int32_t) (wwpn >> 32)), ((u_int32_t) wwpn));
"%s Fabric Device @ PortID 0x%x", pt, clp->portid);
/*
* We're only interested in SCSI_FCP types (for now)
* If we don't have an initiator role we bail.
*
* We just use ISPASYNC_FABRIC_DEV for announcement purposes.
*/
if ((resp->snscb_fc4_types[2] & 1) == 0) {
if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
break;
}
if (fcp->isp_topo != TOPO_F_PORT)
lrange = FC_SNS_ID+1;
/*
* Is this entry for us? If so, we bail.
*/
if (fcp->isp_portid == clp->portid) {
break;
}
/*
* Else, the default policy is to find room for it in
* our local port database. Later, when we execute
* the call to isp_pdb_sync either this newly arrived
* or already logged in device will be (re)announced.
*/
if (fcp->isp_topo == TOPO_FL_PORT)
base = FC_SNS_ID+1;
else
lrange = 0;
base = 0;
if (fcp->isp_topo == TOPO_N_PORT)
lim = 1;
else
lim = MAX_FC_TARG;
/*
* Is it already in our list?
*/
for (target = lrange; target < MAX_FC_TARG; target++) {
for (target = base; target < lim; target++) {
if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
continue;
}
lp = &fcp->portdb[target];
if (lp->port_wwn == wwpn && lp->node_wwn == wwnn) {
if (lp->port_wwn == clp->port_wwn &&
lp->node_wwn == clp->node_wwn) {
lp->fabric_dev = 1;
break;
}
}
if (target < MAX_FC_TARG) {
if (target < lim) {
break;
}
for (target = lrange; target < MAX_FC_TARG; target++) {
for (target = base; target < lim; target++) {
if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
continue;
}
@ -2835,14 +2831,16 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
break;
}
}
if (target == MAX_FC_TARG) {
if (target == lim) {
isp_prt(isp, ISP_LOGWARN,
"no more space for fabric devices");
"out of space for fabric devices");
break;
}
lp->node_wwn = wwnn;
lp->port_wwn = wwpn;
lp->portid = portid;
lp->port_type = clp->port_type;
lp->fc4_type = clp->fc4_type;
lp->node_wwn = clp->node_wwn;
lp->port_wwn = clp->port_wwn;
lp->portid = clp->portid;
lp->fabric_dev = 1;
break;
}

View File

@ -156,7 +156,7 @@ struct isposinfo {
#define INLINE __inline
#define ISP2100_SCRLEN 0x400
#define ISP2100_SCRLEN 0x800
#define MEMZERO bzero
#define MEMCPY(dst, src, amt) bcopy((src), (dst), (amt))

View File

@ -275,11 +275,26 @@ isp_put_icb(struct ispsoftc *, isp_icb_t *, isp_icb_t *);
static INLINE void
isp_get_pdb(struct ispsoftc *, isp_pdb_t *, isp_pdb_t *);
static INLINE void
isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *, ct_hdr_t *);
static INLINE void
isp_put_sns_request(struct ispsoftc *, sns_screq_t *, sns_screq_t *);
static INLINE void
isp_put_gid_ft_request(struct ispsoftc *, sns_gid_ft_req_t *,
sns_gid_ft_req_t *);
static INLINE void
isp_put_gxn_id_request(struct ispsoftc *, sns_gxn_id_req_t *,
sns_gxn_id_req_t *);
static INLINE void
isp_get_sns_response(struct ispsoftc *, sns_scrsp_t *, sns_scrsp_t *, int);
static INLINE void
isp_get_gan_response(struct ispsoftc *, sns_ganrsp_t *, sns_ganrsp_t *);
isp_get_gid_ft_response(struct ispsoftc *, sns_gid_ft_rsp_t *,
sns_gid_ft_rsp_t *, int);
static INLINE void
isp_get_gxn_id_response(struct ispsoftc *, sns_gxn_id_rsp_t *,
sns_gxn_id_rsp_t *);
static INLINE void
isp_get_ga_nxt_response(struct ispsoftc *, sns_ga_nxt_rsp_t *,
sns_ga_nxt_rsp_t *);
#ifdef ISP_TARGET_MODE
#ifndef _ISP_TARGET_H
#include "isp_target.h"
@ -673,6 +688,35 @@ isp_get_pdb(struct ispsoftc *isp, isp_pdb_t *src, isp_pdb_t *dst)
ISP_IOXGET_16(isp, &src->pdb_sl_ptr, dst->pdb_sl_ptr);
}
/*
* CT_HDR canonicalization- only needed for SNS responses
*/
static INLINE void
isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *src, ct_hdr_t *dst)
{
ISP_IOXGET_8(isp, &src->ct_revision, dst->ct_revision);
ISP_IOXGET_8(isp, &src->ct_portid[0], dst->ct_portid[0]);
ISP_IOXGET_8(isp, &src->ct_portid[1], dst->ct_portid[1]);
ISP_IOXGET_8(isp, &src->ct_portid[2], dst->ct_portid[2]);
ISP_IOXGET_8(isp, &src->ct_fcs_type, dst->ct_fcs_type);
ISP_IOXGET_8(isp, &src->ct_fcs_subtype, dst->ct_fcs_subtype);
ISP_IOXGET_8(isp, &src->ct_options, dst->ct_options);
ISP_IOXGET_8(isp, &src->ct_res0, dst->ct_res0);
ISP_IOXGET_16(isp, &src->ct_response, dst->ct_response);
dst->ct_response = (dst->ct_response << 8) | (dst->ct_response >> 8);
ISP_IOXGET_16(isp, &src->ct_resid, dst->ct_resid);
dst->ct_resid = (dst->ct_resid << 8) | (dst->ct_resid >> 8);
ISP_IOXGET_8(isp, &src->ct_res1, dst->ct_res1);
ISP_IOXGET_8(isp, &src->ct_reason, dst->ct_reason);
ISP_IOXGET_8(isp, &src->ct_explanation, dst->ct_explanation);
ISP_IOXGET_8(isp, &src->ct_vunique, dst->ct_vunique);
}
/*
* Generic SNS request - not particularly useful since the per-command data
* isn't always 16 bit words.
*/
static INLINE void
isp_put_sns_request(struct ispsoftc *isp, sns_screq_t *src, sns_screq_t *dst)
{
@ -688,14 +732,52 @@ isp_put_sns_request(struct ispsoftc *isp, sns_screq_t *src, sns_screq_t *dst)
}
static INLINE void
isp_put_gid_ft_request(struct ispsoftc *isp, sns_gid_ft_req_t *src,
sns_gid_ft_req_t *dst)
{
ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen);
ISP_IOXPUT_16(isp, src->snscb_res0, &dst->snscb_res0);
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_res1, &dst->snscb_res1);
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_res3, &dst->snscb_res3);
ISP_IOXPUT_16(isp, src->snscb_fc4_type, &dst->snscb_fc4_type);
}
static INLINE void
isp_put_gxn_id_request(struct ispsoftc *isp, sns_gxn_id_req_t *src,
sns_gxn_id_req_t *dst)
{
ISP_IOXPUT_16(isp, src->snscb_rblen, &dst->snscb_rblen);
ISP_IOXPUT_16(isp, src->snscb_res0, &dst->snscb_res0);
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_res1, &dst->snscb_res1);
ISP_IOXPUT_16(isp, src->snscb_cmd, &dst->snscb_cmd);
ISP_IOXPUT_16(isp, src->snscb_res2, &dst->snscb_res2);
ISP_IOXPUT_32(isp, src->snscb_res3, &dst->snscb_res3);
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.
*/
static INLINE void
isp_get_sns_response(struct ispsoftc *isp, sns_scrsp_t *src,
sns_scrsp_t *dst, int nwords)
{
int i;
for (i = 0; i < 16; i++) {
ISP_IOXGET_8(isp, &src->snscb_cthdr[i], dst->snscb_cthdr[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],
@ -711,12 +793,43 @@ isp_get_sns_response(struct ispsoftc *isp, sns_scrsp_t *src,
}
static INLINE void
isp_get_gan_response(struct ispsoftc *isp, sns_ganrsp_t *src, sns_ganrsp_t *dst)
isp_get_gid_ft_response(struct ispsoftc *isp, sns_gid_ft_rsp_t *src,
sns_gid_ft_rsp_t *dst, int nwords)
{
int i;
for (i = 0; i < 16; i++) {
ISP_IOXGET_8(isp, &src->snscb_cthdr[i], dst->snscb_cthdr[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);
for (j = 0; j < 3; j++) {
ISP_IOXGET_8(isp,
&src->snscb_ports[i].portid[j],
dst->snscb_ports[i].portid[j]);
}
if (dst->snscb_ports[i].control & 0x80) {
break;
}
}
}
static INLINE void
isp_get_gxn_id_response(struct ispsoftc *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_IOXGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]);
}
static INLINE void
isp_get_ga_nxt_response(struct ispsoftc *isp, sns_ga_nxt_rsp_t *src,
sns_ga_nxt_rsp_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],

View File

@ -240,16 +240,6 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_QLOGIC_ISP2312 \
((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
/*
* I/O Mapping Stuff
*/
#if _MACHINE_ARCH == SPARC64
/* An IOMMU means that we only will ever need one descriptor. */
#define ISP_NSEG 2
#else
#define ISP_NSEG ((MAXPHYS/PAGE_SIZE) + 1)
#endif
/*
* Odd case for some AMI raid cards... We need to *not* attach to this.
*/
@ -1031,7 +1021,10 @@ imc(void *arg, bus_dma_segment_t *segs, int nseg, int error)
}
}
#define ISP_NSEGS ((BUS_SPACE_MAXSIZE / PAGE_SIZE) + 1)
/*
* Should be BUS_SPACE_MAXSIZE, but MAXPHYS is larger than BUS_SPACE_MAXSIZE
*/
#define ISP_NSEGS ((MAXPHYS / PAGE_SIZE) + 1)
static int
isp_pci_mbxdma(struct ispsoftc *isp)

View File

@ -773,9 +773,39 @@ typedef struct {
#define SVC3_ROLE_MASK 0x30
#define SVC3_ROLE_SHIFT 4
#define SNS_GAN 0x100
#define SNS_GP3 0x171
#define SNS_RFT 0x217
/*
* CT definition
*
* This is as the QLogic f/w documentations defines it- which is just opposite,
* bit wise, from what the specification defines it as. Additionally, the
* ct_response and ct_resid (really from FC-GS-2) need to be byte swapped.
*/
typedef struct {
u_int8_t ct_revision;
u_int8_t ct_portid[3];
u_int8_t ct_fcs_type;
u_int8_t ct_fcs_subtype;
u_int8_t ct_options;
u_int8_t ct_res0;
u_int16_t ct_response;
u_int16_t ct_resid;
u_int8_t ct_res1;
u_int8_t ct_reason;
u_int8_t ct_explanation;
u_int8_t ct_vunique;
} ct_hdr_t;
#define FS_ACC 0x8002
#define FS_RJT 0x8001
#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP "Out of Order Delivery" */
#define FC4_SCSI 8 /* SCSI-3 via Fivre Channel Protocol (FCP) */
#define SNS_GA_NXT 0x100
#define SNS_GPN_ID 0x112
#define SNS_GNN_ID 0x113
#define SNS_GID_FT 0x171
#define SNS_RFT_ID 0x217
typedef struct {
u_int16_t snscb_rblen; /* response buffer length (words) */
u_int16_t snscb_res0;
@ -784,23 +814,70 @@ typedef struct {
u_int16_t snscb_res1;
u_int16_t snscb_data[1]; /* variable data */
} sns_screq_t; /* Subcommand Request Structure */
#define SNS_GAN_REQ_SIZE (sizeof (sns_screq_t)+(5*(sizeof (u_int16_t))))
#define SNS_GP3_REQ_SIZE (sizeof (sns_screq_t)+(5*(sizeof (u_int16_t))))
#define SNS_RFT_REQ_SIZE (sizeof (sns_screq_t)+(21*(sizeof (u_int16_t))))
typedef struct {
u_int8_t snscb_cthdr[16];
u_int16_t snscb_rblen; /* response buffer length (words) */
u_int16_t snscb_res0;
u_int16_t snscb_addr[4]; /* response buffer address */
u_int16_t snscb_sblen; /* subcommand buffer length (words) */
u_int16_t snscb_res1;
u_int16_t snscb_cmd;
u_int16_t snscb_res2;
u_int32_t snscb_res3;
u_int32_t snscb_port;
} sns_ga_nxt_req_t;
#define SNS_GA_NXT_REQ_SIZE (sizeof (sns_ga_nxt_req_t))
typedef struct {
u_int16_t snscb_rblen; /* response buffer length (words) */
u_int16_t snscb_res0;
u_int16_t snscb_addr[4]; /* response buffer address */
u_int16_t snscb_sblen; /* subcommand buffer length (words) */
u_int16_t snscb_res1;
u_int16_t snscb_cmd;
u_int16_t snscb_res2;
u_int32_t snscb_res3;
u_int32_t snscb_portid;
} sns_gxn_id_req_t;
#define SNS_GXN_ID_REQ_SIZE (sizeof (sns_gxn_id_req_t))
typedef struct {
u_int16_t snscb_rblen; /* response buffer length (words) */
u_int16_t snscb_res0;
u_int16_t snscb_addr[4]; /* response buffer address */
u_int16_t snscb_sblen; /* subcommand buffer length (words) */
u_int16_t snscb_res1;
u_int16_t snscb_cmd;
u_int16_t snscb_mword_div_2;
u_int32_t snscb_res3;
u_int32_t snscb_fc4_type;
} sns_gid_ft_req_t;
#define SNS_GID_FT_REQ_SIZE (sizeof (sns_gid_ft_req_t))
typedef struct {
u_int16_t snscb_rblen; /* response buffer length (words) */
u_int16_t snscb_res0;
u_int16_t snscb_addr[4]; /* response buffer address */
u_int16_t snscb_sblen; /* subcommand buffer length (words) */
u_int16_t snscb_res1;
u_int16_t snscb_cmd;
u_int16_t snscb_res2;
u_int32_t snscb_res3;
u_int32_t snscb_port;
u_int32_t snscb_fc4_types[8];
} sns_rft_id_req_t;
#define SNS_RFT_ID_REQ_SIZE (sizeof (sns_rft_id_req_t))
typedef struct {
ct_hdr_t snscb_cthdr;
u_int8_t snscb_port_type;
u_int8_t snscb_port_id[3];
u_int8_t snscb_portname[8];
u_int16_t snscb_data[1]; /* variable data */
} sns_scrsp_t; /* Subcommand Response Structure */
#define SNS_GAN_RESP_SIZE 608 /* Maximum response size (bytes) */
#define SNS_GP3_RESP_SIZE 532 /* XXX: For 128 ports */
#define SNS_RFT_RESP_SIZE 16
typedef struct {
u_int8_t snscb_cthdr[16];
ct_hdr_t snscb_cthdr;
u_int8_t snscb_port_type;
u_int8_t snscb_port_id[3];
u_int8_t snscb_portname[8];
@ -816,6 +893,25 @@ typedef struct {
u_int8_t snscb_fpname[8];
u_int8_t snscb_reserved;
u_int8_t snscb_hardaddr[3];
} sns_ganrsp_t; /* Subcommand Response Structure */
} sns_ga_nxt_rsp_t; /* Subcommand Response Structure */
#define SNS_GA_NXT_RESP_SIZE (sizeof (sns_ga_nxt_rsp_t))
typedef struct {
ct_hdr_t snscb_cthdr;
u_int8_t snscb_wwn[8];
} sns_gxn_id_rsp_t;
#define SNS_GXN_ID_RESP_SIZE (sizeof (sns_gxn_id_rsp_t))
typedef struct {
ct_hdr_t snscb_cthdr;
struct {
u_int8_t control;
u_int8_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))
#define SNS_RFT_ID_RESP_SIZE (sizeof (ct_hdr_t))
#endif /* _ISPMBOX_H */

View File

@ -54,7 +54,7 @@
#endif
#define ISP_CORE_VERSION_MAJOR 2
#define ISP_CORE_VERSION_MINOR 5
#define ISP_CORE_VERSION_MINOR 6
/*
* Vector for bus specific code to provide specific services.
@ -246,6 +246,11 @@ typedef struct {
#define FC_PORT_ID 0x7f /* Fabric Controller Special ID */
#define FC_SNS_ID 0x80 /* SNS Server Special ID */
/* #define ISP_USE_GA_NXT 1 */ /* Use GA_NXT with switches */
#ifndef GA_NXT_MAX
#define GA_NXT_MAX 256
#endif
typedef struct {
u_int32_t isp_fwoptions : 16,
isp_gbspeed : 2,
@ -280,9 +285,12 @@ typedef struct {
* to move around.
*/
struct lportdb {
u_int
u_int32_t
port_type : 8,
: 4,
fc4_type : 4,
loopid : 8,
: 1,
last_fabric_dev : 1,
force_logout : 1,
was_fabric_dev : 1,
fabric_dev : 1,