Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Minor stuff:



details:   https://anonhg.NetBSD.org/src/rev/baa5b92ae07d
branches:  trunk
changeset: 503753:baa5b92ae07d
user:      mjacob <mjacob%NetBSD.org@localhost>
date:      Mon Feb 12 23:28:50 2001 +0000

description:
Minor stuff:
Remove ISP2100_FABRIC defines- we always handle fabric now. Insert
isp_getmap helper function (for getting Loop Position map). Make
sure we (for our own benefit) mark req_state_flags with RQSF_GOT_SENSE
for Fibre Channel if we got sense data- the !*$)!*$)~*$)*$ Qlogic
f/w doesn't do so. Add ISPCTL_SCAN_FABRIC, ISPCTL_SCAN_LOOP, ISPCTL_SEND_LIP,
and ISPCTL_GET_POSMAP isp_control functions. Correctly send async notifications
upstream for changes in the name server, changes in the port database, and
f/w crashes. Correctly set topology when we get a ASYNC_PTPMODE event.

When resetting the Qlogic 2X00 units, reset the FPM (Fibre Protocol
Module) and FBM (Fibre Buffer Modules). Also remember to clear the
semaphore registers. Tell the RISC processor to not halt on FPM
parity errors.


Finally, use a new tag in the softc to store the opcode for the
last mailbox command used so we can report which opcode timed
out.

Major stuff:
Quite massively redo how we handle Loop events- we've now added several
intermediate states between LOOP_PDB_RCVD and LOOP_READY. This allows us
a lot finer control about how we scan fabric, whether we go further
than scanning fabric, how we look at the local loop, and whether we
merge entries at the level or not. This is the next to last step for
moving managing loop state out of the core module entirely (whereupon
loop && fabric events will simply freeze the command queue and a thread
will run to figure out what's changed and *it* will re-enable the queu).
This fine amount of control also gets us closer to having an external
policy engine decide which fabric devices we really want to log into.

Throw out the ISP_CFG_NOINIT silliness and instead go to the use of
adapter 'roles' to see whether one completes initialization or not
(mostly for Fibre Channel). The ultimate intent, btw, of all of this
is to have a warm standby adapter for failover reasons.  Because
we do roles now, setting of Target Capable Class 3 service parameters
in the ICB for the 2x00 cards reflects from role. Also, in isp_start,
if we're not supporting an initiator role, we bounce outgoing commands
with a Selection Timeout error. Also clean out the TOGGLE_TMODE
goop for FC- there is no toggling of target mode like there is
for parallel SCSI cards.

Do more cleanup with respect to using target ids 0..125 in F-port
topologies. Also keep track of things which *were* fabric devices
so that when you rescan the fabric you can notify the outer layers
when fabric devices go away.

Only force a LOGOUT for fabric devices if they're still logged in
(i.e., you cat their Port Database entry. Clean up the Get All Next
scanning.

diffstat:

 sys/dev/ic/isp.c |  1147 +++++++++++++++++++++++++++++++++--------------------
 1 files changed, 715 insertions(+), 432 deletions(-)

diffs (truncated from 1640 to 300 lines):

diff -r fe6763560071 -r baa5b92ae07d sys/dev/ic/isp.c
--- a/sys/dev/ic/isp.c  Mon Feb 12 23:25:20 2001 +0000
+++ b/sys/dev/ic/isp.c  Mon Feb 12 23:28:50 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: isp.c,v 1.69 2001/01/09 18:54:06 mjacob Exp $ */
+/* $NetBSD: isp.c,v 1.70 2001/02/12 23:28:50 mjacob Exp $ */
 /*
  * This driver, which is contained in NetBSD in the files:
  *
@@ -56,6 +56,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 /*
  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
@@ -99,7 +100,6 @@
     "Target %d duplicates Target %d- killing off both";
 static const char retained[] = 
     "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
-#ifdef ISP2100_FABRIC
 static const char lretained[] =
     "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
 static const char plogout[] =
@@ -114,7 +114,6 @@
     "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
 static const char ldumped[] =
     "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
-#endif
 static const char notresp[] =
   "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
 static const char xact1[] =
@@ -128,7 +127,7 @@
 static const char topology[] =
     "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
 static const char finmsg[] =
-    "(%d.%d.%d): FIN dl%d resid%d STS 0x%x SKEY %c XS_ERR=0x%x";
+    "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
 /*
  * Local function prototypes.
  */
@@ -142,16 +141,15 @@
 static void isp_scsi_channel_init __P((struct ispsoftc *, int));
 static void isp_fibre_init __P((struct ispsoftc *));
 static void isp_mark_getpdb_all __P((struct ispsoftc *));
+static int isp_getmap __P((struct ispsoftc *, fcpos_map_t *));
 static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *));
 static u_int64_t isp_get_portname __P((struct ispsoftc *, int, int));
 static int isp_fclink_test __P((struct ispsoftc *, int));
 static char *isp2100_fw_statename __P((int));
