Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Implement REDUCED INTERRUPT OPERATION usage for F...



details:   https://anonhg.NetBSD.org/src/rev/45753638d83d
branches:  trunk
changeset: 520151:45753638d83d
user:      mjacob <mjacob%NetBSD.org@localhost>
date:      Thu Jan 03 21:45:06 2002 +0000

description:
Implement REDUCED INTERRUPT OPERATION usage for FC cards- this allows the
firmware to delay completion of commands so that it can attempt to batch
a bunch of completions at once- either returning 16 bit handles in mailbox
registers, or in a resposne queue entry that has a whole wad of 16 bit handles.

Distinguish between 2300 and 2312 chipsets- if only because the revisions
on the chips have different meanings.

Add more instrumentation plus ISP_GET_STATS and ISP_CLR_STATS ioctls.
Run up the maximum number of response queue entities we'll look at
per interrupt.

If we haven't set HBA role yet, always return success from isp_fc_runstate.

diffstat:

 sys/dev/ic/isp.c        |  121 +++++++++++++++++++++++++++++++++++------------
 sys/dev/ic/isp_inline.h |   22 +++++++-
 sys/dev/ic/isp_ioctl.h  |   31 +++++++++++-
 sys/dev/ic/ispmbox.h    |    8 +-
 sys/dev/ic/ispvar.h     |   13 ++++-
 5 files changed, 155 insertions(+), 40 deletions(-)

diffs (truncated from 479 to 300 lines):

diff -r 0f676fa8a0c3 -r 45753638d83d sys/dev/ic/isp.c
--- a/sys/dev/ic/isp.c  Thu Jan 03 19:11:17 2002 +0000
+++ b/sys/dev/ic/isp.c  Thu Jan 03 21:45:06 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: isp.c,v 1.86 2001/12/14 00:13:44 mjacob Exp $ */
+/* $NetBSD: isp.c,v 1.87 2002/01/03 21:45:06 mjacob Exp $ */
 /*
  * This driver, which is contained in NetBSD in the files:
  *
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: isp.c,v 1.86 2001/12/14 00:13:44 mjacob Exp $");
+__KERNEL_RCSID(0, "$NetBSD: isp.c,v 1.87 2002/01/03 21:45:06 mjacob Exp $");
 
 #ifdef __NetBSD__
 #include <dev/ic/isp_netbsd.h>
@@ -140,7 +140,7 @@
 /*
  * Local function prototypes.
  */
-static int isp_parse_async(struct ispsoftc *, int);
+static int isp_parse_async(struct ispsoftc *, u_int16_t);
 static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
     u_int16_t *);
 static void
@@ -244,7 +244,7 @@
         * Set up default request/response queue in-pointer/out-pointer
         * register indices.
         */
