Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Add in an ioctl entry point so scsictl mediated b...



details:   https://anonhg.NetBSD.org/src/rev/759087f18a1a
branches:  trunk
changeset: 477181:759087f18a1a
user:      mjacob <mjacob%NetBSD.org@localhost>
date:      Thu Oct 14 02:31:11 1999 +0000

description:
Add in an ioctl entry point so scsictl mediated bus resets will work.
Redo how we start commands- do a 'slow' start function which then
looks to see when we're done the configuration process at which point
it *then* enables sync/wide mode. Set the max openings amount to the
true max openings- not a synthetic. Add a timeout driven command requeue
function so that Loop Down events well freeze things until a later point
in time where they might be restarted.

diffstat:

 sys/dev/ic/isp_netbsd.c |  351 +++++++++++++++++++++++++++++++----------------
 1 files changed, 228 insertions(+), 123 deletions(-)

diffs (truncated from 540 to 300 lines):

diff -r 9dd0e0cf36e5 -r 759087f18a1a sys/dev/ic/isp_netbsd.c
--- a/sys/dev/ic/isp_netbsd.c   Thu Oct 14 02:27:12 1999 +0000
+++ b/sys/dev/ic/isp_netbsd.c   Thu Oct 14 02:31:11 1999 +0000
@@ -1,5 +1,4 @@
-/* $NetBSD: isp_netbsd.c,v 1.16 1999/09/30 23:06:18 thorpej Exp $ */
-/* release_6_5_99 */
+/* $NetBSD: isp_netbsd.c,v 1.17 1999/10/14 02:31:11 mjacob Exp $ */
 /*
  * Platform (NetBSD) dependent common attachment code for Qlogic adapters.
  * Matthew Jacob <mjacob%nas.nasa.gov@localhost>
@@ -32,18 +31,20 @@
  */
 
 #include <dev/ic/isp_netbsd.h>
+#include <sys/scsiio.h>
 
 static void ispminphys __P((struct buf *));
+static int32_t ispcmd_slow __P((ISP_SCSI_XFER_T *));
 static int32_t ispcmd __P((ISP_SCSI_XFER_T *));
+static int
+ispioctl __P((struct scsipi_link *, u_long, caddr_t, int, struct proc *));
 
 static struct scsipi_device isp_dev = { NULL, NULL, NULL, NULL };
 static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
 static void isp_watch __P((void *));
+static void isp_command_requeue __P((void *));
 static void isp_internal_restart __P((void *));
 
-#define        FC_OPENINGS     RQUEST_QUEUE_LEN / (MAX_FC_TARG-1)
-#define        PI_OPENINGS     RQUEST_QUEUE_LEN / (MAX_TARGETS-1)
-
 /*
  * Complete attachment of hardware, include subdevices.
  */
