diff options
author | Brandon Creighton <bjc@cvs.openbsd.org> | 2000-10-11 06:19:20 +0000 |
---|---|---|
committer | Brandon Creighton <bjc@cvs.openbsd.org> | 2000-10-11 06:19:20 +0000 |
commit | 60d99b8926b833934cb89683b494bd5532cda34c (patch) | |
tree | 9aefbaeb01ad703be976076e0e1f6afccf36b0d5 /sys | |
parent | c8c7b1e8c05502e0acc9522f787ed04f8dd51be9 (diff) |
update these to work with cleaner vsbus dma; from netbsd
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/vax/vsa/if_le_vsbus.c | 139 | ||||
-rw-r--r-- | sys/arch/vax/vsa/ncr.c | 135 | ||||
-rw-r--r-- | sys/arch/vax/vsa/vsbus.c | 100 |
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); +} + |