Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Add AdvanSys U2W (LVD) boards support



details:   https://anonhg.NetBSD.org/src/rev/8f326a27ab97
branches:  trunk
changeset: 481688:8f326a27ab97
user:      dante <dante%NetBSD.org@localhost>
date:      Thu Feb 03 20:28:26 2000 +0000

description:
Add AdvanSys U2W (LVD) boards support

diffstat:

 sys/dev/ic/adw.c      |   444 ++++++--
 sys/dev/ic/adw.h      |    75 +-
 sys/dev/ic/adwlib.c   |  2397 ++++++++++++++++++++++++++++++++++++------------
 sys/dev/ic/adwlib.h   |   579 +++++++----
 sys/dev/ic/adwmcode.c |   966 +++++++++++++-----
 sys/dev/ic/adwmcode.h |    14 +-
 sys/dev/pci/adw_pci.c |    27 +-
 7 files changed, 3260 insertions(+), 1242 deletions(-)

diffs (truncated from 5826 to 300 lines):

diff -r 0921afa26adc -r 8f326a27ab97 sys/dev/ic/adw.c
--- a/sys/dev/ic/adw.c  Thu Feb 03 19:57:13 2000 +0000
+++ b/sys/dev/ic/adw.c  Thu Feb 03 20:28:26 2000 +0000
@@ -1,9 +1,9 @@
-/* $NetBSD: adw.c,v 1.12 1999/09/30 23:04:40 thorpej Exp $      */
+/* $NetBSD: adw.c,v 1.13 2000/02/03 20:29:15 dante Exp $        */
 
 /*
  * Generic driver for the Advanced Systems Inc. SCSI controllers
  *
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Author: Baldassare Dante Profeta <dante%mclink.it@localhost>
@@ -70,21 +70,23 @@
 /******************************************************************************/
 
 
-static int adw_alloc_ccbs __P((ADW_SOFTC *));
+static int adw_alloc_controls __P((ADW_SOFTC *));
+static int adw_alloc_carriers __P((ADW_SOFTC *));
+static int adw_create_carriers __P((ADW_SOFTC *));
+static int adw_init_carrier __P((ADW_SOFTC *, ADW_CARRIER *));
 static int adw_create_ccbs __P((ADW_SOFTC *, ADW_CCB *, int));
 static void adw_free_ccb __P((ADW_SOFTC *, ADW_CCB *));
 static void adw_reset_ccb __P((ADW_CCB *));
 static int adw_init_ccb __P((ADW_SOFTC *, ADW_CCB *));
 static ADW_CCB *adw_get_ccb __P((ADW_SOFTC *, int));
-static void adw_queue_ccb __P((ADW_SOFTC *, ADW_CCB *));
-static void adw_start_ccbs __P((ADW_SOFTC *));
+static int adw_queue_ccb __P((ADW_SOFTC *, ADW_CCB *, int));
 
 static int adw_scsi_cmd __P((struct scsipi_xfer *));
 static int adw_build_req __P((struct scsipi_xfer *, ADW_CCB *));
 static void adw_build_sglist __P((ADW_CCB *, ADW_SCSI_REQ_Q *, ADW_SG_BLOCK *));
 static void adwminphys __P((struct buf *));
-static void adw_wide_isr_callback __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *));
-static void adw_sbreset_callback __P((ADW_SOFTC *));
+static void adw_isr_callback __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *));
+static void adw_async_callback __P((ADW_SOFTC *, u_int8_t));
 
 static int adw_poll __P((ADW_SOFTC *, struct scsipi_xfer *, int));
 static void adw_timeout __P((void *));
@@ -113,14 +115,14 @@
 
 
 static int
-adw_alloc_ccbs(sc)
+adw_alloc_controls(sc)
        ADW_SOFTC      *sc;
 {
        bus_dma_segment_t seg;
        int             error, rseg;
 
        /*
-         * Allocate the control blocks.
+         * Allocate the control structure.
          */
        if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adw_control),
                           NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
@@ -135,6 +137,7 @@
                       sc->sc_dev.dv_xname, error);
                return (error);
        }
+
        /*
          * Create and load the DMA map used for the control blocks.
          */
@@ -152,10 +155,163 @@
                       sc->sc_dev.dv_xname, error);
                return (error);
        }
+
        return (0);
 }
 
 
