summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/vax/vsa/if_le_vsbus.c139
-rw-r--r--sys/arch/vax/vsa/ncr.c135
-rw-r--r--sys/arch/vax/vsa/vsbus.c100
3 files changed, 268 insertions, 106 deletions
diff --git a/sys/arch/vax/vsa/if_le_vsbus.c b/sys/arch/vax/vsa/if_le_vsbus.c
index 08901588b70..735a2dfff2a 100644
--- a/sys/arch/vax/vsa/if_le_vsbus.c
+++ b/sys/arch/vax/vsa/if_le_vsbus.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_le_vsbus.c,v 1.1 2000/04/27 02:34:50 bjc Exp $ */
-/* $NetBSD: if_le_vsbus.c,v 1.2 1999/08/27 20:05:08 ragge Exp $ */
+/* $OpenBSD: if_le_vsbus.c,v 1.2 2000/10/11 06:19:19 bjc Exp $ */
+/* $NetBSD: if_le_vsbus.c,v 1.10 2000/06/29 07:14:18 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -103,10 +103,17 @@
#include <dev/ic/am7990reg.h>
#include <dev/ic/am7990var.h>
-#include <dev/tc/if_levar.h>
-int le_vsbus_match __P((struct device *, struct cfdata *, void *));
-void le_vsbus_attach __P((struct device *, struct device *, void *));
+struct le_softc {
+ struct am7990_softc sc_am7990; /* Must be first */
+ struct evcnt sc_intrcnt;
+ bus_dmamap_t sc_dm;
+ volatile u_short *sc_rap;
+ volatile u_short *sc_rdp;
+};
+
+static int le_vsbus_match __P((struct device *, struct cfdata *, void *));
+static void le_vsbus_attach __P((struct device *, struct device *, void *));
static void lewrcsr __P((struct am7990_softc *, u_int16_t, u_int16_t));
static u_int16_t lerdcsr __P((struct am7990_softc *, u_int16_t));
@@ -114,39 +121,60 @@ struct cfattach le_vsbus_ca = {
sizeof(struct le_softc), (cfmatch_t)le_vsbus_match, le_vsbus_attach
};
-void
-lewrcsr(sc, port, val)
- struct am7990_softc *sc;
+static void
+lewrcsr(ls, port, val)
+ struct am7990_softc *ls;
u_int16_t port, val;
{
- struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
+ struct le_softc *sc = (void *)ls;
- ler1->ler1_rap = port;
- ler1->ler1_rdp = val;
+ *sc->sc_rap = port;
+ *sc->sc_rdp = val;
}
-u_int16_t
-lerdcsr(sc, port)
- struct am7990_softc *sc;
+static u_int16_t
+lerdcsr(ls, port)
+ struct am7990_softc *ls;
u_int16_t port;
{
- struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
+ struct le_softc *sc = (void *)ls;
- ler1->ler1_rap = port;
- return ler1->ler1_rdp;
+ *sc->sc_rap = port;
+ return *sc->sc_rdp;
}
-int
+static int
le_vsbus_match(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
- struct vsbus_attach_args *va = aux;
+ struct vsbus_attach_args *va = aux;
volatile short *rdp, *rap;
+ struct leinit initblock;
+ bus_dmamap_t map;
+ int i;
+ int rv = 0;
+ int error;
if (vax_boardtype == VAX_BTYP_49)
return 0;
+
+ error = bus_dmamap_create(va->va_dmat, sizeof(initblock), 1,
+ sizeof(initblock), 0, BUS_DMA_NOWAIT, &map);
+ if (error) {
+ return 0;
+ }
+
+ error = bus_dmamap_load(va->va_dmat, map, &initblock,
+ sizeof(initblock), NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
+ if (error) {
+ bus_dmamap_destroy(va->va_dmat, map);
+ return 0;
+ }
+
+ memset(&initblock, 0, sizeof(initblock));
+
rdp = (short *)va->va_addr;
rap = rdp + 2;
@@ -154,35 +182,42 @@ le_vsbus_match(parent, cf, aux)
*rap = LE_CSR0;
*rdp = LE_C0_STOP;
DELAY(100);
+ *rap = LE_CSR1;
+ *rdp = map->dm_segs->ds_addr & 0xffff;
+ *rap = LE_CSR2;
+ *rdp = (map->dm_segs->ds_addr >> 16) & 0xffff;
+ *rap = LE_CSR0;
*rdp = LE_C0_INIT|LE_C0_INEA;
/* Wait for initialization to finish. */
- DELAY(100000);
- va->va_ivec = vsbus_intr; /* we do our own scb stuff */
+ for (i = 100; i >= 0; i--) {
+ DELAY(1000);
+ /* Should have interrupted by now */
+ if (*rdp & LE_C0_IDON)
+ rv = 1;
+ }
+ *rap = LE_CSR0;
+ *rdp = LE_C0_STOP;
- /* Should have interrupted by now */
- if (*rdp & LE_C0_IDON)
- return 1;
- return 0;
+ bus_dmamap_unload(va->va_dmat, map);
+ bus_dmamap_destroy(va->va_dmat, map);
+ return rv;
}
-void
+static void
le_vsbus_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct vsbus_attach_args *va = aux;
- struct le_softc *sc = (void *)self;
struct vsbus_softc *vsc = (struct vsbus_softc *)parent;
+ struct le_softc *sc = (void *)self;
bus_dma_segment_t seg;
int *lance_addr;
int i, err, rseg;
- struct lereg1 *ler1;
-
- ler1 = sc->sc_r1 = (void *)vax_map_physmem(NI_BASE, 1);
- /* Prettier printout */
- printf("\n%s", self->dv_xname);
+ sc->sc_rdp = (short *)vax_map_physmem(NI_BASE, 1);
+ sc->sc_rap = sc->sc_rdp + 2;
/*
* MD functions.
@@ -192,6 +227,7 @@ le_vsbus_attach(parent, self, aux)
sc->sc_am7990.sc_nocarrier = NULL;
scb_vecalloc(va->va_cvec, (void (*)(void *)) am7990_intr, sc, SCB_ISTACK);
+
/*
* Allocate a (DMA-safe) block for all descriptors and buffers.
*/
@@ -211,18 +247,35 @@ le_vsbus_attach(parent, self, aux)
bus_dmamem_free(va->va_dmat, &seg, rseg);
return;
}
- sc->sc_am7990.sc_addr =
- (paddr_t)sc->sc_am7990.sc_mem & 0xffffff;
- sc->sc_am7990.sc_memsize = ALLOCSIZ;
+ err = bus_dmamap_create(va->va_dmat, ALLOCSIZ, rseg, ALLOCSIZ,
+ 0, BUS_DMA_NOWAIT, &sc->sc_dm);
+ if (err) {
+ printf(": unable to create dma map: err %d\n", err);
+ bus_dmamem_free(va->va_dmat, &seg, rseg);
+ return;
+ }
+ err = bus_dmamap_load(va->va_dmat, sc->sc_dm, sc->sc_am7990.sc_mem,
+ ALLOCSIZ, NULL, BUS_DMA_NOWAIT);
+ if (err) {
+ printf(": unable to load dma map: err %d\n", err);
+ bus_dmamap_destroy(va->va_dmat, sc->sc_dm);
+ bus_dmamem_free(va->va_dmat, &seg, rseg);
+ return;
+ }
+ printf(" buf 0x%lx-0x%lx", sc->sc_dm->dm_segs->ds_addr,
+ sc->sc_dm->dm_segs->ds_addr + sc->sc_dm->dm_segs->ds_len - 1);
+ sc->sc_am7990.sc_addr = sc->sc_dm->dm_segs->ds_addr & 0xffffff;
+ sc->sc_am7990.sc_memsize = sc->sc_dm->dm_segs->ds_len;
- sc->sc_am7990.sc_conf3 = 0;
- sc->sc_am7990.sc_hwinit = NULL;
sc->sc_am7990.sc_copytodesc = am7990_copytobuf_contig;
sc->sc_am7990.sc_copyfromdesc = am7990_copyfrombuf_contig;
sc->sc_am7990.sc_copytobuf = am7990_copytobuf_contig;
sc->sc_am7990.sc_copyfrombuf = am7990_copyfrombuf_contig;
sc->sc_am7990.sc_zerobuf = am7990_zerobuf_contig;
+#ifdef LEDEBUG
+ sc->sc_am7990.sc_debug = 1;
+#endif
/*
* Get the ethernet address out of rom
*/
@@ -233,15 +286,9 @@ le_vsbus_attach(parent, self, aux)
bcopy(self->dv_xname, sc->sc_am7990.sc_arpcom.ac_if.if_xname,
IFNAMSIZ);
- am7990_config(&sc->sc_am7990);
+ /* Prettier printout */
+ printf("\n%s", self->dv_xname);
- /*
- * Register this device as boot device if we booted from it.
- * This will fail if there are more than one le in a machine,
- * fortunately there may be only one.
- */
- if (B_TYPE(bootdev) == BDEV_LE)
- booted_from = self;
-
vsc->sc_mask |= 1 << (va->va_maskno-1);
+ am7990_config(&sc->sc_am7990);
}
diff --git a/sys/arch/vax/vsa/ncr.c b/sys/arch/vax/vsa/ncr.c
index dd37716e7a0..e24baf5237b 100644
--- a/sys/arch/vax/vsa/ncr.c
+++ b/sys/arch/vax/vsa/ncr.c
@@ -1,4 +1,5 @@
-/* $NetBSD: ncr.c,v 1.26 2000/03/25 15:27:57 tsutsui Exp $ */
+/* $OpenBSD: ncr.c,v 1.7 2000/10/11 06:19:19 bjc Exp $ */
+/* $NetBSD: ncr.c,v 1.32 2000/06/25 16:00:43 ragge Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -40,9 +41,6 @@
* This file contains the machine-dependent parts of the NCR-5380
* controller. The machine-independent parts are in ncr5380sbc.c.
*
- * Note: Only PIO transfers for now which implicates very bad
- * performance. DMA support will come soon.
- *
* Jens A. Nilsson.
*
* Credits:
@@ -78,6 +76,7 @@
#include <machine/bus.h>
#include <machine/sid.h>
#include <machine/scb.h>
+#include <machine/clock.h>
#define MIN_DMA_LEN 128
@@ -103,8 +102,12 @@ struct si_softc {
bus_space_handle_t sc_regh;
struct si_dma_handle ncr_dma[SCI_OPENINGS];
+ struct vsbus_dma sc_vd;
+ int onlyscsi; /* This machine needs no queueing */
};
+static int ncr_dmasize;
+
static int si_match __P((struct device *, void *, void *));
static void si_attach __P((struct device *, struct device *, void *));
static void si_minphys __P((struct buf *));
@@ -116,6 +119,7 @@ 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 *));
+static void si_dma_go __P((void *));
#define NCR5380_READ(sc, reg) bus_space_read_1(sc->sc_regt, \
0, sc->ncr_sc.reg)
@@ -155,7 +159,8 @@ si_match(parent, cf, aux)
struct vsbus_attach_args *va = aux;
volatile char *si_csr = (char *) va->va_addr;
- if (vax_boardtype == VAX_BTYP_49)
+ if (vax_boardtype == VAX_BTYP_49 || vax_boardtype == VAX_BTYP_46
+ || vax_boardtype == VAX_BTYP_48)
return 0;
/* This is the way Linux autoprobes the interrupt MK-990321 */
si_csr[12] = 0;
@@ -175,8 +180,7 @@ si_attach(parent, self, aux)
struct vsbus_softc *vsc = (struct vsbus_softc *)parent;
struct si_softc *sc = (struct si_softc *) self;
struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
-
- printf("\n");
+ int tweak, target;
/* enable interrupts on vsbus too */
scb_vecalloc(va->va_cvec, (void (*)(void *)) ncr5380_intr, sc, SCB_ISTACK);
@@ -188,30 +192,29 @@ si_attach(parent, self, aux)
* 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 */
+ if (va->va_paddr & 0x100) { /* Secondary SCSI controller */
+ sc->ncr_off = DMASIZE;
+ sc->onlyscsi = 1;
}
+ sc->ncr_addr = (caddr_t)va->va_dmaaddr;
+ ncr_dmasize = min(va->va_dmasize, MAXPHYS);
+
+ /*
+ * 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;
@@ -224,7 +227,7 @@ si_attach(parent, self, aux)
sc->sc_regh = vax_map_physmem(va->va_paddr, 1);
/* Register offsets */
- ncr_sc->sci_r0 = (void *)sc->sc_regh;
+ ncr_sc->sci_r0 = (void *)sc->sc_regh+0;
ncr_sc->sci_r1 = (void *)sc->sc_regh+4;
ncr_sc->sci_r2 = (void *)sc->sc_regh+8;
ncr_sc->sci_r3 = (void *)sc->sc_regh+12;
@@ -235,18 +238,36 @@ si_attach(parent, self, aux)
ncr_sc->sc_no_disconnect = 0xff;
+ /*
+ * Get the SCSI chip target address out of NVRAM.
+ * This do not apply to the VS2000.
+ */
+ tweak = clk_tweak + (va->va_paddr & 0x100 ? 3 : 0);
+ if (vax_boardtype == VAX_BTYP_410)
+ target = 7;
+ else
+ target = (clk_page[0xbc/2] >> tweak) & 7;
+
+ printf("\n%s: NCR5380, SCSI ID %d\n", ncr_sc->sc_dev.dv_xname, target);
+
ncr_sc->sc_link.adapter_softc = sc;
- ncr_sc->sc_link.adapter_target = 7;
+ ncr_sc->sc_link.adapter_target = target;
ncr_sc->sc_link.adapter = &si_ops;
ncr_sc->sc_link.device = &si_dev;
ncr_sc->sc_link.openings = 4;
/*
+ * Init the vsbus DMA resource queue struct */
+ sc->sc_vd.vd_go = si_dma_go;
+ sc->sc_vd.vd_arg = sc;
+
+ /*
* Initialize si board itself.
*/
ncr5380_init(ncr_sc);
ncr5380_reset_scsibus(ncr_sc);
config_found(&(ncr_sc->sc_dev), &(ncr_sc->sc_link), scsiprint);
+
}
/*
@@ -256,10 +277,8 @@ static void
si_minphys(bp)
struct buf *bp;
{
- if ((vax_boardtype == VAX_BTYP_410) && (bp->b_bcount > (16*1024)))
- bp->b_bcount = (16*1024);
- else if (bp->b_bcount > MAXPHYS)
- bp->b_bcount = MAXPHYS;
+ if (bp->b_bcount > ncr_dmasize)
+ bp->b_bcount = ncr_dmasize;
}
void
@@ -285,7 +304,7 @@ si_dma_alloc(ncr_sc)
/* Make sure our caller checked sc_min_dma_len. */
if (xlen < MIN_DMA_LEN)
- panic("si_dma_alloc: len=0x%x\n", xlen);
+ panic("si_dma_alloc: len=0x%x", xlen);
/*
* Find free PDMA handle. Guaranteed to find one since we
@@ -296,7 +315,7 @@ si_dma_alloc(ncr_sc)
if ((sc->ncr_dma[i].dh_flags & SIDH_BUSY) == 0)
goto found;
}
- panic("sbc: no free PDMA handles");
+ panic("ncr: no free PDMA handles");
found:
dh = &sc->ncr_dma[i];
dh->dh_flags = SIDH_BUSY;
@@ -318,6 +337,14 @@ si_dma_free(ncr_sc)
struct sci_req *sr = ncr_sc->sc_current;
struct si_dma_handle *dh = sr->sr_dma_hand;
+#ifdef DIAGNOSTIC
+ if (dh == NULL)
+ panic("si_dma_free: no DMA handle");
+#endif
+
+ if (ncr_sc->sc_state & NCR_DOINGDMA)
+ panic("si_dma_free: free while DMA in progress");
+
if (dh->dh_flags & SIDH_BUSY)
dh->dh_flags = 0;
else
@@ -338,6 +365,23 @@ si_dma_start(ncr_sc)
struct ncr5380_softc *ncr_sc;
{
struct si_softc *sc = (struct si_softc *)ncr_sc;
+
+ /* Just put on queue; will call go() from below */
+ if (sc->onlyscsi)
+ si_dma_go(ncr_sc);
+ else
+ vsbus_dma_start(&sc->sc_vd);
+}
+
+/*
+ * go() routine called when another transfer somewhere is finished.
+ */
+void
+si_dma_go(arg)
+ void *arg;
+{
+ struct ncr5380_softc *ncr_sc = arg;
+ 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;
@@ -346,10 +390,7 @@ si_dma_start(ncr_sc)
* 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,
+ vsbus_copyfromproc(dh->dh_proc, dh->dh_addr,
sc->ncr_addr, dh->dh_len);
bus_space_write_1(sc->sc_regt, sc->sc_regh,
sc->ncr_dmadir, 0);
@@ -426,12 +467,8 @@ si_dma_stop(ncr_sc)
}
if (count == 0) {
if (((dh->dh_flags & SIDH_OUT) == 0)) {
- if ((vaddr_t)dh->dh_addr & KERNBASE)
- bcopy(sc->ncr_addr, dh->dh_addr, dh->dh_len);
- else
- vsbus_copytoproc(dh->dh_proc, sc->ncr_addr,
- dh->dh_addr, dh->dh_len);
-
+ vsbus_copytoproc(dh->dh_proc, sc->ncr_addr,
+ dh->dh_addr, dh->dh_len);
}
ncr_sc->sc_dataptr += dh->dh_len;
ncr_sc->sc_datalen -= dh->dh_len;
@@ -440,6 +477,8 @@ si_dma_stop(ncr_sc)
NCR5380_WRITE(sc, sci_mode, NCR5380_READ(sc, sci_mode) &
~(SCI_MODE_DMA | SCI_MODE_DMA_IE));
NCR5380_WRITE(sc, sci_icmd, 0);
+ if (sc->onlyscsi == 0)
+ vsbus_dma_intr(); /* Try to start more transfers */
}
int
diff --git a/sys/arch/vax/vsa/vsbus.c b/sys/arch/vax/vsa/vsbus.c
index d66f4ed6310..6e2df6f4a8b 100644
--- a/sys/arch/vax/vsa/vsbus.c
+++ b/sys/arch/vax/vsa/vsbus.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: vsbus.c,v 1.4 2000/04/27 00:52:07 bjc Exp $ */
-/* $NetBSD: vsbus.c,v 1.20 1999/10/22 21:10:12 ragge Exp $ */
+/* $OpenBSD: vsbus.c,v 1.5 2000/10/11 06:19:19 bjc Exp $ */
+/* $NetBSD: vsbus.c,v 1.29 2000/06/29 07:14:37 mrg Exp $ */
/*
* Copyright (c) 1996, 1999 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -49,6 +49,7 @@
#include <sys/stat.h>
#include <vm/vm.h>
+#include <vm/vm_kern.h>
#define _VAX_BUS_DMA_PRIVATE
#include <machine/bus.h>
@@ -96,6 +97,9 @@ struct vax_bus_dma_tag vsbus_bus_dma_tag = {
_bus_dmamem_mmap,
};
+extern struct vax_bus_space vax_mem_bus_space;
+static SIMPLEQ_HEAD(, vsbus_dma) vsbus_dma;
+
struct cfattach vsbus_ca = {
sizeof(struct vsbus_softc), (cfmatch_t)vsbus_match, vsbus_attach
};
@@ -141,27 +145,55 @@ vsbus_attach(parent, self, aux)
void *aux;
{
struct vsbus_softc *sc = (void *)self;
+ int dbase, dsize;
int discard;
- vaddr_t temp;
printf("\n");
+ sc->sc_dmatag = vsbus_bus_dma_tag;
+
switch (vax_boardtype) {
+#if VAX49
case VAX_BTYP_49:
- temp = vax_map_physmem(0x25c00000, 1);
- sc->sc_intreq = (char *)temp + 12;
- sc->sc_intclr = (char *)temp + 12;
- sc->sc_intmsk = (char *)temp + 8;
+ sc->sc_vsregs = vax_map_physmem(0x25c00000, 1);
+ sc->sc_intreq = (char *)sc->sc_vsregs + 12;
+ sc->sc_intclr = (char *)sc->sc_vsregs + 12;
+ sc->sc_intmsk = (char *)sc->sc_vsregs + 8;
+ vsbus_dma_init(sc, 8192);
break;
+#endif
+
+#if VAX46 || VAX48
+ case VAX_BTYP_48:
+ case VAX_BTYP_46:
+ sc->sc_vsregs = vax_map_physmem(VS_REGS, 1);
+ sc->sc_intreq = (char *)sc->sc_vsregs + 15;
+ sc->sc_intclr = (char *)sc->sc_vsregs + 15;
+ sc->sc_intmsk = (char *)sc->sc_vsregs + 12;
+ vsbus_dma_init(sc, 32768);
+#endif
+
default:
- temp = vax_map_physmem(VS_REGS, 1);
- sc->sc_intreq = (char *)temp + 15;
- sc->sc_intclr = (char *)temp + 15;
- sc->sc_intmsk = (char *)temp + 12;
+ sc->sc_vsregs = vax_map_physmem(VS_REGS, 1);
+ sc->sc_intreq = (char *)sc->sc_vsregs + 15;
+ sc->sc_intclr = (char *)sc->sc_vsregs + 15;
+ sc->sc_intmsk = (char *)sc->sc_vsregs + 12;
+ if (vax_boardtype == VAX_BTYP_410) {
+ dbase = KA410_DMA_BASE;
+ dsize = KA410_DMA_SIZE;
+ } else {
+ dbase = KA420_DMA_BASE;
+ dsize = KA420_DMA_SIZE;
+ *(char *)(sc->sc_vsregs + 0xe0) = 1; /* Big DMA */
+ }
+ sc->sc_dmasize = dsize;
+ sc->sc_dmaaddr = uvm_km_valloc(kernel_map, dsize);
+ ioaccess(sc->sc_dmaaddr, dbase, dsize/VAX_NBPG);
break;
}
+ SIMPLEQ_INIT(&vsbus_dma);
/*
* First: find which interrupts we won't care about.
* There are interrupts that interrupt on a periodic basic
@@ -196,7 +228,8 @@ vsbus_search(parent, cfd, aux)
va.va_paddr = cf->cf_loc[0];
va.va_addr = vax_map_physmem(va.va_paddr, 1);
- va.va_dmat = &vsbus_bus_dma_tag;
+ va.va_dmat = &sc->sc_dmatag;
+ va.va_iot = &vax_mem_bus_space;
*sc->sc_intmsk = 0;
*sc->sc_intclr = 0xff;
@@ -229,6 +262,8 @@ vsbus_search(parent, cfd, aux)
va.va_br = br;
va.va_cvec = vec;
va.confargs = aux;
+ va.va_dmaaddr = sc->sc_dmaaddr;
+ va.va_dmasize = sc->sc_dmasize;
config_attach(parent, cf, &va, vsbus_print);
return 1;
@@ -241,6 +276,7 @@ forgetit:
return 0;
}
+#if 0
static volatile struct dma_lock {
int dl_locked;
int dl_wanted;
@@ -288,6 +324,7 @@ vsbus_unlockDMA(ca)
}
return (0);
}
+#endif
/*
@@ -331,6 +368,10 @@ vsbus_copytoproc(p, from, to, len)
struct pte *pte;
paddr_t pa;
+ if ((long)to & KERNBASE) { /* In kernel space */
+ bcopy(from, to, len);
+ return;
+ }
pte = uvtopte(TRUNC_PAGE(to), (&p->p_addr->u_pcb));
if ((vaddr_t)to & PGOFSET) {
int cz = ROUND_PAGE(to) - (vaddr_t)to;
@@ -361,6 +402,10 @@ vsbus_copyfromproc(p, from, to, len)
struct pte *pte;
paddr_t pa;
+ if ((long)from & KERNBASE) { /* In kernel space */
+ bcopy(from, to, len);
+ return;
+ }
pte = uvtopte(TRUNC_PAGE(from), (&p->p_addr->u_pcb));
if ((vaddr_t)from & PGOFSET) {
int cz = ROUND_PAGE(from) - (vaddr_t)from;
@@ -381,3 +426,34 @@ vsbus_copyfromproc(p, from, to, len)
pte += 8; /* XXX */
}
}
+
+/*
+ * There can only be one user of the DMA area on VS2k/VS3100 at one
+ * time, so keep track of it here.
+ */
+static int vsbus_active = 0;
+
+void
+vsbus_dma_start(struct vsbus_dma *vd)
+{
+ SIMPLEQ_INSERT_TAIL(&vsbus_dma, vd, vd_q);
+
+ if (vsbus_active == 0)
+ vsbus_dma_intr();
+}
+
+void
+vsbus_dma_intr(void)
+{
+ struct vsbus_dma *vd;
+
+ vd = SIMPLEQ_FIRST(&vsbus_dma);
+ if (vd == NULL) {
+ vsbus_active = 0;
+ return;
+ }
+ vsbus_active = 1;
+ SIMPLEQ_REMOVE_HEAD(&vsbus_dma, vd, vd_q);
+ (*vd->vd_go)(vd->vd_arg);
+}
+