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