Source-Changes-HG archive

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

[src/thorpej_scsipi]: src/sys/dev/eisa Adapt to scsipi API changes.



details:   https://anonhg.NetBSD.org/src/rev/669cd0aa6a7f
branches:  thorpej_scsipi
changeset: 477269:669cd0aa6a7f
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue Oct 19 17:44:55 1999 +0000

description:
Adapt to scsipi API changes.

diffstat:

 sys/dev/eisa/ahb.c |  416 +++++++++++++++++++++++-----------------------------
 1 files changed, 185 insertions(+), 231 deletions(-)

diffs (truncated from 551 to 300 lines):

diff -r 54ab02680b64 -r 669cd0aa6a7f sys/dev/eisa/ahb.c
--- a/sys/dev/eisa/ahb.c        Tue Oct 19 17:39:25 1999 +0000
+++ b/sys/dev/eisa/ahb.c        Tue Oct 19 17:44:55 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahb.c,v 1.28 1999/09/30 23:04:39 thorpej Exp $ */
+/*     $NetBSD: ahb.c,v 1.28.2.1 1999/10/19 17:44:55 thorpej Exp $     */
 
 #include "opt_ddb.h"
 
@@ -111,10 +111,9 @@
        TAILQ_HEAD(, ahb_ecb) sc_free_ecb;
        struct ahb_ecb *sc_immed_ecb;   /* an outstanding immediete command */
        int sc_numecbs;
-       struct scsipi_link sc_link;
+
        struct scsipi_adapter sc_adapter;
-
-       TAILQ_HEAD(, scsipi_xfer) sc_queue;
+       struct scsipi_channel sc_channel;
 };
 
 /*
@@ -137,7 +136,8 @@
 int    ahb_find __P((bus_space_tag_t, bus_space_handle_t, struct ahb_probe_data *));
 int    ahb_init __P((struct ahb_softc *));
 void   ahbminphys __P((struct buf *));
-int    ahb_scsi_cmd __P((struct scsipi_xfer *));
+void   ahb_scsipi_request __P((struct scsipi_channel *,
+           scsipi_adapter_req_t, void *));
 int    ahb_poll __P((struct ahb_softc *, struct scsipi_xfer *, int));
 void   ahb_timeout __P((void *));
 int    ahb_create_ecbs __P((struct ahb_softc *, struct ahb_ecb *, int));
@@ -145,14 +145,6 @@
 integrate void ahb_reset_ecb __P((struct ahb_softc *, struct ahb_ecb *));
 integrate int ahb_init_ecb __P((struct ahb_softc *, struct ahb_ecb *));
 
-/* the below structure is so we have a default dev struct for our link struct */
-struct scsipi_device ahb_dev = {
-       NULL,                   /* Use default error handler */
-       NULL,                   /* have a queue, served by this */
-       NULL,                   /* have no async handler */
-       NULL,                   /* Use default 'done' routine */
-};
-
 int    ahbmatch __P((struct device *, struct cfdata *, void *));
 void   ahbattach __P((struct device *, struct device *, void *));
 
@@ -213,6 +205,8 @@
        eisa_intr_handle_t ih;
        const char *model, *intrstr;
        struct ahb_probe_data apd;
+       struct scsipi_adapter *adapt = &sc->sc_adapter;
+       struct scsipi_channel *chan = &sc->sc_channel;
 
        if (!strcmp(ea->ea_idstring, "ADP0000"))
                model = EISA_PRODUCT_ADP0000;
@@ -238,32 +232,34 @@
                panic("ahbattach: ahb_find failed!");
 
        TAILQ_INIT(&sc->sc_free_ecb);
-       TAILQ_INIT(&sc->sc_queue);
+
+       /*
+        * Fill in the scsipi_adapter.
+        */
+       memset(adapt, 0, sizeof(*adapt));
+       adapt->adapt_dev = &sc->sc_dev;
+       adapt->adapt_nchannels = 1;
+       /* adapt_openings initialized below */
+       adapt->adapt_max_periph = 4;            /* XXX arbitrary? */
+       adapt->adapt_request = ahb_scsipi_request;
+       adapt->adapt_minphys = ahbminphys;
+
+       /*
+        * Fill in the scsipi_channel.
+        */
+       memset(chan, 0, sizeof(*chan));
+       chan->chan_adapter = adapt;
+       chan->chan_bustype = &scsi_bustype;
+       chan->chan_channel = 0;
+       chan->chan_ntargets = 8;
+       chan->chan_nluns = 8;
+       chan->chan_id = apd.sc_scsi_dev;
 
        if (ahb_init(sc) != 0) {
                /* Error during initialization! */
                return;
        }
 
