Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/vax/vsa DMA support for the NCR 5380-equipped vs310...



details:   https://anonhg.NetBSD.org/src/rev/fe488961ee07
branches:  trunk
changeset: 477585:fe488961ee07
user:      ragge <ragge%NetBSD.org@localhost>
date:      Fri Oct 22 21:12:20 1999 +0000

description:
DMA support for the NCR 5380-equipped vs3100's.

diffstat:

 sys/arch/vax/vsa/ncr.c |  271 ++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 237 insertions(+), 34 deletions(-)

diffs (truncated from 333 to 300 lines):

diff -r 58e3a65281ec -r fe488961ee07 sys/arch/vax/vsa/ncr.c
--- a/sys/arch/vax/vsa/ncr.c    Fri Oct 22 21:10:12 1999 +0000
+++ b/sys/arch/vax/vsa/ncr.c    Fri Oct 22 21:12:20 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ncr.c,v 1.22 1999/09/21 18:07:54 ragge Exp $   */
+/*     $NetBSD: ncr.c,v 1.23 1999/10/22 21:12:20 ragge Exp $   */
 
 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -17,8 +17,8 @@
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
+ *       This product includes software developed by the NetBSD
+ *       Foundation, Inc. and its contributors.
  * 4. Neither the name of The NetBSD Foundation nor the names of its
  *    contributors may be used to endorse or promote products derived
  *    from this software without specific prior written permission.
@@ -61,6 +61,9 @@
 #include <sys/proc.h>
 #include <sys/user.h>
 
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+
 #include <dev/scsipi/scsi_all.h>
 #include <dev/scsipi/scsipi_all.h>
 #include <dev/scsipi/scsipi_debug.h>
@@ -77,17 +80,23 @@
 
 #define MIN_DMA_LEN 128
 
-#ifdef notyet
 struct si_dma_handle {
        int     dh_flags;
 #define SIDH_BUSY      1
 #define SIDH_OUT       2
-       u_char  *dh_addr;
+       caddr_t dh_addr;
+       int     dh_len;
+       struct  proc *dh_proc;
 };
-#endif
 
 struct si_softc {
-       struct ncr5380_softc    ncr_sc;
+       struct  ncr5380_softc   ncr_sc;
+       caddr_t ncr_addr;
+       int     ncr_off;
+       int     ncr_dmaaddr;
+       int     ncr_dmacount;
+       int     ncr_dmadir;
+       struct  si_dma_handle ncr_dma[SCI_OPENINGS];
 };
 
 /* This is copied from julian's bt driver */
@@ -99,24 +108,24 @@
        NULL,   /* Use default "done" routine. */
 };
 
-static int si_match(struct device *, struct cfdata *, void *);
-static void si_attach(struct device *, struct device *, void *);
-static void si_minphys(struct buf *);
-static void si_intr(int);
-void dk_establish(void);
+static int si_match(struct device *, struct cfdata *, void *);
+static void si_attach(struct device *, struct device *, void *);
+static void si_minphys(struct buf *);
+static void si_intr(int);
+
+static void si_dma_alloc __P((struct ncr5380_softc *));
+static void si_dma_free __P((struct ncr5380_softc *));
+static void si_dma_setup __P((struct ncr5380_softc *));
+static void si_dma_start __P((struct ncr5380_softc *));
+static void si_dma_poll __P((struct ncr5380_softc *));
+static void si_dma_eop __P((struct ncr5380_softc *));
+static void si_dma_stop __P((struct ncr5380_softc *));
+
 
 struct cfattach ncr_ca = {
        sizeof(struct si_softc), si_match, si_attach
 };
 
-void
-dk_establish(void)
-{
-#if 0
-       printf("faking dk_establish()...\n");
-#endif
-}
-
 static int
 si_match(parent, cf, aux)
        struct device *parent;
@@ -149,24 +158,38 @@
 
        printf("\n");
        /*
-        * MD function pointers used by the MI code.
+        * DMA area mapin.
+        * On VS3100, split the 128K block between the two devices.
+        * On VS2000, don't care for now.
         */
+#define DMASIZE (64*1024)
+       if (vax_boardtype != VAX_BTYP_410) {
+               if (va->va_paddr & 0x100) /* Magic */
+                       sc->ncr_off = DMASIZE;
+               sc->ncr_addr = (caddr_t)uvm_km_valloc(kernel_map, DMASIZE);
+               
+               ioaccess((vaddr_t)sc->ncr_addr,
+                   0x202d0000 + sc->ncr_off, DMASIZE/VAX_NBPG);
+
+               /*
+                * MD function pointers used by the MI code.
+                */
+               ncr_sc->sc_dma_alloc = si_dma_alloc;
+               ncr_sc->sc_dma_free  = si_dma_free;
+               ncr_sc->sc_dma_setup = si_dma_setup;
+               ncr_sc->sc_dma_start = si_dma_start;
+               ncr_sc->sc_dma_poll  = si_dma_poll;
+               ncr_sc->sc_dma_eop   = si_dma_eop;
+               ncr_sc->sc_dma_stop  = si_dma_stop;
+
+               /* DMA control register offsets */
+               sc->ncr_dmaaddr = 32;   /* DMA address in buffer, longword */
+               sc->ncr_dmacount = 64;  /* DMA count register */
+               sc->ncr_dmadir = 68;    /* Direction of DMA transfer */
+       }
        ncr_sc->sc_pio_out = ncr5380_pio_out;
        ncr_sc->sc_pio_in =  ncr5380_pio_in;
 