-       if (IS_2300(isp)) {
+       if (IS_23XX(isp)) {
                isp->isp_rqstinrp = BIU_REQINP;
                isp->isp_rqstoutrp = BIU_REQOUTP;
                isp->isp_respinrp = BIU_RSPINP;
@@ -271,6 +271,7 @@
                        btype = "2200";
                        break;
                case ISP_HA_FC_2300:
+               case ISP_HA_FC_2312:
                        btype = "2300";
                        break;
                default:
@@ -566,7 +567,7 @@
 #endif
        } else {
                ISP_WRITE(isp, RISC_MTR2100, 0x1212);
-               if (IS_2200(isp) || IS_2300(isp)) {
+               if (IS_2200(isp) || IS_23XX(isp)) {
                        ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
                }
        }
@@ -584,7 +585,7 @@
         * Avoid doing this on the 2312 because you can generate a PCI
         * parity error (chip breakage).
         */
-       if (IS_2300(isp)) {
+       if (IS_23XX(isp)) {
                USEC_DELAY(5);
        } else {
                loops = MBOX_DELAY_COUNT;
@@ -650,7 +651,7 @@
                dodnld = 0;
        }
 
-       if (IS_2300(isp))
+       if (IS_23XX(isp))
                code_org = ISP_CODE_ORG_2300;
        else
                code_org = ISP_CODE_ORG;
@@ -1235,7 +1236,7 @@
         * 
         * NB: for the 2300, ICBOPT_EXTENDED is required.
         */
-       if (IS_2200(isp) || IS_2300(isp)) {
+       if (IS_2200(isp) || IS_23XX(isp)) {
                icbp->icb_fwoptions |= ICBOPT_EXTENDED;
                /*
                 * Prefer or force Point-To-Point instead Loop?
@@ -1254,8 +1255,8 @@
                        icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
                        break;
                }
-               if (IS_2300(isp)) {
-                       if (isp->isp_revision < 2) {
+               if (IS_23XX(isp)) {
+                       if (!IS_2312(isp) && isp->isp_revision < 2) {
                                icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
                        }
                        if (isp->isp_confopts & ISP_CFG_ONEGB) {
@@ -1266,10 +1267,13 @@
                                icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
                        }
                }
+               icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
+               icbp->icb_racctimer = 4;
+               icbp->icb_idelaytimer = 8;
        }
 
        if ((IS_2200(isp) && ISP_FW_REVX(isp->isp_fwrev) >=
-           ISP_FW_REV(2, 1, 26)) || IS_2300(isp)) {
+           ISP_FW_REV(2, 1, 26)) || IS_23XX(isp)) {
                /*
                 * Turn on LIP F8 async event (1)
                 * Turn on generate AE 8013 on all LIP Resets (2)
@@ -1283,7 +1287,7 @@
        }
        icbp->icb_logintime = 30;       /* 30 second login timeout */
 
-       if (IS_2300(isp)) {
+       if (IS_23XX(isp)) {
                ISP_WRITE(isp, isp->isp_rqstinrp, 0);
                ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
                ISP_WRITE(isp, isp->isp_respinrp, 0);
@@ -1548,7 +1552,7 @@
                return (-1);
        }
        fcp->isp_loopid = mbs.param[1];
-       if (IS_2200(isp) || IS_2300(isp)) {
+       if (IS_2200(isp) || IS_23XX(isp)) {
                int topo = (int) mbs.param[6];
                if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
                        topo = TOPO_PTP_STUB;
@@ -1625,7 +1629,7 @@
        }
 
        fcp->isp_gbspeed = 1;
-       if (IS_2300(isp)) {
+       if (IS_23XX(isp)) {
                mbs.param[0] = MBOX_GET_SET_DATA_RATE;
                mbs.param[1] = MBGSD_GET_RATE;
                /* mbs.param[2] undefined if we're just getting rate */
@@ -1880,7 +1884,7 @@
                        mbs.param[1] = loopid << 8;
                        mbs.param[2] = portid >> 16;
                        mbs.param[3] = portid & 0xffff;
-                       if (IS_2200(isp) || IS_2300(isp)) {
+                       if (IS_2200(isp) || IS_23XX(isp)) {
                                /* only issue a PLOGI if not logged in */
                                mbs.param[1] |= 0x1;
                        }
@@ -3010,7 +3014,7 @@
  * Limit our stack depth by sticking with the max likely number
  * of completions on a request queue at any one time.
  */
-#define        MAX_REQUESTQ_COMPLETIONS        32
+#define        MAX_REQUESTQ_COMPLETIONS        64
 
 void
 isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
@@ -3041,12 +3045,9 @@
                                    "Mbox Command Async (0x%x) with no waiters",
                                    mbox);
                        }
-               } else {
-                       int fhandle = isp_parse_async(isp, (int) mbox);
-                       isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
-                       if (fhandle > 0) {
-                               isp_fastpost_complete(isp, (u_int16_t) fhandle);
-                       }
+                       isp->isp_intmboxc++;
+               } else if (isp_parse_async(isp, mbox) < 0) {
+                       return;
                }
                if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) {
                        ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
@@ -3077,7 +3078,7 @@
         *
         * If we're a 2300, we can ask what hardware what it thinks.
         */
-       if (IS_2300(isp)) {
+       if (IS_23XX(isp)) {
                optr = ISP_READ(isp, isp->isp_respoutrp);
                if (isp->isp_residx != optr) {
                        isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
@@ -3090,8 +3091,10 @@
        /*
         * You *must* read the Response Queue In Pointer
         * prior to clearing the RISC interrupt.
+        *
+        * Debounce the 2300 if revision less than 2.
         */
-       if (IS_2100(isp) || IS_2300(isp)) {
+       if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
                i = 0;
                do {
                        iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
@@ -3119,7 +3122,7 @@
                 * make sure the old interrupt went away (to avoid 'ringing'
                 * effects), but that didn't stop this from occurring.
                 */
-               if (IS_2300(isp)) {
+               if (IS_23XX(isp)) {
                        USEC_DELAY(100);
                        iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
                        junk = ISP_READ(isp, BIU_R2HSTSLO);
@@ -3156,6 +3159,15 @@
 
                if (type == RQSTYPE_RESPONSE) {
                        isp_get_response(isp, (ispstatusreq_t *) hp, sp);
+               } else if (type == RQSTYPE_RIO2) {
+                       isp_rio2_t rio;
+                       isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
+                       for (i = 0; i < rio.req_header.rqs_seqno; i++) {
+                               isp_fastpost_complete(isp, rio.req_handles[i]);
+                       }
+                       if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
+                               isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
+                       continue;
                } else {
                        if (!isp_handle_other_response(isp, type, hp, &optr)) {
                                MEMZERO(hp, QENTRY_LEN);        /* PERF */
@@ -3381,12 +3393,15 @@
                 * While we're at it, reqad the requst queue out pointer.
                 */
                isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
+               if (isp->isp_rscchiwater < ndone)
+                       isp->isp_rscchiwater = ndone;
        }
 
        isp->isp_residx = optr;
        for (i = 0; i < ndone; i++) {
                xs = complist[i];
                if (xs) {
+                       isp->isp_rsltccmplt++;
                        isp_done(xs);
                }
        }
@@ -3397,16 +3412,16 @@
  */
 
 static int
-isp_parse_async(struct ispsoftc *isp, int mbox)
+isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
 {
        int bus;
-       u_int16_t fast_post_handle = 0;
 
        if (IS_DUALBUS(isp)) {
                bus = ISP_READ(isp, OUTMAILBOX6);
        } else {
                bus = 0;
        }
+       isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
 
        switch (mbox) {
        case ASYNC_BUS_RESET:
@@ -3508,10 +3523,32 @@
                isp->isp_sendmarker |= (1 << bus);
                break;
 
+       /*
+        * We can use bus, which will always be zero for FC cards,
+        * as a mailbox pattern accumulator to be checked below.
+        */
+       case ASYNC_RIO5:
+               bus = 0x1ce;    /* outgoing mailbox regs 1-3, 6-7 */
+               break;
+
+       case ASYNC_RIO4:
+               bus = 0x14e;    /* outgoing mailbox regs 1-3, 6 */
+               break;
+
+       case ASYNC_RIO3:
+               bus = 0x10e;    /* outgoing mailbox regs 1-3 */
+               break;
+
+       case ASYNC_RIO2:
+               bus = 0x106;    /* outgoing mailbox regs 1-2 */
+               break;
+
+       case ASYNC_RIO1:
        case ASYNC_CMD_CMPLT:
-               fast_post_handle = ISP_READ(isp, OUTMAILBOX1);
-               isp_prt(isp, ISP_LOGDEBUG3, "fast post completion of %u",
-                   fast_post_handle);
+               bus = 0x102;    /* outgoing mailbox regs 1 */
+               break;
+
+       case ASYNC_RIO_RESP:
                break;
 
        case ASYNC_CTIO_DONE:
@@ -3673,7 +3710,28 @@
                isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
                break;
        }
-       return (fast_post_handle);
+
+       if (bus & 0x100) {
+               int i, nh;
+               u_int16_t handles[5];
+
+               for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
+                       if ((bus & (1 << i)) == 0) {
+                               continue;
+                       }
+                       handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
+               }



Home | Main Index | Thread Index | Old Index