-       /*
-        * Fill in the adapter switch.
-        */
-       sc->sc_adapter.scsipi_cmd = ahb_scsi_cmd;
-       sc->sc_adapter.scsipi_minphys = ahbminphys;
-
-       /*
-        * fill in the prototype scsipi_link.
-        */
-       sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
-       sc->sc_link.adapter_softc = sc;
-       sc->sc_link.scsipi_scsi.adapter_target = apd.sc_scsi_dev;
-       sc->sc_link.adapter = &sc->sc_adapter;
-       sc->sc_link.device = &ahb_dev;
-       sc->sc_link.openings = 4;
-       sc->sc_link.scsipi_scsi.max_target = 7;
-       sc->sc_link.scsipi_scsi.max_lun = 7;
-       sc->sc_link.type = BUS_SCSI;
-
        if (eisa_intr_map(ec, apd.sc_irq, &ih)) {
                printf("%s: couldn't map interrupt (%d)\n",
                    sc->sc_dev.dv_xname, apd.sc_irq);
@@ -287,7 +283,7 @@
        /*
         * ask the adapter what subunits are present
         */
-       config_found(self, &sc->sc_link, scsiprint);
+       config_found(self, &sc->sc_channel, scsiprint);
 }
 
 /*
@@ -321,7 +317,7 @@
        bus_space_write_4(iot, ioh, MBOXOUT0,
            sc->sc_dmamap_ecb->dm_segs[0].ds_addr + AHB_ECB_OFF(ecb));
        bus_space_write_1(iot, ioh, ATTN, opcode |
-               ecb->xs->sc_link->scsipi_scsi.target);
+               ecb->xs->xs_periph->periph_target);
 
        if ((ecb->xs->xs_control & XS_CTL_POLL) == 0)
                timeout(ahb_timeout, ecb, (ecb->timeout * hz) / 1000);
@@ -354,7 +350,7 @@
        bus_space_write_4(iot, ioh, MBOXOUT0, cmd);     /* don't know this will work */
        bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_SET_HOST_READY);
        bus_space_write_1(iot, ioh, ATTN, OP_IMMED |
-               ecb->xs->sc_link->scsipi_scsi.target);
+               ecb->xs->xs_periph->periph_target);
 
        if ((ecb->xs->xs_control & XS_CTL_POLL) == 0)
                timeout(ahb_timeout, ecb, (ecb->timeout * hz) / 1000);
@@ -661,19 +657,7 @@
        }
 done:
        ahb_free_ecb(sc, ecb);
-       xs->xs_status |= XS_STS_DONE;
        scsipi_done(xs);
-
-       /*
-        * If there are queue entries in the software queue, try to
-        * run the first one.  We should be more or less guaranteed
-        * to succeed, since we just freed an ECB.
-        *
-        * NOTE: ahb_scsi_cmd() relies on our calling it with
-        * the first entry in the queue.
-        */
-       if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
-               (void) ahb_scsi_cmd(xs);
 }
 
 /*
@@ -827,6 +811,8 @@
                    sc->sc_dev.dv_xname, i, AHB_ECB_MAX);
        }
 
+       sc->sc_adapter.adapt_openings = i;
+
        return (0);
 }
 
@@ -844,220 +830,187 @@
  * start a scsi operation given the command and the data address.  Also needs
  * the unit, target and lu.
  */