+static int
+adw_alloc_carriers(sc)
+       ADW_SOFTC      *sc;
+{
+       bus_dma_segment_t seg;
+       int             error, rseg;
+
+       /*
+         * Allocate the control structure.
+         */
+       sc->sc_control->carriers = malloc(ADW_CARRIER_SIZE * ADW_MAX_CARRIER,
+                       M_DEVBUF, M_WAITOK);
+       if(!sc->sc_control->carriers) {
+               printf("%s: malloc() failed in allocating carrier structures,"
+                      " error = %d\n", sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+
+       if ((error = bus_dmamem_alloc(sc->sc_dmat,
+                       ADW_CARRIER_SIZE * ADW_MAX_CARRIER,
+                       NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
+               printf("%s: unable to allocate carrier structures,"
+                      " error = %d\n", sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+       if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
+                       ADW_CARRIER_SIZE * ADW_MAX_CARRIER,
+                       (caddr_t *) &sc->sc_control->carriers,
+                       BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
+               printf("%s: unable to map carrier structures,"
+                       " error = %d\n", sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+
+       /*
+         * Create and load the DMA map used for the control blocks.
+         */
+       if ((error = bus_dmamap_create(sc->sc_dmat,
+                       ADW_CARRIER_SIZE * ADW_MAX_CARRIER, 1,
+                       ADW_CARRIER_SIZE * ADW_MAX_CARRIER, 0, BUS_DMA_NOWAIT,
+                       &sc->sc_dmamap_carrier)) != 0) {
+               printf("%s: unable to create carriers DMA map,"
+                       " error = %d\n", sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+       if ((error = bus_dmamap_load(sc->sc_dmat,
+                       sc->sc_dmamap_carrier, sc->sc_control->carriers,
+                       ADW_CARRIER_SIZE * ADW_MAX_CARRIER, NULL,
+                       BUS_DMA_NOWAIT)) != 0) {
+               printf("%s: unable to load carriers DMA map,"
+                       " error = %d\n", sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+
+       error = bus_dmamap_create(sc->sc_dmat, ADW_CARRIER_SIZE* ADW_MAX_CARRIER,
+                       1, ADW_CARRIER_SIZE * ADW_MAX_CARRIER,
+                       0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
+                       &sc->sc_control->dmamap_xfer);
+       if (error) {
+               printf("%s: unable to create Carrier DMA map, error = %d\n",
+                      sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+
+       return (0);
+}
+
+
+/*
+ * Create a set of Carriers and add them to the free list.  Called once
+ * by adw_init().  We return the number of Carriers successfully created.
+ */
+static int
+adw_create_carriers(sc)
+       ADW_SOFTC       *sc;
+{
+       ADW_CARRIER     *carr;
+       u_int32_t       carr_next = NULL;
+       int             i, error;
+
+       for(i=0; i < ADW_MAX_CARRIER; i++) {
+               carr = (ADW_CARRIER *)(((u_int8_t *)sc->sc_control->carriers) +
+                               (ADW_CARRIER_SIZE * i));
+               if ((error = adw_init_carrier(sc, carr)) != 0) {
+                       printf("%s: unable to initialize carrier, error = %d\n",
+                              sc->sc_dev.dv_xname, error);
+                       return (i);
+               }
+               carr->next_vpa = carr_next;
+               carr_next = carr->carr_pa;
+carr->id = i;
+       }
+       sc->carr_freelist = carr;
+       return (i);
+}
+
+
+static int
+adw_init_carrier(sc, carr)
+       ADW_SOFTC       *sc;
+       ADW_CARRIER     *carr;
+{
+       u_int32_t       carr_pa;
+       int             /*error, */hashnum;
+
+       /*
+         * Create the DMA map for all of the Carriers.
+         */
+/*     error = bus_dmamap_create(sc->sc_dmat, ADW_CARRIER_SIZE,
+                       1, ADW_CARRIER_SIZE,
+                       0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
+                       &carr->dmamap_xfer);
+       if (error) {
+               printf("%s: unable to create Carrier DMA map, error = %d\n",
+                      sc->sc_dev.dv_xname, error);
+               return (error);
+       }
+*/
+       /*
+        * put in the phystokv hash table
+        * Never gets taken out.
+        */
+       carr_pa = ADW_CARRIER_ADDR(sc, carr);
+       carr->carr_pa = carr_pa;
+       hashnum = CARRIER_HASH(carr_pa);
+       carr->nexthash = sc->sc_carrhash[hashnum];
+       sc->sc_carrhash[hashnum] = carr;
+
+       return(0);
+}
+
+
+/*
+ * Given a physical address, find the Carrier that it corresponds to.
+ */
+ADW_CARRIER *
+adw_carrier_phys_kv(sc, carr_phys)
+       ADW_SOFTC       *sc;
+       u_int32_t       carr_phys;
+{
+       int hashnum = CARRIER_HASH(carr_phys);
+       ADW_CARRIER *carr = sc->sc_carrhash[hashnum];
+
+       while (carr) {
+               if (carr->carr_pa == carr_phys)
+                       break;
+               carr = carr->nexthash;
+       }
+       return (carr);
+}
+
+
 /*
  * Create a set of ccbs and add them to the free list.  Called once
  * by adw_init().  We return the number of CCBs successfully created.
@@ -169,7 +325,6 @@
        ADW_CCB        *ccb;
        int             i, error;
 
-       bzero(ccbstore, sizeof(ADW_CCB) * count);
        for (i = 0; i < count; i++) {
                ccb = &ccbstore[i];
                if ((error = adw_init_ccb(sc, ccb)) != 0) {
@@ -234,7 +389,7 @@
                         ADW_MAX_SG_LIST, (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
                   0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
        if (error) {
-               printf("%s: unable to create DMA map, error = %d\n",
+               printf("%s: unable to create CCB DMA map, error = %d\n",
                       sc->sc_dev.dv_xname, error);
                return (error);
        }
@@ -315,39 +470,41 @@
 /*
  * Queue a CCB to be sent to the controller, and send it if possible.
  */
-static void
-adw_queue_ccb(sc, ccb)
+static int
+adw_queue_ccb(sc, ccb, retry)
        ADW_SOFTC      *sc;
        ADW_CCB        *ccb;
+       int             retry;
 {
-       int             s;
-
-       s = splbio();
-       TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
-       splx(s);
+       int             errcode;
 
-       adw_start_ccbs(sc);
-}
-
-
-static void
-adw_start_ccbs(sc)
-       ADW_SOFTC      *sc;
-{
-       ADW_CCB        *ccb;
-       int             s;
+       if(!retry)
+               TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
 
        while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
 
-               while (AdvExeScsiQueue(sc, &ccb->scsiq) == ADW_BUSY);
+               errcode = AdvExeScsiQueue(sc, &ccb->scsiq);
+               switch(errcode) {
+               case ADW_SUCCESS:
+                       break;
 
-               s = splbio();
+               case ADW_BUSY:
+                       printf("ADW_BUSY\n");
+                       return(ADW_BUSY);
+
+               case ADW_ERROR:
+                       printf("ADW_ERROR\n");
+                       TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
+                       return(ADW_ERROR);
+               }



Home | Main Index | Thread Index | Old Index