summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/pci/psycho.c
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/sparc64/pci/psycho.c
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/sparc64/pci/psycho.c')
-rw-r--r--sys/sparc64/pci/psycho.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 9b32b95..418b81c 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -113,8 +113,12 @@ static int psycho_dmamap_load_uio(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
static void psycho_dmamap_unload(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
static void psycho_dmamap_sync(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
bus_dmasync_op_t);
+static int psycho_dmamem_alloc_size(bus_dma_tag_t, bus_dma_tag_t, void **, int,
+ bus_dmamap_t *, bus_size_t size);
static int psycho_dmamem_alloc(bus_dma_tag_t, bus_dma_tag_t, void **, int,
bus_dmamap_t *);
+static void psycho_dmamem_free_size(bus_dma_tag_t, bus_dma_tag_t, void *,
+ bus_dmamap_t, bus_size_t size);
static void psycho_dmamem_free(bus_dma_tag_t, bus_dma_tag_t, void *,
bus_dmamap_t);
@@ -497,7 +501,9 @@ psycho_attach(device_t dev)
sc->sc_dmat->dt_dmamap_load_uio = psycho_dmamap_load_uio;
sc->sc_dmat->dt_dmamap_unload = psycho_dmamap_unload;
sc->sc_dmat->dt_dmamap_sync = psycho_dmamap_sync;
+ sc->sc_dmat->dt_dmamem_alloc_size = psycho_dmamem_alloc_size;
sc->sc_dmat->dt_dmamem_alloc = psycho_dmamem_alloc;
+ sc->sc_dmat->dt_dmamem_free_size = psycho_dmamem_free_size;
sc->sc_dmat->dt_dmamem_free = psycho_dmamem_free;
/* XXX: register as root dma tag (kluge). */
sparc64_root_dma_tag = sc->sc_dmat;
@@ -1314,6 +1320,17 @@ psycho_alloc_bus_tag(struct psycho_softc *sc, int type)
* hooks into the iommu dvma calls.
*/
static int
+psycho_dmamem_alloc_size(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void **vaddr,
+ int flags, bus_dmamap_t *mapp, bus_size_t size)
+{
+ struct psycho_softc *sc;
+
+ sc = (struct psycho_softc *)pdmat->cookie;
+ return (iommu_dvmamem_alloc_size(pdmat, ddmat, sc->sc_is, vaddr, flags,
+ mapp, size));
+}
+
+static int
psycho_dmamem_alloc(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void **vaddr,
int flags, bus_dmamap_t *mapp)
{
@@ -1325,6 +1342,16 @@ psycho_dmamem_alloc(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void **vaddr,
}
static void
+psycho_dmamem_free_size(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void *vaddr,
+ bus_dmamap_t map, bus_size_t size)
+{
+ struct psycho_softc *sc;
+
+ sc = (struct psycho_softc *)pdmat->cookie;
+ iommu_dvmamem_free_size(pdmat, ddmat, sc->sc_is, vaddr, map, size);
+}
+
+static void
psycho_dmamem_free(bus_dma_tag_t pdmat, bus_dma_tag_t ddmat, void *vaddr,
bus_dmamap_t map)
{
OpenPOWER on IntegriCloud