Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Update from Matthew Jacob:



details:   https://anonhg.NetBSD.org/src/rev/9d58eecbf87d
branches:  trunk
changeset: 486121:9d58eecbf87d
user:      he <he%NetBSD.org@localhost>
date:      Sat May 13 16:53:03 2000 +0000

description:
Update from Matthew Jacob:

  Correctly account for F-port vs. F-port (no FLOGI_ACC) topologies.
  Make sure we get a port database entry for the fabric name server.
  Preserve fabric logins if the device didn't change across fabric
  or port database changes, or the device has already logged into
  us (e.g., for target/initiator dual role devices like Veritas
  SANbox). Propagate class 3 service parameter changes where devices
  can change roles.

  Fix all occurrences of setting a sendmarker so that setting it
  for one bus on dual bus cards doesn't wipe a pending sendmarker
  for other busses on the same card :-;.

  Comments added and clarifications made in some of the target mode code.

diffstat:

 sys/dev/ic/isp.c         |  435 ++++++++++++++++++++++++++++++----------------
 sys/dev/ic/isp_netbsd.c  |    5 +-
 sys/dev/ic/isp_target.c  |   20 +-
 sys/dev/ic/isp_target.h  |   10 +-
 sys/dev/ic/isp_tpublic.h |   54 ++++-
 sys/dev/ic/ispmbox.h     |    4 +-
 sys/dev/ic/ispreg.h      |   15 +-
 sys/dev/ic/ispvar.h      |   23 +-
 8 files changed, 371 insertions(+), 195 deletions(-)

diffs (truncated from 1082 to 300 lines):

diff -r a0da113eb5a2 -r 9d58eecbf87d sys/dev/ic/isp.c
--- a/sys/dev/ic/isp.c  Sat May 13 15:27:17 2000 +0000
+++ b/sys/dev/ic/isp.c  Sat May 13 16:53:03 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: isp.c,v 1.51 2000/02/21 19:18:53 mjacob Exp $ */
+/* $NetBSD: isp.c,v 1.52 2000/05/13 16:53:03 he Exp $ */
 /*
  * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration
  * All rights reserved.
@@ -1025,7 +1025,7 @@
        /*
         * We have to use FULL LOGIN even though it resets the loop too much
         * because otherwise port database entries don't get updated after
-        * a LIP- this is a known f/w bug.
+        * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
         */
        if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) {
                fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
@@ -1079,26 +1079,8 @@
        icbp->icb_logintime = 60;       /* 60 second login timeout */
 
        if (fcp->isp_nodewwn) {
-               u_int64_t pn;
                MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_nodewwn);
-               if (fcp->isp_portwwn) {
-                       pn = fcp->isp_portwwn;
-               } else {
-                       pn = fcp->isp_nodewwn |
-                           (((u_int64_t)(isp->isp_unit+1)) << 56);
-               }
-               /*
-                * If the top nibble is 2, we can construct a port name
-                * from the node name by setting a nonzero instance in
-                * bits 56..59. Otherwise, we need to make it identical
-                * to Node name...
-                */
-               if ((fcp->isp_nodewwn >> 60) == 2) {
-                       MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pn);
-               } else {
-                       MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname,
-                           fcp->isp_nodewwn);
-               }
+               MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_portwwn);
        } else {
                fcp->isp_fwoptions &= ~(ICBOPT_USE_PORTNAME|ICBOPT_FULL_LOGIN);
        }
@@ -1253,10 +1235,11 @@
                "Private Loop",
                "FL Port",
                "N-Port to N-Port",
-               "F Port"
+               "F Port",
+               "F Port (no FLOGI_ACC response)"
        };
        mbreg_t mbs;
-       int count, topo = -1;
+       int count;
        u_int8_t lwfs;
        fcparam *fcp;
 #if    defined(ISP2100_FABRIC)