-#ifdef notyet
-       ncr_sc->sc_dma_alloc = si_dma_alloc;
-       ncr_sc->sc_dma_free  = si_dma_free;
-       ncr_sc->sc_dma_setup = si_dma_setup;
-       ncr_sc->sc_dma_start = si_dma_start;
-       ncr_sc->sc_dma_poll  = si_dma_poll;
-       ncr_sc->sc_dma_eop   = si_dma_eop;
-       ncr_sc->sc_dma_stop  = si_dma_stop;
-#endif
-       ncr_sc->sc_intr_on   = NULL /*si_intr_on*/;
-       ncr_sc->sc_intr_off  = NULL /*si_intr_off*/;
-
-       ncr_sc->sc_dma_alloc = NULL;
        ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
 
        /*
@@ -228,3 +251,183 @@
 {
        ncr5380_intr(ncr_cd.cd_devs[arg]);
 }
+
+void
+si_dma_alloc(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       struct sci_req *sr = ncr_sc->sc_current;
+       struct scsipi_xfer *xs = sr->sr_xs;
+       struct si_dma_handle *dh;
+       int xlen, i;
+
+#ifdef DIAGNOSTIC
+       if (sr->sr_dma_hand != NULL)
+               panic("si_dma_alloc: already have DMA handle");
+#endif
+
+       /* Polled transfers shouldn't allocate a DMA handle. */
+       if (sr->sr_flags & SR_IMMED)
+               return;
+
+       xlen = ncr_sc->sc_datalen;
+
+       /* Make sure our caller checked sc_min_dma_len. */
+       if (xlen < MIN_DMA_LEN)
+               panic("si_dma_alloc: len=0x%x\n", xlen);
+
+       /*
+        * Find free PDMA handle.  Guaranteed to find one since we
+        * have as many PDMA handles as the driver has processes.
+        * (instances?)
+        */
+        for (i = 0; i < SCI_OPENINGS; i++) {
+               if ((sc->ncr_dma[i].dh_flags & SIDH_BUSY) == 0)
+                       goto found;
+       }
+       panic("sbc: no free PDMA handles");
+found:
+       dh = &sc->ncr_dma[i];
+       dh->dh_flags = SIDH_BUSY;
+       dh->dh_addr = ncr_sc->sc_dataptr;
+       dh->dh_len = xlen;
+       dh->dh_proc = xs->bp->b_proc;
+
+       /* Remember dest buffer parameters */
+       if (xs->xs_control & XS_CTL_DATA_OUT)
+               dh->dh_flags |= SIDH_OUT;
+
+       sr->sr_dma_hand = dh;
+}
+
+void
+si_dma_free(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct sci_req *sr = ncr_sc->sc_current;
+       struct si_dma_handle *dh = sr->sr_dma_hand;
+
+       if (dh->dh_flags & SIDH_BUSY)
+               dh->dh_flags = 0;
+       else
+               printf("si_dma_free: free'ing unused buffer\n");
+
+       sr->sr_dma_hand = NULL;
+}
+
+void
+si_dma_setup(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       /* Do nothing here */
+}
+
+void
+si_dma_start(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       struct sci_req *sr = ncr_sc->sc_current;
+       struct si_dma_handle *dh = sr->sr_dma_hand;
+
+       /*
+        * Set the VAX-DMA-specific registers, and copy the data if
+        * it is directed "outbound".
+        */
+       if (dh->dh_flags & SIDH_OUT) {
+               if ((vaddr_t)dh->dh_addr & KERNBASE)
+                       bcopy(dh->dh_addr, sc->ncr_addr, dh->dh_len);
+               else
+                       vsbus_copyfromproc(dh->dh_proc, dh->dh_addr,
+                           sc->ncr_addr, dh->dh_len);
+               bus_space_write_1(ncr_sc->sc_regt, ncr_sc->sc_regh,
+                   sc->ncr_dmadir, 0);
+       } else {
+               bus_space_write_1(ncr_sc->sc_regt, ncr_sc->sc_regh,
+                   sc->ncr_dmadir, 1);
+       }
+       bus_space_write_4(ncr_sc->sc_regt, ncr_sc->sc_regh,
+           sc->ncr_dmacount, -dh->dh_len);
+       bus_space_write_4(ncr_sc->sc_regt, ncr_sc->sc_regh,
+           sc->ncr_dmaaddr, sc->ncr_off);
+       /*
+        * Now from the 5380-internal DMA registers.
+        */
+       if (dh->dh_flags & SIDH_OUT) {
+               NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_DATA_OUT);
+               NCR5380_WRITE(ncr_sc, sci_icmd, SCI_ICMD_DATA);
+               NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode)
+                   | SCI_MODE_DMA | SCI_MODE_DMA_IE);
+               NCR5380_WRITE(ncr_sc, sci_dma_send, 0);
+       } else {
+               NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_DATA_IN);
+               NCR5380_WRITE(ncr_sc, sci_icmd, 0);
+               NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode)
+                   | SCI_MODE_DMA | SCI_MODE_DMA_IE);
+               NCR5380_WRITE(ncr_sc, sci_irecv, 0);
+       }
+       ncr_sc->sc_state |= NCR_DOINGDMA;
+}
+
+/*
+ * When?
+ */
+void
+si_dma_poll(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       printf("si_dma_poll\n");
+}
+
+/*
+ * When?
+ */
+void
+si_dma_eop(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       printf("si_dma_eop\n");
+}
+
+void
+si_dma_stop(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       struct sci_req *sr = ncr_sc->sc_current;
+       struct si_dma_handle *dh = sr->sr_dma_hand;
+       int count, i;



Home | Main Index | Thread Index | Old Index