Source-Changes-HG archive

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

[src/netbsd-1-4]: src/sys/dev Apply patch (requested by Matthew Jacob via he):



details:   https://anonhg.NetBSD.org/src/rev/5ae20942ee7d
branches:  netbsd-1-4
changeset: 470601:5ae20942ee7d
user:      he <he%NetBSD.org@localhost>
date:      Sat May 13 17:05:50 2000 +0000

description:
Apply patch (requested by Matthew Jacob via he):
  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.

  Add support for > 12 byte CDBs.  Split out nvram reading into
  per-card functions.  Add proper Ultra2/Ultra3 support.  Upgrade
  firmware.

diffstat:

 sys/dev/ic/isp.c                |  1544 +++++++++-----
 sys/dev/ic/isp_inline.h         |    23 +-
 sys/dev/ic/isp_netbsd.c         |     5 +-
 sys/dev/ic/isp_netbsd.h         |     4 +-
 sys/dev/ic/ispmbox.h            |    50 +-
 sys/dev/ic/ispreg.h             |    93 +-
 sys/dev/ic/ispvar.h             |    43 +-
 sys/dev/microcode/isp/asm_pci.h |  4039 ++++++++++++++++++++++++++++++++++++++-
 sys/dev/pci/isp_pci.c           |    10 +-
 9 files changed, 5196 insertions(+), 615 deletions(-)

diffs (truncated from 6565 to 300 lines):

diff -r 8e5b8a901abf -r 5ae20942ee7d sys/dev/ic/isp.c
--- a/sys/dev/ic/isp.c  Sat May 13 15:33:33 2000 +0000
+++ b/sys/dev/ic/isp.c  Sat May 13 17:05:50 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: isp.c,v 1.34.2.1 2000/01/08 22:42:37 he Exp $ */
+/* $NetBSD: isp.c,v 1.34.2.2 2000/05/13 17:14:01 he Exp $ */
 /*
  * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration
  * All rights reserved.
@@ -95,6 +95,11 @@
 static void isp_setdfltparm __P((struct ispsoftc *, int));
 static int isp_read_nvram __P((struct ispsoftc *));
 static void isp_rdnvram_word __P((struct ispsoftc *, int, u_int16_t *));
+static void isp_parse_nvram_1020 __P((struct ispsoftc *, u_int8_t *));
+static void isp_parse_nvram_1080 __P((struct ispsoftc *, int, u_int8_t *));
+static void isp_parse_nvram_12160 __P((struct ispsoftc *, int, u_int8_t *));
+static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *));
+
 
 /*
  * Reset Hardware.
@@ -188,7 +193,15 @@
 
                isp->isp_clock = 100;
 
-               revname = "1080";
+               if (IS_1280(isp))
+                       revname = "1280";
+               else if (IS_1080(isp))
+                       revname = "1080";
+               else if (IS_12160(isp))
+                       revname = "12160";
+               else
+                       revname = "<UNKLVD>";
+
                l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
                switch (l) {
                case ISP1080_LVD_MODE:
@@ -209,9 +222,8 @@
                        break;
                }
 
-               if (IS_1280(isp)) {
+               if (IS_DUALBUS(isp)) {
                        sdp++;
-                       revname[1] = '2';
                        l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
                        l &= ISP1080_MODE_MASK;
                        switch(l) {
@@ -793,22 +805,16 @@
         *
         * Ultra2 F/W always has had fast posting (and LVD transitions)
         *
-        * Ultra and older (i.e., SBus) cards may not. Assume SBus cards
-        * do not, and only guess that 4.55.0 <= x < 5.0.0 (initiator
-        * only) and x >= 7.55 (initiator/target) has fast posting.
+        * Ultra and older (i.e., SBus) cards may not. It's just safer
+        * to assume not for them.
         */
 
        mbs.param[0] = MBOX_SET_FW_FEATURES;
        mbs.param[1] = 0;
        if (IS_ULTRA2(isp))
                mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
-#ifndef        ISP_NO_FASTPOST_SCSI
-       if ((ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(4, 55, 0) &&
-           (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(5, 0, 0))) ||
-           (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(7, 55, 0))) {
+       if (IS_ULTRA2(isp) || IS_1240(isp))
                mbs.param[1] |= FW_FEATURE_FAST_POST;
-       }
-#endif
        if (mbs.param[1] != 0) {
                u_int16_t sfeat = mbs.param[1];
                isp_mboxcmd(isp, &mbs);
@@ -1019,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;
@@ -1058,29 +1064,23 @@
        icbp->icb_retry_delay = fcp->isp_retry_delay;
        icbp->icb_retry_count = fcp->isp_retry_count;
        icbp->icb_hardaddr = loopid;
+#ifdef PRET_A_PORTE
+       if (IS_2200(isp)) {
+               icbp->icb_fwoptions |= ICBOPT_EXTENDED;
+               /*
+                * Prefer or force Point-To-Point instead Loop?
+                */
+               if (isp->isp_confopts & ISP_CFG_NPORT)
+                       icbp->icb_xfwoptions = ICBXOPT_PTP_2_LOOP;
+               else
+                       icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP;
+       }
+#endif
        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);
        }
@@ -1235,11 +1235,11 @@
                "Private Loop",
                "FL Port",
                "N-Port to N-Port",
-               "F Port"
+               "F Port",
+               "F Port (no FLOGI_ACC response)"
        };
-       char *tname;
        mbreg_t mbs;
-       int count, topo = -1;
+       int count;
        u_int8_t lwfs;
        fcparam *fcp;
 #if    defined(ISP2100_FABRIC)
@@ -1282,55 +1282,75 @@
                return (-1);
        }
        fcp->isp_loopid = mbs.param[1];
-       if (isp->isp_type == ISP_HA_FC_2200) {
-               if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(2, 0, 14)) {
-                       topo = (int) mbs.param[6];
-               }
-       } else if (isp->isp_type == ISP_HA_FC_2100) {
-               if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(1, 17, 26)) {
-                       topo = (int) mbs.param[6];
-               }
+       if (IS_2200(isp)) {
+               int topo = (int) mbs.param[6];
+               if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
+                       topo = TOPO_PTP_STUB;
+               fcp->isp_topo = topo;
+       } else {
+               fcp->isp_topo = TOPO_NL_PORT;
        }
-       if (topo < 0 || topo > 3)
-               tname = "unknown";
-       else
-               tname = toponames[topo];
-
-       /*
-        * 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 (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, tname);
 
                /*
-                * 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,
-           tname);
+       {
+               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);
 }
 
@@ -1348,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);
@@ -1368,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
        /*
@@ -1383,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.
@@ -1397,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++) {



Home | Main Index | Thread Index | Old Index