-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_pdb_sync __P((struct ispsoftc *));
+static int isp_scan_loop __P((struct ispsoftc *));
 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));
 
@@ -230,7 +228,8 @@
        DISABLE_INTS(isp);
 
        /*
-        * Put the board into PAUSE mode (so we can read the SXP registers).
+        * Put the board into PAUSE mode (so we can read the SXP registers
+        * or write FPM/FBM registers).
         */
        ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
 
@@ -245,6 +244,14 @@
                default:
                        break;
                }
+               /*
+                * While we're paused, reset the FPM module and FBM fifos.
+                */
+               ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
+               ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
+               ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
+               ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
+               ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
        } else if (IS_1240(isp)) {
                sdparam *sdp = isp->isp_param;
                revname = "1240";
@@ -488,6 +495,8 @@
         */
        ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
        USEC_DELAY(100);
+       /* Clear semaphore register (just to be sure) */
+       ISP_WRITE(isp, BIU_SEMA, 0);
 
        /*
         * Establish some initial burst rate stuff.
@@ -525,6 +534,9 @@
 #endif
        } else {
                ISP_WRITE(isp, RISC_MTR2100, 0x1212);
+               if (IS_2200(isp)) {
+                       ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
+               }
        }
 
        ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
@@ -756,12 +768,10 @@
        if (IS_DUALBUS(isp)) {
                isp_setdfltparm(isp, 1);
        }
-       if ((isp->isp_confopts & ISP_CFG_NOINIT) == 0) {
-               if (IS_FC(isp)) {
-                       isp_fibre_init(isp);
-               } else {
-                       isp_scsi_init(isp);
-               }
+       if (IS_FC(isp)) {
+               isp_fibre_init(isp);
+       } else {
+               isp_scsi_init(isp);
        }
 }
 
@@ -778,6 +788,13 @@
                sdp_chan1++;
        }
 
+       /*
+        * If we have no role (neither target nor initiator), return.
+        */
+       if (isp->isp_role == ISP_ROLE_NONE) {
+               return;
+       }
+
        /* First do overall per-card settings. */
 
        /*
@@ -1039,6 +1056,20 @@
 
        fcp = isp->isp_param;
 
+       /*
+        * Do this *before* initializing the firmware.
+        */
+       isp_mark_getpdb_all(isp);
+       fcp->isp_fwstate = FW_CONFIG_WAIT;
+       fcp->isp_loopstate = LOOP_NIL;
+
+       /*
+        * If we have no role (neither target nor initiator), return.
+        */
+       if (isp->isp_role == ISP_ROLE_NONE) {
+               return;
+       }
+
        loopid = DEFAULT_LOOPID(isp);
        icbp = (isp_icb_t *) fcp->isp_scratch;
        MEMZERO(icbp, sizeof (*icbp));
@@ -1078,6 +1109,19 @@
         * Node Name && Port Names to be distinct.
         */
 
+       
+       /*
+        * Make sure that target role reflects into fwoptions.
+        */
+       if (isp->isp_role & ISP_ROLE_TARGET) {
+               fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
+       } else {
+               fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
+       }
+
+       /*
+        * Propagate all of this into the ICB structure.
+        */
        icbp->icb_fwoptions = fcp->isp_fwoptions;
        icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
        if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
@@ -1154,13 +1198,10 @@
            "isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions);
        ISP_SWIZZLE_ICB(isp, icbp);
 
+
        /*
-        * Do this *before* initializing the firmware.
+        * Init the firmware
         */
-       isp_mark_getpdb_all(isp);
-       fcp->isp_fwstate = FW_CONFIG_WAIT;
-       fcp->isp_loopstate = LOOP_NIL;
-
        mbs.param[0] = MBOX_INIT_FIRMWARE;
        mbs.param[1] = 0;
        mbs.param[2] = DMA_MSW(fcp->isp_scdma);
@@ -1190,6 +1231,36 @@
  * else failure.
  */
 
+static int
+isp_getmap(isp, map)
+       struct ispsoftc *isp;
+       fcpos_map_t *map;
+{
+       fcparam *fcp = (fcparam *) isp->isp_param;
+       mbreg_t mbs;
+
+       mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
+       mbs.param[1] = 0;
+       mbs.param[2] = DMA_MSW(fcp->isp_scdma);
+       mbs.param[3] = DMA_LSW(fcp->isp_scdma);
+       /*
+        * Unneeded. For the 2100, except for initializing f/w, registers
+        * 4/5 have to not be written to.
+        *      mbs.param[4] = 0;
+        *      mbs.param[5] = 0;
+        *
+        */
+       mbs.param[6] = 0;
+       mbs.param[7] = 0;
+       isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
+       if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
+               MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
+               map->fwmap = mbs.param[1] != 0;
+               return (0);
+       }
+       return (-1);
+}
+
 static void
 isp_mark_getpdb_all(isp)
        struct ispsoftc *isp;