@@ -52,14 +53,15 @@
        struct ispsoftc *isp;
 {
 
-       isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
        isp->isp_osinfo._adapter.scsipi_minphys = ispminphys;
+       isp->isp_osinfo._adapter.scsipi_ioctl = ispioctl;
 
        isp->isp_state = ISP_RUNSTATE;
        isp->isp_osinfo._link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
        isp->isp_osinfo._link.adapter_softc = isp;
        isp->isp_osinfo._link.device = &isp_dev;
        isp->isp_osinfo._link.adapter = &isp->isp_osinfo._adapter;
+       isp->isp_osinfo._link.openings = isp->isp_maxcmds;
        TAILQ_INIT(&isp->isp_osinfo.waitq);
 
        if (IS_FC(isp)) {
@@ -67,6 +69,7 @@
                 * Give it another chance here to come alive...
                 */
                fcparam *fcp = isp->isp_param;
+               isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
                if (fcp->isp_fwstate != FW_READY) {
                        (void) isp_control(isp, ISPCTL_FCLINK_TEST, NULL);
                }
@@ -79,12 +82,11 @@
 #else
                isp->isp_osinfo._link.scsipi_scsi.max_lun = 15;
 #endif
-               isp->isp_osinfo._link.openings = FC_OPENINGS;
                isp->isp_osinfo._link.scsipi_scsi.adapter_target =
                        ((fcparam *)isp->isp_param)->isp_loopid;
        } else {
                sdparam *sdp = isp->isp_param;
-               isp->isp_osinfo._link.openings = PI_OPENINGS;
+               isp->isp_osinfo._adapter.scsipi_cmd = ispcmd_slow;
                isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_TARGETS-1;
                if (isp->isp_bustype == ISP_BT_SBUS) {
                        isp->isp_osinfo._link.scsipi_scsi.max_lun = 7;
@@ -101,6 +103,8 @@
                }
                isp->isp_osinfo._link.scsipi_scsi.adapter_target =
                    sdp->isp_initiator_id;
+               isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
+               isp->isp_osinfo.discovered[1] = 1 << sdp->isp_initiator_id;
                if (IS_12X0(isp)) {
                        isp->isp_osinfo._link_b = isp->isp_osinfo._link;
                        sdp++;
@@ -109,15 +113,12 @@
                        isp->isp_osinfo._link_b.scsipi_scsi.channel = 1;
                }
        }
-       if (isp->isp_osinfo._link.openings < 2)
-               isp->isp_osinfo._link.openings = 2;
        isp->isp_osinfo._link.type = BUS_SCSI;
 
        /*
         * Send a SCSI Bus Reset (used to be done as part of attach,
         * but now left to the OS outer layers).
         */
-       
        if (IS_SCSI(isp)) {
                int bus = 0;
                (void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
@@ -132,7 +133,7 @@
         * Start the watchdog.
         */
        isp->isp_dogactive = 1;
-       timeout(isp_watch, isp, 30 * hz);
+       timeout(isp_watch, isp, WATCH_INTERVAL * hz);
 
        /*
         * And attach children (if any).
@@ -164,44 +165,86 @@
        minphys(bp);
 }
 
-static int
+static int32_t
+ispcmd_slow(xs)
+       ISP_SCSI_XFER_T *xs;
+{
+       /*
+        * Have we completed discovery for this adapter?
+        */
+       if ((xs->xs_control & XS_CTL_DISCOVERY) == 0) {
+               struct ispsoftc *isp = XS_ISP(xs);
+               sdparam *sdp = isp->isp_param;
+               int s = splbio();
+               int chan = XS_CHANNEL(xs), chmax = IS_12X0(isp)? 2 : 1;
+               u_int16_t f = DPARM_DEFAULT;
+
+               sdp += chan;
+               if (xs->sc_link->quirks & SDEV_NOSYNC) {
+                       f ^= DPARM_SYNC;
+               }
+               if (xs->sc_link->quirks & SDEV_NOWIDE) {
+                       f ^= DPARM_WIDE;
+               }
+               if (xs->sc_link->quirks & SDEV_NOTAG) {
+                       f ^= DPARM_TQING;
+               }
+               sdp->isp_devparam[XS_TGT(xs)].dev_flags = f;
+               sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
+               isp->isp_osinfo.discovered[chan] |= (1 << XS_TGT(xs));
+               f = 0xffff ^ (1 << sdp->isp_initiator_id);
+               for (chan = 0; chan < chmax; chan++) {
+                       if (isp->isp_osinfo.discovered[chan] == f)
+                               break;
+               }
+               if (chan == chmax) {
+                       isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
+                       isp->isp_update = 1;
+                       if (IS_12X0(isp))
+                               isp->isp_update |= 2;
+               }
+               (void) splx(s);
+       }
+       return (ispcmd(xs));
+}
+
+static int      
+ispioctl(sc_link, cmd, addr, flag, p)
+       struct scsipi_link *sc_link;
+       u_long cmd;
+       caddr_t addr;
+       int flag;
+       struct proc *p;
+{
+       struct ispsoftc *isp = sc_link->adapter_softc;
+       int s, chan, retval = ENOTTY;
+       
+       switch (cmd) {
+       case SCBUSIORESET:
+               chan = sc_link->scsipi_scsi.channel;
+               s = splbio();
+               if (isp_control(isp, ISPCTL_RESET_BUS, &chan))
+                       retval = EIO;
+               else
+                       retval = 0;
+               (void) splx(s);
+               break;
+       default:
+               break;
+       }
+       return (retval);
+}
+
+
+static int32_t
 ispcmd(xs)
        ISP_SCSI_XFER_T *xs;
 {
        struct ispsoftc *isp;
-       int result;
-       int s;
+       int result, s;
 
        isp = XS_ISP(xs);
        s = splbio();
-       /*
-        * This is less efficient than I would like in that the
-        * majority of cases will have to do some pointer deferences
-        * to find out that things don't need to be updated.
-        */
-#if 0 /* XXX THORPEJ */
-       if ((xs->xs_control & XS_CTL_DISCOVERY) == 0 &&
-           (isp->isp_type & ISP_HA_SCSI)) {
-               sdparam *sdp = isp->isp_param;
-               sdp += XS_CHANNEL(xs);
-               if (sdp->isp_devparam[XS_TGT(xs)].dev_flags !=
-                   sdp->isp_devparam[XS_TGT(xs)].cur_dflags) {
-                       u_int16_t f = DPARM_WIDE|DPARM_SYNC|DPARM_TQING;
-                       if (xs->sc_link->quirks & SDEV_NOSYNC)
-                               f &= ~DPARM_SYNC;
-                       if (xs->sc_link->quirks & SDEV_NOWIDE)
-                               f &= ~DPARM_WIDE;
-                       if (xs->sc_link->quirks & SDEV_NOTAG)
-                               f &= ~DPARM_TQING;
-                       sdp->isp_devparam[XS_TGT(xs)].dev_flags &=
-                               ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING);
-                       sdp->isp_devparam[XS_TGT(xs)].dev_flags |= f;
-                       sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
-                       isp->isp_update |= (1 << XS_CHANNEL(xs));
-               }
-       }
-#endif /* XXX THORPEJ */
-
        if (isp->isp_state < ISP_RUNSTATE) {
                DISABLE_INTS(isp);
                isp_init(isp);
@@ -209,7 +252,7 @@
                        ENABLE_INTS(isp);
                         (void) splx(s);
                         XS_SETERR(xs, HBA_BOTCH);
-                        return (CMD_COMPLETE);
+                        return (COMPLETE);
                 }
                 isp->isp_state = ISP_RUNSTATE;
                ENABLE_INTS(isp);
@@ -218,7 +261,6 @@
        /*
         * Check for queue blockage...
         */
-
        if (isp->isp_osinfo.blocked) {
                if (xs->xs_control & XS_CTL_POLL) {
                        xs->error = XS_DRIVER_STUFFUP;
@@ -227,37 +269,70 @@
                }
                TAILQ_INSERT_TAIL(&isp->isp_osinfo.waitq, xs, adapter_q);
                splx(s);
-               return (CMD_QUEUED);
+               return (SUCCESSFULLY_QUEUED);
        }
-       
        DISABLE_INTS(isp);
        result = ispscsicmd(xs);
        ENABLE_INTS(isp);
-       if (result != CMD_QUEUED || (xs->xs_control & XS_CTL_POLL) == 0) {
+
+       if ((xs->xs_control & XS_CTL_POLL) == 0) {
+               switch (result) {
+               case CMD_QUEUED:
+                       result = SUCCESSFULLY_QUEUED;
+                       break;
+               case CMD_EAGAIN:
+                       result = TRY_AGAIN_LATER;
+                       break;
+               case CMD_RQLATER:
+                       result = SUCCESSFULLY_QUEUED;
+                       timeout(isp_command_requeue, xs, hz);
+                       break;
+               case CMD_COMPLETE:
+                       result = COMPLETE;
+                       break;
+               }
                (void) splx(s);
                return (result);
        }
 
+       switch (result) {
+       case CMD_QUEUED:
+               result = SUCCESSFULLY_QUEUED;
+               break;
+       case CMD_RQLATER:
+       case CMD_EAGAIN:
+               if (XS_NOERR(xs)) {
+                       xs->error = XS_DRIVER_STUFFUP;
+               }
+               result = TRY_AGAIN_LATER;
+               break;
+       case CMD_COMPLETE:
+               result = COMPLETE;
+               break;
+               
+       }
        /*
         * If we can't use interrupts, poll on completion.
         */
-       if (isp_poll(isp, xs, XS_TIME(xs))) {
-               /*
-                * If no other error occurred but we didn't finish,
-                * something bad happened.
-                */
-               if (XS_IS_CMD_DONE(xs) == 0) {



Home | Main Index | Thread Index | Old Index