diff options
author | scottl <scottl@FreeBSD.org> | 2003-01-29 07:25:27 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-01-29 07:25:27 +0000 |
commit | 27cbbd88a297ee95096971d969fc28f1f2c7a09c (patch) | |
tree | d21203bdfa9f1d0c2ea53afbd752b1326d109e6c /sys/alpha | |
parent | 1bc11f23c6b4c14967b2c1745df47caa7147c66e (diff) | |
download | FreeBSD-src-27cbbd88a297ee95096971d969fc28f1f2c7a09c.zip FreeBSD-src-27cbbd88a297ee95096971d969fc28f1f2c7a09c.tar.gz |
Implement bus_dmamem_alloc_size() and bus_dmamem_free_size() as
counterparts to bus_dmamem_alloc() and bus_dmamem_free(). This allows
the caller to specify the size of the allocation instead of it defaulting
to the max_size field of the busdma tag.
This is intended to aid in converting drivers to busdma. Lots of
hardware cannot understand scatter/gather lists, which forces the
driver to copy the i/o buffers to a single contiguous region
before sending it to the hardware. Without these new methods, this
would require a new busdma tag for each operation, or a complex
internal allocator/cache for each driver.
Allocations greater than PAGE_SIZE are rounded up to the next
PAGE_SIZE by contigmalloc(), so this is not suitable for multiple
static allocations that would be better served by a single
fixed-length subdivided allocation.
Reviewed by: jake (sparc64)
Diffstat (limited to 'sys/alpha')
-rw-r--r-- | sys/alpha/alpha/busdma_machdep.c | 34 | ||||
-rw-r--r-- | sys/alpha/include/bus.h | 6 |
2 files changed, 32 insertions, 8 deletions
diff --git a/sys/alpha/alpha/busdma_machdep.c b/sys/alpha/alpha/busdma_machdep.c index 9de3342..3fcbc30 100644 --- a/sys/alpha/alpha/busdma_machdep.c +++ b/sys/alpha/alpha/busdma_machdep.c @@ -350,14 +350,18 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) * A dmamap to for use with dmamap_load is also allocated. */ int -bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, - bus_dmamap_t *mapp) +bus_dmamem_alloc_size(bus_dma_tag_t dmat, void** vaddr, int flags, + bus_dmamap_t *mapp, bus_size_t size) { + + if (size > dmat->maxsize) + return (ENOMEM); + /* If we succeed, no mapping/bouncing will be required */ *mapp = &nobounce_dmamap; - if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { - *vaddr = malloc(dmat->maxsize, M_DEVBUF, + if ((size <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { + *vaddr = malloc(size, M_DEVBUF, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : 0); } else { /* @@ -365,7 +369,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, * and handles multi-seg allocations. Nobody is doing * multi-seg allocations yet though. */ - *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, + *vaddr = contigmalloc(size, M_DEVBUF, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : 0, 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul, dmat->boundary); @@ -375,12 +379,20 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, return (0); } +int +bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, + bus_dmamap_t *mapp) +{ + return (bus_dmamem_alloc_size(dmat, vaddr, flags, mapp, dmat->maxsize)); +} + /* * Free a piece of memory and it's allociated dmamap, that was allocated * via bus_dmamem_alloc. */ void -bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) +bus_dmamem_free_size(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map, + bus_size_t size) { /* * dmamem does not need to be bounced, so the map should be @@ -388,10 +400,16 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) */ if (map != &nobounce_dmamap) panic("bus_dmamem_free: Invalid map freed\n"); - if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) + if ((size <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) free(vaddr, M_DEVBUF); else - contigfree(vaddr, dmat->maxsize, M_DEVBUF); + contigfree(vaddr, size, M_DEVBUF); +} + +void +bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) +{ + bus_dmamem_free_size(dmat, vaddr, map, dmat->maxsize); } #define BUS_DMAMAP_NSEGS ((BUS_SPACE_MAXSIZE / PAGE_SIZE) + 1) diff --git a/sys/alpha/include/bus.h b/sys/alpha/include/bus.h index 784eda3..3a87d1a 100644 --- a/sys/alpha/include/bus.h +++ b/sys/alpha/include/bus.h @@ -571,6 +571,9 @@ int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); * bus device space based on the constraints lited in the dma tag. * A dmamap to for use with dmamap_load is also allocated. */ +int bus_dmamem_alloc_size(bus_dma_tag_t dmat, void** vaddr, int flags, + bus_dmamap_t *mapp, bus_size_t size); + int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, bus_dmamap_t *mapp); @@ -578,6 +581,9 @@ int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, * Free a piece of memory and it's allociated dmamap, that was allocated * via bus_dmamem_alloc. */ +void bus_dmamem_free_size(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map, + bus_size_t size); + void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); /* |