Use a SNS REGISTER FC4 TYPE subcommand to register with the name server.
This means we should be able to work with McData switches now. Change ISPASYNC_PDB_CHANGED to ISPASYNC_LOGGED_INOUT (more descriptive). Allow F-Port topologies to use target ids 0..125 to log into fabric devices. Yet again fool around with defaul WWN stuff.
This commit is contained in:
parent
12a0ea436c
commit
81df08ddef
147
sys/dev/ic/isp.c
147
sys/dev/ic/isp.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: isp.c,v 1.68 2000/12/30 19:47:20 mjacob Exp $ */
|
||||
/* $NetBSD: isp.c,v 1.69 2001/01/09 18:54:06 mjacob Exp $ */
|
||||
/*
|
||||
* This driver, which is contained in NetBSD in the files:
|
||||
*
|
||||
@ -150,6 +150,7 @@ static int isp_same_lportdb __P((struct lportdb *, struct lportdb *));
|
||||
static int isp_pdb_sync __P((struct ispsoftc *, int));
|
||||
#ifdef ISP2100_FABRIC
|
||||
static int isp_scan_fabric __P((struct ispsoftc *));
|
||||
static void isp_register_fc4_type __P((struct ispsoftc *));
|
||||
#endif
|
||||
static void isp_fw_state __P((struct ispsoftc *));
|
||||
static void isp_mboxcmd __P((struct ispsoftc *, mbreg_t *, int));
|
||||
@ -177,7 +178,7 @@ isp_reset(isp)
|
||||
{
|
||||
mbreg_t mbs;
|
||||
int loops, i, touched, dodnld = 1;
|
||||
char *revname;
|
||||
char *revname = "????";
|
||||
|
||||
isp->isp_state = ISP_NILSTATE;
|
||||
|
||||
@ -1413,19 +1414,12 @@ isp_fclink_test(isp, usdelay)
|
||||
lp->portid = BITS2WORD(pdb.pdb_portid_bits);
|
||||
lp->loopid = pdb.pdb_loopid;
|
||||
lp->loggedin = lp->valid = 1;
|
||||
#if 0
|
||||
if (isp->isp_rfabric == 0) {
|
||||
isp_i_register_fc4_type(isp);
|
||||
}
|
||||
#endif
|
||||
isp_register_fc4_type(isp);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fcp->isp_portid = mbs.param[2];
|
||||
fcp->isp_onfabric = 0;
|
||||
#if 0
|
||||
isp->isp_rfabric = 0;
|
||||
#endif
|
||||
fcp->portdb[FL_PORT_ID].valid = 0;
|
||||
}
|
||||
|
||||
@ -1482,7 +1476,7 @@ isp_pdb_sync(isp, target)
|
||||
struct lportdb *lp, *tport;
|
||||
fcparam *fcp = isp->isp_param;
|
||||
isp_pdb_t pdb;
|
||||
int loopid, prange, lim;
|
||||
int loopid, frange, prange, lim;
|
||||
|
||||
#ifdef ISP2100_FABRIC
|
||||
/*
|
||||
@ -1500,12 +1494,14 @@ isp_pdb_sync(isp, target)
|
||||
switch (fcp->isp_topo) {
|
||||
case TOPO_F_PORT:
|
||||
case TOPO_PTP_STUB:
|
||||
prange = 0;
|
||||
frange = prange = 0;
|
||||
break;
|
||||
case TOPO_N_PORT:
|
||||
frange = FC_SNS_ID+1;
|
||||
prange = 2;
|
||||
break;
|
||||
default:
|
||||
frange = FC_SNS_ID+1;
|
||||
prange = FL_PORT_ID;
|
||||
break;
|
||||
}
|
||||
@ -1740,7 +1736,7 @@ isp_pdb_sync(isp, target)
|
||||
/*
|
||||
* Tell the outside world we've arrived.
|
||||
*/
|
||||
(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &i);
|
||||
(void) isp_async(isp, ISPASYNC_LOGGED_INOUT, &i);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1755,7 +1751,7 @@ isp_pdb_sync(isp, target)
|
||||
* Tell the outside world we've gone away.
|
||||
*/
|
||||
loopid = lp - fcp->portdb;
|
||||
(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid);
|
||||
(void) isp_async(isp, ISPASYNC_LOGGED_INOUT, &loopid);
|
||||
MEMZERO((void *) lp, sizeof (*lp));
|
||||
}
|
||||
|
||||
@ -1763,27 +1759,39 @@ isp_pdb_sync(isp, target)
|
||||
/*
|
||||
* Now log in any fabric devices
|
||||
*/
|
||||
for (lp = &fcp->portdb[FC_SNS_ID+1];
|
||||
for (lp = &fcp->portdb[frange];
|
||||
lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
|
||||
u_int32_t portid;
|
||||
mbreg_t mbs;
|
||||
|
||||
loopid = lp - fcp->portdb;
|
||||
if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Anything here?
|
||||
*/
|
||||
if (lp->port_wwn == 0)
|
||||
if (lp->port_wwn == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't try to log into yourself.
|
||||
*/
|
||||
if ((portid = lp->portid) == fcp->isp_portid)
|
||||
if ((portid = lp->portid) == fcp->isp_portid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we'd been logged in- see if we still are and we haven't
|
||||
* changed. If so, no need to log ourselves out, etc..
|
||||
*
|
||||
* Unfortunately, our charming Qlogic f/w has decided to
|
||||
* return a valid port database entry for a fabric device
|
||||
* that has, in fact, gone away. And it hangs trying to
|
||||
* log it out.
|
||||
*/
|
||||
if (lp->loggedin &&
|
||||
isp_getpdb(isp, lp->loopid, &pdb) == 0) {
|
||||
@ -1944,7 +1952,7 @@ isp_pdb_sync(isp, target)
|
||||
if (lp->node_wwn && lp->port_wwn) {
|
||||
lp->valid = 1;
|
||||
loopid = lp - fcp->portdb;
|
||||
(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid);
|
||||
(void) isp_async(isp, ISPASYNC_LOGGED_INOUT, &loopid);
|
||||
continue;
|
||||
}
|
||||
dump_em:
|
||||
@ -2024,6 +2032,39 @@ isp_scan_fabric(isp)
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
isp_register_fc4_type(struct ispsoftc *isp)
|
||||
{
|
||||
fcparam *fcp = isp->isp_param;
|
||||
sns_screq_t *reqp;
|
||||
mbreg_t mbs;
|
||||
|
||||
reqp = (sns_screq_t *) fcp->isp_scratch;
|
||||
MEMZERO((void *) reqp, SNS_RFT_REQ_SIZE);
|
||||
reqp->snscb_rblen = SNS_RFT_RESP_SIZE >> 1;
|
||||
reqp->snscb_addr[RQRSP_ADDR0015] = DMA_LSW(fcp->isp_scdma + 0x100);
|
||||
reqp->snscb_addr[RQRSP_ADDR1631] = DMA_MSW(fcp->isp_scdma + 0x100);
|
||||
reqp->snscb_sblen = 22;
|
||||
reqp->snscb_data[0] = SNS_RFT;
|
||||
reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
|
||||
reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
|
||||
reqp->snscb_data[6] = 0x100; /* SCS - FCP */
|
||||
#if 0
|
||||
reqp->snscb_data[6] |= 20; /* ISO/IEC 8802-2 LLC/SNAP */
|
||||
#endif
|
||||
ISP_SWIZZLE_SNS_REQ(isp, reqp);
|
||||
mbs.param[0] = MBOX_SEND_SNS;
|
||||
mbs.param[1] = SNS_RFT_REQ_SIZE >> 1;
|
||||
mbs.param[2] = DMA_MSW(fcp->isp_scdma);
|
||||
mbs.param[3] = DMA_LSW(fcp->isp_scdma);
|
||||
mbs.param[6] = 0;
|
||||
mbs.param[7] = 0;
|
||||
isp_mboxcmd(isp, &mbs, MBLOGALL);
|
||||
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
|
||||
isp_prt(isp, ISP_LOGINFO, "Register FC4 types succeeded");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Start a command. Locking is assumed done in the caller.
|
||||
@ -2079,9 +2120,13 @@ isp_start(xs)
|
||||
#if defined(ISP2100_FABRIC)
|
||||
/*
|
||||
* If we're not on a Fabric, we can't have a target
|
||||
* above FL_PORT_ID-1. If we're on a fabric and
|
||||
* connected as an F-port, we can't have a target
|
||||
* less than FC_SNS_ID+1.
|
||||
* above FL_PORT_ID-1.
|
||||
*
|
||||
* If we're on a fabric and *not* connected as an F-port,
|
||||
* we can't have a target less than FC_SNS_ID+1. This
|
||||
* keeps us from having to sort out the difference between
|
||||
* local public loop devices and those which we might get
|
||||
* from a switch's database.
|
||||
*/
|
||||
if (fcp->isp_onfabric == 0) {
|
||||
if (target >= FL_PORT_ID) {
|
||||
@ -2093,7 +2138,7 @@ isp_start(xs)
|
||||
XS_SETERR(xs, HBA_SELTIMEOUT);
|
||||
return (CMD_COMPLETE);
|
||||
}
|
||||
if (fcp->isp_topo == TOPO_F_PORT &&
|
||||
if (fcp->isp_topo != TOPO_F_PORT &&
|
||||
target < FL_PORT_ID) {
|
||||
XS_SETERR(xs, HBA_SELTIMEOUT);
|
||||
return (CMD_COMPLETE);
|
||||
@ -2470,10 +2515,11 @@ isp_control(isp, ctl, arg)
|
||||
break;
|
||||
}
|
||||
isp_init(isp);
|
||||
if (isp->isp_state != ISP_INITSTATE) {
|
||||
break;
|
||||
if ((isp->isp_confopts & ISP_CFG_NOINIT) == 0) {
|
||||
if (isp->isp_state == ISP_INITSTATE) {
|
||||
isp->isp_state = ISP_RUNSTATE;
|
||||
}
|
||||
}
|
||||
isp->isp_state = ISP_RUNSTATE;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -3064,16 +3110,16 @@ isp_parse_async(isp, mbox)
|
||||
isp->isp_sendmarker = 1;
|
||||
FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
|
||||
isp_mark_getpdb_all(isp);
|
||||
isp_prt(isp, ISP_LOGINFO, "Port Database Changed");
|
||||
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, (void *) 0);
|
||||
break;
|
||||
|
||||
case ASYNC_CHANGE_NOTIFY:
|
||||
isp_mark_getpdb_all(isp);
|
||||
/*
|
||||
* Not correct, but it will force us to rescan the loop.
|
||||
*/
|
||||
FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
|
||||
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL);
|
||||
isp_mark_getpdb_all(isp);
|
||||
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, (void *) 1);
|
||||
break;
|
||||
|
||||
case ASYNC_PTPMODE:
|
||||
@ -4291,6 +4337,8 @@ isp_setdfltparm(isp, channel)
|
||||
|
||||
if (IS_FC(isp)) {
|
||||
fcparam *fcp = (fcparam *) isp->isp_param;
|
||||
int nvfail;
|
||||
|
||||
fcp += channel;
|
||||
if (fcp->isp_gotdparms) {
|
||||
return;
|
||||
@ -4322,19 +4370,40 @@ isp_setdfltparm(isp, channel)
|
||||
fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
|
||||
|
||||
/*
|
||||
* Now try and read NVRAM
|
||||
* Now try and read NVRAM unless told to not do so.
|
||||
* This will set fcparam's isp_nodewwn && isp_portwwn.
|
||||
*/
|
||||
if ((isp->isp_confopts & (ISP_CFG_NONVRAM|ISP_CFG_OWNWWN)) ||
|
||||
(isp_read_nvram(isp))) {
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"Node WWN 0x%08x%08x, Port WWN 0x%08x%08x",
|
||||
(u_int32_t) (fcp->isp_nodewwn >> 32),
|
||||
(u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
|
||||
(u_int32_t) (fcp->isp_portwwn >> 32),
|
||||
(u_int32_t) (fcp->isp_portwwn & 0xffffffff));
|
||||
if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
|
||||
nvfail = isp_read_nvram(isp);
|
||||
if (nvfail)
|
||||
isp->isp_confopts |= ISP_CFG_NONVRAM;
|
||||
} else {
|
||||
nvfail = 1;
|
||||
}
|
||||
/*
|
||||
* Set node && port to override platform set defaults
|
||||
* unless the nvram read failed (or none was done),
|
||||
* or the platform code wants to use what had been
|
||||
* set in the defaults.
|
||||
*/
|
||||
if (nvfail || (isp->isp_confopts & ISP_CFG_OWNWWN)) {
|
||||
isp_prt(isp, ISP_LOGCONFIG,
|
||||
"Using Node WWN 0x%08x%08x, Port WWN 0x%08x%08x",
|
||||
(u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
|
||||
(u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff),
|
||||
(u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
|
||||
(u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
|
||||
isp->isp_confopts |= ISP_CFG_OWNWWN;
|
||||
ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
|
||||
ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
|
||||
} else {
|
||||
/*
|
||||
* We always start out with values derived
|
||||
* from NVRAM or our platform default.
|
||||
*/
|
||||
ISP_NODEWWN(isp) = fcp->isp_nodewwn;
|
||||
ISP_PORTWWN(isp) = fcp->isp_portwwn;
|
||||
}
|
||||
fcp->isp_nodewwn = ISP_NODEWWN(isp);
|
||||
fcp->isp_portwwn = ISP_PORTWWN(isp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user