@@ -1300,53 +1283,74 @@
        }
        fcp->isp_loopid = mbs.param[1];
        if (IS_2200(isp)) {
-               topo = (int) mbs.param[6];
-               if (topo < 0 || topo > 3)
-                       topo = 0;
+               int topo = (int) mbs.param[6];
+               if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
+                       topo = TOPO_PTP_STUB;
+               fcp->isp_topo = topo;
        } else {
-               topo = 0;
+               fcp->isp_topo = TOPO_NL_PORT;
        }
-
-       /*
-        * If we're not on a fabric, the low 8 bits will be our AL_PA.
-        * If we're on a fabric, the low 8 bits will still be our AL_PA.
-        */
        fcp->isp_alpa = mbs.param[2];
+
 #if    defined(ISP2100_FABRIC)
        fcp->isp_onfabric = 0;
-       if (isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
-
-               if (IS_2100(isp))
-                       topo = 1;
-
+       if (fcp->isp_topo != TOPO_N_PORT &&
+           isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
+               struct lportdb *lp;
+               if (IS_2100(isp)) {
+                       fcp->isp_topo = TOPO_FL_PORT;
+               }
                fcp->isp_portid = mbs.param[2] | (((int)mbs.param[3]) << 16);
                fcp->isp_onfabric = 1;
-               CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State "
-                   "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
-                   fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
-                   toponames[topo]);
 
                /*
-                * Make sure we're logged out of all fabric devices.
+                * Save the Fabric controller's port database entry.
                 */
-               for (count = FC_SNS_ID+1; count < MAX_FC_TARG; count++) {
-                       struct lportdb *lp = &fcp->portdb[count];
-                       if (lp->valid == 0 || lp->fabdev == 0)
-                               continue;
-                       PRINTF("%s: logging out target %d at Loop ID %d "
-                           "(port id 0x%x)\n", isp->isp_name, count,
-                           lp->loopid, lp->portid);
-                       mbs.param[0] = MBOX_FABRIC_LOGOUT;
-                       mbs.param[1] = lp->loopid << 8;
-                       mbs.param[2] = 0;
-                       mbs.param[3] = 0;
-                       isp_mboxcmd(isp, &mbs);
+               lp = &fcp->portdb[FL_PORT_ID];
+               lp->node_wwn =
+                   (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
+                   (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
+                   (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
+                   (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
+                   (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
+                   (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
+                   (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
+                   (((u_int64_t)pdb.pdb_nodename[7]));
+               lp->port_wwn =
+                   (((u_int64_t)pdb.pdb_portname[0]) << 56) |
+                   (((u_int64_t)pdb.pdb_portname[1]) << 48) |
+                   (((u_int64_t)pdb.pdb_portname[2]) << 40) |
+                   (((u_int64_t)pdb.pdb_portname[3]) << 32) |
+                   (((u_int64_t)pdb.pdb_portname[4]) << 24) |
+                   (((u_int64_t)pdb.pdb_portname[5]) << 16) |
+                   (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
+                   (((u_int64_t)pdb.pdb_portname[7]));
+               lp->roles =
+                   (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
+               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
        } else
 #endif
-       CFGPRINTF("%s: Loop ID %d, ALPA 0x%x Loop State 0x%x topology '%s'\n",
-           isp->isp_name, fcp->isp_loopid, fcp->isp_alpa, fcp->isp_loopstate,
-           toponames[topo]);
+       {
+               fcp->isp_portid = mbs.param[2];
+               fcp->isp_onfabric = 0;
+#if    0
+               isp->isp_rfabric = 0;
+#endif
+               fcp->portdb[FL_PORT_ID].valid = 0;
+       }
+
+       CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State "
+           "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
+           fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
+           toponames[fcp->isp_topo]);
+
        return (0);
 }
 
@@ -1364,7 +1368,7 @@
         */
 
        if (a->port_wwn == 0 || a->port_wwn != b->port_wwn ||
-           a->loopid != b->loopid) {
+           a->loopid != b->loopid || a->roles != b->roles) {
                return (0);
        } else {
                return (1);
@@ -1384,7 +1388,7 @@
        struct lportdb *lp, *tport;
        fcparam *fcp = isp->isp_param;
        isp_pdb_t pdb;
-       int loopid, lim;
+       int loopid, prange, lim;
 
 #ifdef ISP2100_FABRIC
        /*
@@ -1399,6 +1403,19 @@
 #endif
 
 
+       switch (fcp->isp_topo) {
+       case TOPO_F_PORT:
+       case TOPO_PTP_STUB:
+               prange = 0;
+               break;
+       case TOPO_N_PORT:
+               prange = 2;
+               break;
+       default:
+               prange = FL_PORT_ID;
+               break;
+       }
+
        /*
         * Run through the local loop ports and get port database info
         * for each loop ID.
@@ -1413,12 +1430,17 @@
         * make sure the temp port database is clean...
         */
        MEMZERO((void *) tport, sizeof (tport));
-       for (lim = loopid = 0; loopid < FL_PORT_ID; loopid++) {
+
+       for (lim = loopid = 0; loopid < prange; loopid++) {
                lp = &tport[loopid];
                lp->node_wwn = isp_get_portname(isp, loopid, 1);
+               if (fcp->isp_loopstate != LOOP_PDB_RCVD)
+                       return (-1);
                if (lp->node_wwn == 0)
                        continue;
                lp->port_wwn = isp_get_portname(isp, loopid, 0);
+               if (fcp->isp_loopstate != LOOP_PDB_RCVD)
+                       return (-1);
                if (lp->port_wwn == 0) {
                        lp->node_wwn = 0;
                        continue;
@@ -1428,9 +1450,14 @@
                 * Get an entry....
                 */
                if (isp_getpdb(isp, loopid, &pdb) != 0) {
+                       if (fcp->isp_loopstate != LOOP_PDB_RCVD)
+                               return (-1);
                        continue;
                }
 
+               if (fcp->isp_loopstate != LOOP_PDB_RCVD)
+                       return (-1);
+
                /*
                 * If the returned database element doesn't match what we
                 * asked for, restart the process entirely (up to a point...).
@@ -1503,7 +1530,7 @@
         * Now merge our local copy of the port database into our saved copy.
         * Notify the outer layers of new devices arriving.
         */
-       for (loopid = 0; loopid < FL_PORT_ID; loopid++) {
+       for (loopid = 0; loopid < prange; loopid++) {
                int i;
 
                /*
@@ -1556,10 +1583,7 @@
                        fcp->portdb[i].portid = tport[loopid].portid;
                        fcp->portdb[i].loopid = loopid;
                        fcp->portdb[i].valid = 1;
-                       /*
-                        * XXX: Should we also propagate roles in case they
-                        * XXX: changed?
-                        */
+                       fcp->portdb[i].roles = tport[loopid].roles;
 
                        /*
                         * Now make sure this Port WWN doesn't exist elsewhere
@@ -1634,7 +1658,7 @@
         * Now find all previously used targets that are now invalid and
         * notify the outer layers that they're gone.
         */
-       for (lp = fcp->portdb; lp < &fcp->portdb[FL_PORT_ID]; lp++) {
+       for (lp = fcp->portdb; lp < &fcp->portdb[prange]; lp++) {
                if (lp->valid || lp->port_wwn == 0)
                        continue;
 
@@ -1650,13 +1674,13 @@
        /*
         * Now log in any fabric devices
         */
-       for (lim = FC_SNS_ID+1, lp = &fcp->portdb[FC_SNS_ID+1];
+       for (lp = &fcp->portdb[FC_SNS_ID+1];
             lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
                u_int32_t portid;
                mbreg_t mbs;
 
                /*
-                * Nothing here?
+                * Anything here?
                 */
                if (lp->port_wwn == 0)
                        continue;
@@ -1667,16 +1691,61 @@
                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..
+                */
+               if (lp->loggedin &&
+                   isp_getpdb(isp, lp->loopid, &pdb) == 0) {
+                       int nrole;
+                       u_int64_t nwwnn, nwwpn;



Home | Main Index | Thread Index | Old Index