-int
-ahb_scsi_cmd(xs)
+void
+ahb_scsipi_request(chan, req, arg)
+       struct scsipi_channel *chan;
+       scsipi_adapter_req_t req;
+       void *arg;
+{
        struct scsipi_xfer *xs;
-{
-       struct scsipi_link *sc_link = xs->sc_link;
-       struct ahb_softc *sc = sc_link->adapter_softc;
+       struct scsipi_periph *periph;
+       struct ahb_softc *sc = (void *)chan->chan_adapter->adapt_dev;
        bus_dma_tag_t dmat = sc->sc_dmat;
        struct ahb_ecb *ecb;
        int error, seg, flags, s;
-       int fromqueue = 0, dontqueue = 0;
 
-       SC_DEBUG(sc_link, SDEV_DB2, ("ahb_scsi_cmd\n"));
+       switch (req) {
+       case ADAPTER_REQ_RUN_XFER:
+               xs = arg;
+               periph = xs->xs_periph;
+               flags = xs->xs_control;
 
-       s = splbio();           /* protect the queue */
+               SC_DEBUG(sc_link, SDEV_DB2, ("ahb_scsipi_request\n"));
 
-       /*
-        * If we're running the queue from ahb_done(), we've been
-        * called with the first queue entry as our argument.
-        */
-       if (xs == TAILQ_FIRST(&sc->sc_queue)) {
-               TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
-               fromqueue = 1;
-               goto get_ecb;
-       }
+               /* Get an ECB to use. */
+               ecb = ahb_get_ecb(sc, flags);
+#ifdef DIAGNOSTIC
+               /*
+                * This should never happen as we track the resources
+                * in the mid-layer.
+                */
+               if (ecb == NULL) {
+                       scsipi_printaddr(periph);
+                       printf("unable to allocate ecb\n");
+                       panic("ahb_scsipi_request");
+               }
+#endif
+
+               ecb->xs = xs;
+               ecb->timeout = xs->timeout;
 
-       /* Polled requests can't be queued for later. */
-       dontqueue = xs->xs_control & XS_CTL_POLL;
+               /*
+                * If it's a reset, we need to do an 'immediate'
+                * command, and store its ecb for later
+                * if there is already an immediate waiting,
+                * then WE must wait
+                */
+               if (flags & XS_CTL_RESET) {
+                       ecb->flags |= ECB_IMMED;
+                       if (sc->sc_immed_ecb) {
+                               ahb_free_ecb(sc, ecb);
+                               xs->error = XS_BUSY;
+                               scsipi_done(xs);
+                               return;
+                       }
+                       sc->sc_immed_ecb = ecb;
 
-       /*
-        * If there are jobs in the queue, run them first.
-        */
-       if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
-               /*
-                * If we can't queue, we have to abort, since
-                * we have to preserve order.
-                */
-               if (dontqueue) {
+                       s = splbio();
+                       ahb_send_immed(sc, AHB_TARG_RESET, ecb);
                        splx(s);
-                       xs->error = XS_DRIVER_STUFFUP;
-                       return (TRY_AGAIN_LATER);
+
+                       if ((flags & XS_CTL_POLL) == 0)
+                               return;
+
+                       /*
+                        * If we can't use interrupts, poll on completion
+                        */
+                       if (ahb_poll(sc, xs, ecb->timeout))
+                               ahb_timeout(ecb);
+                       return;
                }
 
                /*
-                * Swap with the first queue entry.
+                * Put all the arguments for the xfer in the ecb
                 */
-               TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
-               xs = TAILQ_FIRST(&sc->sc_queue);
-               TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
-               fromqueue = 1;
-       }
+               ecb->opcode = ECB_SCSI_OP;
+               ecb->opt1 = ECB_SES /*| ECB_DSB*/ | ECB_ARS;
+               ecb->opt2 = periph->periph_lun | ECB_NRB;
+               bcopy(xs->cmd, &ecb->scsi_cmd,
+                   ecb->scsi_cmd_length = xs->cmdlen);
+               ecb->sense_ptr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
+                   AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_sense);
+               ecb->req_sense_length = sizeof(ecb->ecb_sense);
+               ecb->status = sc->sc_dmamap_ecb->dm_segs[0].ds_addr +
+                   AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_status);
+               ecb->ecb_status.host_stat = 0x00;
+               ecb->ecb_status.target_stat = 0x00;
 
- get_ecb:
-       /*
-        * get a ecb (mbox-out) to use. If the transfer
-        * is from a buf (possibly from interrupt time)
-        * then we can't allow it to sleep
-        */
-       flags = xs->xs_control;
-       if ((ecb = ahb_get_ecb(sc, flags)) == NULL) {



Home | Main Index | Thread Index | Old Index