summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2003-01-29 07:25:27 +0000
committerscottl <scottl@FreeBSD.org>2003-01-29 07:25:27 +0000
commit27cbbd88a297ee95096971d969fc28f1f2c7a09c (patch)
treed21203bdfa9f1d0c2ea53afbd752b1326d109e6c /sys/alpha
parent1bc11f23c6b4c14967b2c1745df47caa7147c66e (diff)
downloadFreeBSD-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.c34
-rw-r--r--sys/alpha/include/bus.h6
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);
/*
OpenPOWER on IntegriCloud