Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Use a SNS REGISTER FC4 TYPE subcommand to registe...



details:   https://anonhg.NetBSD.org/src/rev/a0df6090703b
branches:  trunk
changeset: 501946:a0df6090703b
user:      mjacob <mjacob%NetBSD.org@localhost>
date:      Tue Jan 09 18:54:06 2001 +0000

description:
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.

diffstat:

 sys/dev/ic/isp.c |  147 ++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 108 insertions(+), 39 deletions(-)

diffs (truncated from 304 to 300 lines):

diff -r bc6816fa4d76 -r a0df6090703b sys/dev/ic/isp.c
--- a/sys/dev/ic/isp.c  Tue Jan 09 18:41:53 2001 +0000
+++ b/sys/dev/ic/isp.c  Tue Jan 09 18:54:06 2001 +0000
@@ -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_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 @@
 {
        mbreg_t mbs;
        int loops, i, touched, dodnld = 1;
-       char *revname;
+       char *revname = "????";
 
        isp->isp_state = ISP_NILSTATE;
 
@@ -1413,19 +1414,12 @@
                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 @@
        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 @@
        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 @@
                /*
                 * 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 @@
                 * 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 @@
        /*
         * 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 @@
                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 @@
         */
        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 @@
 #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 @@
                                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 @@
                                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->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 @@
 
        if (IS_FC(isp)) {
                fcparam *fcp = (fcparam *) isp->isp_param;
+               int nvfail;
+
                fcp += channel;
                if (fcp->isp_gotdparms) {
                        return;
@@ -4322,19 +4370,40 @@
                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) == 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 ((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 (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);



Home | Main Index | Thread Index | Old Index