diff options
author | gallatin <gallatin@FreeBSD.org> | 2000-06-19 18:41:27 +0000 |
---|---|---|
committer | gallatin <gallatin@FreeBSD.org> | 2000-06-19 18:41:27 +0000 |
commit | ccfeb47d98df65abb9bc01f29fb2da0a88dd4d83 (patch) | |
tree | d825e4455c867bd8bc4781e256435b6ee9942f38 | |
parent | cf9d5ec1797dcd397de2af6e7b1fbfd360baf401 (diff) | |
download | FreeBSD-src-ccfeb47d98df65abb9bc01f29fb2da0a88dd4d83.zip FreeBSD-src-ccfeb47d98df65abb9bc01f29fb2da0a88dd4d83.tar.gz |
Support bounce buffers for ISA DMA on the alpha. This is required for the
irongate chipset (used in the UP1000) which does not support scatter/gather
DMA. We'll still use scatter gather if the core logic chipset supports it.
Reviewed by: dfr
-rw-r--r-- | sys/alpha/alpha/busdma_machdep.c | 16 | ||||
-rw-r--r-- | sys/alpha/alpha/vm_machdep.c | 2 | ||||
-rw-r--r-- | sys/alpha/include/md_var.h | 1 | ||||
-rw-r--r-- | sys/alpha/isa/isa_dma.c | 31 | ||||
-rw-r--r-- | sys/powerpc/aim/vm_machdep.c | 2 | ||||
-rw-r--r-- | sys/powerpc/include/md_var.h | 1 | ||||
-rw-r--r-- | sys/powerpc/powerpc/vm_machdep.c | 2 |
7 files changed, 39 insertions, 16 deletions
diff --git a/sys/alpha/alpha/busdma_machdep.c b/sys/alpha/alpha/busdma_machdep.c index d01433b..aa92602 100644 --- a/sys/alpha/alpha/busdma_machdep.c +++ b/sys/alpha/alpha/busdma_machdep.c @@ -240,7 +240,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) error = 0; - if (dmat->flags & BUS_DMA_ISA) { + if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) { bus_dmamap_t map; map = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF, M_NOWAIT); @@ -290,10 +290,12 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) panic("bus_dmamap_create: page reallocation " "not implemented"); } - pages = atop(dmat->maxsize); + pages = atop(dmat->maxsize) + 1; pages = MIN(maxpages - total_bpages, pages); - error = alloc_bounce_pages(dmat, pages); + if (alloc_bounce_pages(dmat, pages) < pages) + error = ENOMEM; + if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) { if (error == 0) dmat->flags |= BUS_DMA_MIN_ALLOC_COMP; @@ -316,7 +318,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) { - if (dmat->flags & BUS_DMA_ISA) { + if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) { sgmap_free_region(chipset.sgmap, map->sgmaphandle); } @@ -404,7 +406,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, error = 0; - if (dmat->flags & BUS_DMA_ISA) { + if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) { /* * For ISA dma, we use the chipset's scatter-gather * map to map the tranfer into the ISA reachable range @@ -529,7 +531,7 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) { struct bounce_page *bpage; - if (dmat->flags & BUS_DMA_ISA) { + if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) { sgmap_unload_region(chipset.sgmap, map->busaddress, map->buflen); @@ -606,7 +608,7 @@ alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) M_NOWAIT, 0ul, dmat->lowaddr, PAGE_SIZE, - 0); + dmat->boundary); if (bpage->vaddr == NULL) { free(bpage, M_DEVBUF); break; diff --git a/sys/alpha/alpha/vm_machdep.c b/sys/alpha/alpha/vm_machdep.c index 68bbf29..8baea02 100644 --- a/sys/alpha/alpha/vm_machdep.c +++ b/sys/alpha/alpha/vm_machdep.c @@ -462,10 +462,8 @@ vm_page_zero_idle() void swi_vm() { -#if 0 if (busdma_swi_pending != 0) busdma_swi(); -#endif } /* diff --git a/sys/alpha/include/md_var.h b/sys/alpha/include/md_var.h index 4595c8a..740d40b 100644 --- a/sys/alpha/include/md_var.h +++ b/sys/alpha/include/md_var.h @@ -37,6 +37,7 @@ extern char sigcode[]; extern char esigcode[]; extern int szsigcode; extern int Maxmem; +extern int busdma_swi_pending; extern void (*netisrs[32]) __P((void)); struct fpreg; diff --git a/sys/alpha/isa/isa_dma.c b/sys/alpha/isa/isa_dma.c index 8b5e64b..5864c7a 100644 --- a/sys/alpha/isa/isa_dma.c +++ b/sys/alpha/isa/isa_dma.c @@ -83,6 +83,7 @@ static bus_dmamap_t dma_map[8]; static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */ static u_int8_t dma_inuse = 0; /* User for acquire/release */ static u_int8_t dma_auto_mode = 0; +static u_int8_t dma_bounced = 0; #define VALID_DMA_MASK (7) @@ -105,6 +106,7 @@ isa_dmainit(chan, bouncebufsize) * Reset the DMA hardware. */ outb(DMA1_RESET, 0); + outb((IO_DMA1 + 1*14), 0); outb(DMA2_RESET, 0); isa_dmacascade(4); @@ -122,7 +124,7 @@ isa_dmainit(chan, bouncebufsize) if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/boundary, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, + /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/bouncebufsize, @@ -219,13 +221,15 @@ isa_dmacascade(chan) */ struct isa_dmastart_arg { - int chan; - int flags; + caddr_t addr; + int chan; + int flags; }; static void isa_dmastart_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { + caddr_t addr = ((struct isa_dmastart_arg *) arg)->addr; int chan = ((struct isa_dmastart_arg *) arg)->chan; int flags = ((struct isa_dmastart_arg *) arg)->flags; bus_addr_t phys = segs->ds_addr; @@ -235,6 +239,17 @@ static void isa_dmastart_cb(void *arg, bus_dma_segment_t *segs, int nseg, if (nseg != 1) panic("isa_dmastart: transfer mapping not contiguous"); + if ((chipset.sgmap == NULL) && + (pmap_extract(pmap_kernel(), (vm_offset_t)addr) + > BUS_SPACE_MAXADDR_24BIT)) { + /* we bounced */ + dma_bounced |= (1 << chan); + /* copy bounce buffer on write */ + if (!(flags & ISADMA_READ)) + bus_dmamap_sync(dma_tag[chan], dma_map[chan], + BUS_DMASYNC_PREWRITE); + } + if ((chan & 4) == 0) { /* * Program one of DMA channels 0..3. These are @@ -348,6 +363,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) */ outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4); + args.addr = addr; args.chan = chan; args.flags = flags; bus_dmamap_load(dma_tag[chan], dma_map[chan], addr, nbytes, @@ -369,6 +385,15 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) (dma_auto_mode & (1 << chan)) == 0 ) printf("isa_dmadone: channel %d not busy\n", chan); + if (dma_bounced & (1 << chan)) { + /* copy bounce buffer on read */ + if (flags & ISADMA_READ) { + bus_dmamap_sync(dma_tag[chan], dma_map[chan], + BUS_DMASYNC_POSTREAD); + } + dma_bounced &= ~(1 << chan); + } + if ((dma_auto_mode & (1 << chan)) == 0) { outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4); bus_dmamap_unload(dma_tag[chan], dma_map[chan]); diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 68bbf29..8baea02 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -462,10 +462,8 @@ vm_page_zero_idle() void swi_vm() { -#if 0 if (busdma_swi_pending != 0) busdma_swi(); -#endif } /* diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h index 4595c8a..740d40b 100644 --- a/sys/powerpc/include/md_var.h +++ b/sys/powerpc/include/md_var.h @@ -37,6 +37,7 @@ extern char sigcode[]; extern char esigcode[]; extern int szsigcode; extern int Maxmem; +extern int busdma_swi_pending; extern void (*netisrs[32]) __P((void)); struct fpreg; diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index 68bbf29..8baea02 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -462,10 +462,8 @@ vm_page_zero_idle() void swi_vm() { -#if 0 if (busdma_swi_pending != 0) busdma_swi(); -#endif } /* |