@@ -1197,7 +1268,7 @@
        fcparam *fcp = (fcparam *) isp->isp_param;
        int i;
        for (i = 0; i < MAX_FC_TARG; i++) {
-               fcp->portdb[i].valid = 0;
+               fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
        }
 }
 
@@ -1276,12 +1347,12 @@
                "F Port (no FLOGI_ACC response)"
        };
        mbreg_t mbs;
-       int count;
+       int count, check_for_fabric;
        u_int8_t lwfs;
        fcparam *fcp;
-#if    defined(ISP2100_FABRIC)
+       struct lportdb *lp;
        isp_pdb_t pdb;
-#endif
+
        fcp = isp->isp_param;
 
        /*
@@ -1374,23 +1445,42 @@
        } else {
                fcp->isp_topo = TOPO_NL_PORT;
        }
-       fcp->isp_alpa = mbs.param[2];
-
-#if    defined(ISP2100_FABRIC)
+       fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
+
+       /*
+        * Check to see if we're on a fabric by trying to see if we
+        * can talk to the fabric name server. This can be a bit
+        * tricky because if we're a 2100, we should check always
+        * (in case we're connected to an server doing aliasing).
+        */
        fcp->isp_onfabric = 0;
-       if (fcp->isp_topo != TOPO_N_PORT &&
-           isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
-               struct lportdb *lp;
+
+       if (IS_2100(isp))
+               check_for_fabric = 1;
+       else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT)
+               check_for_fabric = 1;
+       else
+               check_for_fabric = 0;
+
+       if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
+               int loopid = FL_PORT_ID;
                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;
+
+               if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
+                       /*
+                        * Crock.
+                        */
+                       fcp->isp_topo = TOPO_NL_PORT;
+                       goto not_on_fabric;
+               }
+               fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
 



Home | Main Index | Thread Index | Old Index