Module Name: src Committed By: matt Date: Tue Sep 18 05:47:28 UTC 2012
Modified Files: src/sys/arch/arm/arm32: bus_dma.c src/sys/arch/arm/at91: at91_bus_dma.c src/sys/arch/arm/broadcom: bcm2835_dma.c bcm53xx_board.c src/sys/arch/arm/ep93xx: ep93xx_busdma.c src/sys/arch/arm/footbridge: footbridge_pci.c src/sys/arch/arm/gemini: gemini_dma.c src/sys/arch/arm/imx: imx_dma.c src/sys/arch/arm/include: bus_defs.h bus_funcs.h src/sys/arch/arm/ixp12x0: ixp12x0_pci_dma.c src/sys/arch/arm/marvell: mvsoc_dma.c src/sys/arch/arm/omap: omap_dma.c src/sys/arch/arm/s3c2xx0: s3c2xx0_busdma.c src/sys/arch/arm/xscale: becc.c i80312.c i80321.c ixp425_ixme.c ixp425_pci_dma.c pxa2x0_dma.c Log Message: Add bounce buffer support for ARM bus_dma(9). Add macros to help initialize bus_dma_tag structures. To generate a diff of this commit: cvs rdiff -u -r1.57 -r1.58 src/sys/arch/arm/arm32/bus_dma.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/at91/at91_bus_dma.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/broadcom/bcm2835_dma.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/broadcom/bcm53xx_board.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/ep93xx/ep93xx_busdma.c cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/footbridge/footbridge_pci.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/gemini/gemini_dma.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/imx_dma.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/include/bus_defs.h cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/include/bus_funcs.h cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/ixp12x0/ixp12x0_pci_dma.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/marvell/mvsoc_dma.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/omap/omap_dma.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/s3c2xx0/s3c2xx0_busdma.c cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/xscale/becc.c cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/xscale/i80312.c cvs rdiff -u -r1.23 -r1.24 src/sys/arch/arm/xscale/i80321.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/xscale/ixp425_ixme.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/xscale/ixp425_pci_dma.c \ src/sys/arch/arm/xscale/pxa2x0_dma.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm32/bus_dma.c diff -u src/sys/arch/arm/arm32/bus_dma.c:1.57 src/sys/arch/arm/arm32/bus_dma.c:1.58 --- src/sys/arch/arm/arm32/bus_dma.c:1.57 Tue Sep 11 17:54:12 2012 +++ src/sys/arch/arm/arm32/bus_dma.c Tue Sep 18 05:47:26 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma.c,v 1.57 2012/09/11 17:54:12 matt Exp $ */ +/* $NetBSD: bus_dma.c,v 1.58 2012/09/18 05:47:26 matt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #define _ARM32_BUS_DMA_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.57 2012/09/11 17:54:12 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.58 2012/09/18 05:47:26 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -55,10 +55,44 @@ __KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v #include <arm/cpufunc.h> +static struct evcnt bus_dma_creates = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "creates"); +static struct evcnt bus_dma_bounced_creates = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "bounced creates"); +static struct evcnt bus_dma_loads = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "loads"); +static struct evcnt bus_dma_bounced_loads = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "bounced loads"); +static struct evcnt bus_dma_read_bounces = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "read bounces"); +static struct evcnt bus_dma_write_bounces = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "write bounces"); +static struct evcnt bus_dma_bounced_unloads = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "bounced unloads"); +static struct evcnt bus_dma_unloads = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "unloads"); +static struct evcnt bus_dma_bounced_destroys = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "bounced destroys"); +static struct evcnt bus_dma_destroys = + EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "busdma", "destroys"); + +EVCNT_ATTACH_STATIC(bus_dma_creates); +EVCNT_ATTACH_STATIC(bus_dma_bounced_creates); +EVCNT_ATTACH_STATIC(bus_dma_loads); +EVCNT_ATTACH_STATIC(bus_dma_bounced_loads); +EVCNT_ATTACH_STATIC(bus_dma_read_bounces); +EVCNT_ATTACH_STATIC(bus_dma_write_bounces); +EVCNT_ATTACH_STATIC(bus_dma_unloads); +EVCNT_ATTACH_STATIC(bus_dma_bounced_unloads); +EVCNT_ATTACH_STATIC(bus_dma_destroys); +EVCNT_ATTACH_STATIC(bus_dma_bounced_destroys); + +#define STAT_INCR(x) (bus_dma_ ## x.ev_count++) + int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, struct vmspace *, int); -struct arm32_dma_range *_bus_dma_inrange(struct arm32_dma_range *, - int, bus_addr_t); +static struct arm32_dma_range * + _bus_dma_inrange(struct arm32_dma_range *, int, bus_addr_t); /* * Check to see if the specified page is in an allowed DMA range. @@ -89,13 +123,16 @@ _bus_dmamap_load_paddr(bus_dma_tag_t t, { bus_dma_segment_t * const segs = map->dm_segs; int nseg = map->dm_nsegs; - bus_addr_t lastaddr = 0xdead; /* XXX gcc */ + bus_addr_t lastaddr; bus_addr_t bmask = ~(map->_dm_boundary - 1); bus_addr_t curaddr; bus_size_t sgsize; if (nseg > 0) lastaddr = segs[nseg-1].ds_addr + segs[nseg-1].ds_len; + else + lastaddr = 0xdead; + again: sgsize = size; @@ -156,6 +193,55 @@ _bus_dmamap_load_paddr(bus_dma_tag_t t, return (0); } +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE +static int _bus_dma_alloc_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map, + bus_size_t size, int flags); +static void _bus_dma_free_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map); +static int _bus_dma_uiomove(void *buf, struct uio *uio, size_t n, + int direction); + +static int +_bus_dma_load_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map, void *buf, + size_t buflen, int buftype, int flags) +{ + struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; + struct vmspace * const vm = vmspace_kernel(); + int error; + + KASSERT(cookie != NULL); + KASSERT(cookie->id_flags & _BUS_DMA_MIGHT_NEED_BOUNCE); + + /* + * Allocate bounce pages, if necessary. + */ + if ((cookie->id_flags & _BUS_DMA_HAS_BOUNCE) == 0) { + error = _bus_dma_alloc_bouncebuf(t, map, buflen, flags); + if (error) + return (error); + } + + /* + * Cache a pointer to the caller's buffer and load the DMA map + * with the bounce buffer. + */ + cookie->id_origbuf = buf; + cookie->id_origbuflen = buflen; + error = _bus_dmamap_load_buffer(t, map, cookie->id_bouncebuf, + buflen, vm, flags); + if (error) + return (error); + + STAT_INCR(bounced_loads); + map->dm_mapsize = buflen; + map->_dm_vmspace = vm; + map->_dm_buftype = buftype; + + /* ...so _bus_dmamap_sync() knows we're bouncing */ + cookie->id_flags |= _BUS_DMA_IS_BOUNCING; + return 0; +} +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ + /* * Common function for DMA map creation. May be called by bus-specific * DMA map creation functions. @@ -187,11 +273,10 @@ _bus_dmamap_create(bus_dma_tag_t t, bus_ */ mapsize = sizeof(struct arm32_bus_dmamap) + (sizeof(bus_dma_segment_t) * (nsegments - 1)); - if ((mapstore = malloc(mapsize, M_DMAMAP, - (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) + const int mallocflags = M_ZERO|(flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK; + if ((mapstore = malloc(mapsize, M_DMAMAP, mallocflags)) == NULL) return (ENOMEM); - memset(mapstore, 0, mapsize); map = (struct arm32_bus_dmamap *)mapstore; map->_dm_size = size; map->_dm_segcnt = nsegments; @@ -199,13 +284,61 @@ _bus_dmamap_create(bus_dma_tag_t t, bus_ map->_dm_boundary = boundary; map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT); map->_dm_origbuf = NULL; - map->_dm_buftype = ARM32_BUFTYPE_INVALID; + map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID; map->_dm_vmspace = vmspace_kernel(); + map->_dm_cookie = NULL; map->dm_maxsegsz = maxsegsz; map->dm_mapsize = 0; /* no valid mappings */ map->dm_nsegs = 0; *dmamp = map; + +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie *cookie; + int cookieflags; + void *cookiestore; + size_t cookiesize; + int error; + + cookieflags = 0; + + if (t->_may_bounce != NULL) { + error = (*t->_may_bounce)(t, map, flags, &cookieflags); + if (error != 0) + goto out; + } + + if (t->_ranges != NULL) + cookieflags |= _BUS_DMA_MIGHT_NEED_BOUNCE; + + if ((cookieflags & _BUS_DMA_MIGHT_NEED_BOUNCE) == 0) { + STAT_INCR(creates); + return 0; + } + + cookiesize = sizeof(struct arm32_bus_dma_cookie) + + (sizeof(bus_dma_segment_t) * map->_dm_segcnt); + + /* + * Allocate our cookie. + */ + if ((cookiestore = malloc(cookiesize, M_DMAMAP, mallocflags)) == NULL) { + error = ENOMEM; + goto out; + } + cookie = (struct arm32_bus_dma_cookie *)cookiestore; + cookie->id_flags = cookieflags; + map->_dm_cookie = cookie; + STAT_INCR(bounced_creates); + + error = _bus_dma_alloc_bouncebuf(t, map, size, flags); + out: + if (error) + _bus_dmamap_destroy(t, map); +#else + STAT_INCR(creates); +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ + #ifdef DEBUG_DMA printf("dmamap_create:map=%p\n", map); #endif /* DEBUG_DMA */ @@ -223,16 +356,26 @@ _bus_dmamap_destroy(bus_dma_tag_t t, bus #ifdef DEBUG_DMA printf("dmamap_destroy: t=%p map=%p\n", t, map); #endif /* DEBUG_DMA */ +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie *cookie = map->_dm_cookie; /* - * Explicit unload. + * Free any bounce pages this map might hold. */ - map->dm_maxsegsz = map->_dm_maxmaxsegsz; - map->dm_mapsize = 0; - map->dm_nsegs = 0; - map->_dm_origbuf = NULL; - map->_dm_buftype = ARM32_BUFTYPE_INVALID; - map->_dm_vmspace = NULL; + if (cookie != NULL) { + if (cookie->id_flags & _BUS_DMA_IS_BOUNCING) + STAT_INCR(bounced_unloads); + map->dm_nsegs = 0; + if (cookie->id_flags & _BUS_DMA_HAS_BOUNCE) + _bus_dma_free_bouncebuf(t, map); + STAT_INCR(bounced_destroys); + free(cookie, M_DMAMAP); + } else +#endif + STAT_INCR(destroys); + + if (map->dm_nsegs > 0) + STAT_INCR(unloads); free(map, M_DMAMAP); } @@ -245,19 +388,33 @@ int _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags) { - int error; struct vmspace *vm; + int error; #ifdef DEBUG_DMA printf("dmamap_load: t=%p map=%p buf=%p len=%lx p=%p f=%d\n", t, map, buf, buflen, p, flags); #endif /* DEBUG_DMA */ + if (map->dm_nsegs > 0) { +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie *cookie = map->_dm_cookie; + if (cookie != NULL) { + if (cookie->id_flags & _BUS_DMA_IS_BOUNCING) { + STAT_INCR(bounced_unloads); + cookie->id_flags &= ~_BUS_DMA_IS_BOUNCING; + } + } else +#endif + STAT_INCR(unloads); + } + /* * Make sure that on error condition we return "no valid mappings". */ map->dm_mapsize = 0; map->dm_nsegs = 0; + map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID; KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); if (buflen > map->_dm_size) @@ -270,18 +427,23 @@ _bus_dmamap_load(bus_dma_tag_t t, bus_dm } /* _bus_dmamap_load_buffer() clears this if we're not... */ - map->_dm_flags |= ARM32_DMAMAP_COHERENT; + map->_dm_flags |= _BUS_DMAMAP_COHERENT; error = _bus_dmamap_load_buffer(t, map, buf, buflen, vm, flags); if (error == 0) { map->dm_mapsize = buflen; - map->_dm_origbuf = buf; - map->_dm_buftype = ARM32_BUFTYPE_LINEAR; map->_dm_vmspace = vm; + map->_dm_origbuf = buf; + map->_dm_buftype = _BUS_DMA_BUFTYPE_LINEAR; + return 0; } -#ifdef DEBUG_DMA - printf("dmamap_load: error=%d\n", error); -#endif /* DEBUG_DMA */ +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; + if (cookie != NULL && (cookie->id_flags & _BUS_DMA_MIGHT_NEED_BOUNCE)) { + error = _bus_dma_load_bouncebuf(t, map, buf, buflen, + _BUS_DMA_BUFTYPE_LINEAR, flags); + } +#endif return (error); } @@ -300,11 +462,25 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, b t, map, m0, flags); #endif /* DEBUG_DMA */ + if (map->dm_nsegs > 0) { +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie *cookie = map->_dm_cookie; + if (cookie != NULL) { + if (cookie->id_flags & _BUS_DMA_IS_BOUNCING) { + STAT_INCR(bounced_unloads); + cookie->id_flags &= ~_BUS_DMA_IS_BOUNCING; + } + } else +#endif + STAT_INCR(unloads); + } + /* * Make sure that on error condition we return "no valid mappings." */ map->dm_mapsize = 0; map->dm_nsegs = 0; + map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID; KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); #ifdef DIAGNOSTIC @@ -319,7 +495,7 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, b * Mbuf chains should almost never have coherent (i.e. * un-cached) mappings, so clear that flag now. */ - map->_dm_flags &= ~ARM32_DMAMAP_COHERENT; + map->_dm_flags &= ~_BUS_DMAMAP_COHERENT; error = 0; for (m = m0; m != NULL && error == 0; m = m->m_next) { @@ -397,12 +573,17 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, b if (error == 0) { map->dm_mapsize = m0->m_pkthdr.len; map->_dm_origbuf = m0; - map->_dm_buftype = ARM32_BUFTYPE_MBUF; + map->_dm_buftype = _BUS_DMA_BUFTYPE_MBUF; map->_dm_vmspace = vmspace_kernel(); /* always kernel */ + return 0; } -#ifdef DEBUG_DMA - printf("dmamap_load_mbuf: error=%d\n", error); -#endif /* DEBUG_DMA */ +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; + if (cookie != NULL && (cookie->id_flags & _BUS_DMA_MIGHT_NEED_BOUNCE)) { + error = _bus_dma_load_bouncebuf(t, map, m0, m0->m_pkthdr.len, + _BUS_DMA_BUFTYPE_MBUF, flags); + } +#endif return (error); } @@ -429,7 +610,7 @@ _bus_dmamap_load_uio(bus_dma_tag_t t, bu iov = uio->uio_iov; /* _bus_dmamap_load_buffer() clears this if we're not... */ - map->_dm_flags |= ARM32_DMAMAP_COHERENT; + map->_dm_flags |= _BUS_DMAMAP_COHERENT; error = 0; for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) { @@ -448,7 +629,7 @@ _bus_dmamap_load_uio(bus_dma_tag_t t, bu if (error == 0) { map->dm_mapsize = uio->uio_resid; map->_dm_origbuf = uio; - map->_dm_buftype = ARM32_BUFTYPE_UIO; + map->_dm_buftype = _BUS_DMA_BUFTYPE_UIO; map->_dm_vmspace = uio->uio_vmspace; } return (error); @@ -485,7 +666,7 @@ _bus_dmamap_unload(bus_dma_tag_t t, bus_ map->dm_mapsize = 0; map->dm_nsegs = 0; map->_dm_origbuf = NULL; - map->_dm_buftype = ARM32_BUFTYPE_INVALID; + map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID; map->_dm_vmspace = NULL; } @@ -540,8 +721,17 @@ static inline void _bus_dmamap_sync_linear(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, bus_size_t len, int ops) { +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; + bool bouncing = (cookie != NULL && (cookie->id_flags & _BUS_DMA_IS_BOUNCING)); +#endif bus_dma_segment_t *ds = map->dm_segs; vaddr_t va = (vaddr_t) map->_dm_origbuf; +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + if (bouncing) { + va = (vaddr_t) cookie->id_bouncebuf; + } +#endif while (len > 0) { while (offset >= ds->ds_len) { @@ -668,6 +858,7 @@ void _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, bus_size_t len, int ops) { + bool bouncing = false; #ifdef DEBUG_DMA printf("dmamap_sync: t=%p map=%p offset=%lx len=%lx ops=%x\n", @@ -704,18 +895,63 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm * * POSTWRITE -- Nothing. */ +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; + bouncing = (cookie != NULL && (cookie->id_flags & _BUS_DMA_IS_BOUNCING)); +#endif - ops &= (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - if (ops == 0) + const int pre_ops = ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + if (!bouncing && pre_ops == 0) return; +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + if (bouncing && (ops & BUS_DMASYNC_PREWRITE)) { + STAT_INCR(write_bounces); + char * const dataptr = (char *)cookie->id_bouncebuf + offset; + /* + * Copy the caller's buffer to the bounce buffer. + */ + switch (map->_dm_buftype) { + case _BUS_DMA_BUFTYPE_LINEAR: + memcpy(dataptr, cookie->id_origlinearbuf + offset, len); + break; + case _BUS_DMA_BUFTYPE_MBUF: + m_copydata(cookie->id_origmbuf, offset, len, dataptr); + break; + case _BUS_DMA_BUFTYPE_UIO: + _bus_dma_uiomove(dataptr, cookie->id_origuio, len, UIO_WRITE); + break; +#ifdef DIAGNOSTIC + case _BUS_DMA_BUFTYPE_RAW: + panic("_bus_dmamap_sync(pre): _BUS_DMA_BUFTYPE_RAW"); + break; + + case _BUS_DMA_BUFTYPE_INVALID: + panic("_bus_dmamap_sync(pre): _BUS_DMA_BUFTYPE_INVALID"); + break; + + default: + panic("_bus_dmamap_sync(pre): map %p: unknown buffer type %d\n", + map, map->_dm_buftype); + break; +#endif /* DIAGNOSTIC */ + } + } +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ + /* Skip cache frobbing if mapping was COHERENT. */ - if (map->_dm_flags & ARM32_DMAMAP_COHERENT) { + if (!bouncing && (map->_dm_flags & _BUS_DMAMAP_COHERENT)) { /* Drain the write buffer. */ cpu_drain_writebuf(); return; } +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + if (bouncing && ((map->_dm_flags & _BUS_DMAMAP_COHERENT) || pre_ops == 0)) { + goto bounce_it; + } +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ + /* * If the mapping belongs to a non-kernel vmspace, and the * vmspace has not been active since the last time a full @@ -725,34 +961,82 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm vm_map_pmap(&map->_dm_vmspace->vm_map)->pm_cstate.cs_cache_d == 0)) return; - switch (map->_dm_buftype) { - case ARM32_BUFTYPE_LINEAR: + int buftype = map->_dm_buftype; +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + if (bouncing) { + buftype = _BUS_DMA_BUFTYPE_LINEAR; + } +#endif + + switch (buftype) { + case _BUS_DMA_BUFTYPE_LINEAR: _bus_dmamap_sync_linear(t, map, offset, len, ops); break; - case ARM32_BUFTYPE_MBUF: + case _BUS_DMA_BUFTYPE_MBUF: _bus_dmamap_sync_mbuf(t, map, offset, len, ops); break; - case ARM32_BUFTYPE_UIO: + case _BUS_DMA_BUFTYPE_UIO: _bus_dmamap_sync_uio(t, map, offset, len, ops); break; - case ARM32_BUFTYPE_RAW: - panic("_bus_dmamap_sync: ARM32_BUFTYPE_RAW"); + case _BUS_DMA_BUFTYPE_RAW: + panic("_bus_dmamap_sync: _BUS_DMA_BUFTYPE_RAW"); break; - case ARM32_BUFTYPE_INVALID: - panic("_bus_dmamap_sync: ARM32_BUFTYPE_INVALID"); + case _BUS_DMA_BUFTYPE_INVALID: + panic("_bus_dmamap_sync: _BUS_DMA_BUFTYPE_INVALID"); break; default: - printf("unknown buffer type %d\n", map->_dm_buftype); - panic("_bus_dmamap_sync"); + panic("_bus_dmamap_sync: map %p: unknown buffer type %d\n", + map, map->_dm_buftype); } /* Drain the write buffer. */ cpu_drain_writebuf(); + +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + bounce_it: + if ((ops & BUS_DMASYNC_POSTREAD) == 0 + || cookie == NULL + || (cookie->id_flags & _BUS_DMA_IS_BOUNCING) == 0) + return; + + char * const dataptr = (char *)cookie->id_bouncebuf + offset; + STAT_INCR(read_bounces); + /* + * Copy the bounce buffer to the caller's buffer. + */ + switch (map->_dm_buftype) { + case _BUS_DMA_BUFTYPE_LINEAR: + memcpy(cookie->id_origlinearbuf + offset, dataptr, len); + break; + + case _BUS_DMA_BUFTYPE_MBUF: + m_copyback(cookie->id_origmbuf, offset, len, dataptr); + break; + + case _BUS_DMA_BUFTYPE_UIO: + _bus_dma_uiomove(dataptr, cookie->id_origuio, len, UIO_READ); + break; +#ifdef DIAGNOSTIC + case _BUS_DMA_BUFTYPE_RAW: + panic("_bus_dmamap_sync(post): _BUS_DMA_BUFTYPE_RAW"); + break; + + case _BUS_DMA_BUFTYPE_INVALID: + panic("_bus_dmamap_sync(post): _BUS_DMA_BUFTYPE_INVALID"); + break; + + default: + panic("_bus_dmamap_sync(post): map %p: unknown buffer type %d\n", + map, map->_dm_buftype); + break; +#endif + } +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ } /* @@ -1009,7 +1293,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, #endif curaddr = (*pde & s_frame) | (vaddr & s_offset); if (*pde & L1_S_CACHE_MASK) { - map->_dm_flags &= ~ARM32_DMAMAP_COHERENT; + map->_dm_flags &= ~_BUS_DMAMAP_COHERENT; } } else { pte = *ptep; @@ -1020,20 +1304,20 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, (vaddr & L2_L_OFFSET); if (pte & L2_L_CACHE_MASK) { map->_dm_flags &= - ~ARM32_DMAMAP_COHERENT; + ~_BUS_DMAMAP_COHERENT; } } else { curaddr = (pte & L2_S_FRAME) | (vaddr & L2_S_OFFSET); if (pte & L2_S_CACHE_MASK) { map->_dm_flags &= - ~ARM32_DMAMAP_COHERENT; + ~_BUS_DMAMAP_COHERENT; } } } } else { (void) pmap_extract(pmap, vaddr, &curaddr); - map->_dm_flags &= ~ARM32_DMAMAP_COHERENT; + map->_dm_flags &= ~_BUS_DMAMAP_COHERENT; } /* @@ -1163,3 +1447,189 @@ arm32_dma_range_intersect(struct arm32_d /* No intersection found. */ return (0); } + +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE +static int +_bus_dma_alloc_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map, + bus_size_t size, int flags) +{ + struct arm32_bus_dma_cookie *cookie = map->_dm_cookie; + int error = 0; + +#ifdef DIAGNOSTIC + if (cookie == NULL) + panic("_bus_dma_alloc_bouncebuf: no cookie"); +#endif + + cookie->id_bouncebuflen = round_page(size); + error = _bus_dmamem_alloc(t, cookie->id_bouncebuflen, + PAGE_SIZE, map->_dm_boundary, cookie->id_bouncesegs, + map->_dm_segcnt, &cookie->id_nbouncesegs, flags); + if (error) + goto out; + error = _bus_dmamem_map(t, cookie->id_bouncesegs, + cookie->id_nbouncesegs, cookie->id_bouncebuflen, + (void **)&cookie->id_bouncebuf, flags); + + out: + if (error) { + _bus_dmamem_free(t, cookie->id_bouncesegs, + cookie->id_nbouncesegs); + cookie->id_bouncebuflen = 0; + cookie->id_nbouncesegs = 0; + } else { + cookie->id_flags |= _BUS_DMA_HAS_BOUNCE; + } + + return (error); +} + +static void +_bus_dma_free_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map) +{ + struct arm32_bus_dma_cookie *cookie = map->_dm_cookie; + +#ifdef DIAGNOSTIC + if (cookie == NULL) + panic("_bus_dma_alloc_bouncebuf: no cookie"); +#endif + + _bus_dmamem_unmap(t, cookie->id_bouncebuf, cookie->id_bouncebuflen); + _bus_dmamem_free(t, cookie->id_bouncesegs, + cookie->id_nbouncesegs); + cookie->id_bouncebuflen = 0; + cookie->id_nbouncesegs = 0; + cookie->id_flags &= ~_BUS_DMA_HAS_BOUNCE; +} + +/* + * This function does the same as uiomove, but takes an explicit + * direction, and does not update the uio structure. + */ +static int +_bus_dma_uiomove(void *buf, struct uio *uio, size_t n, int direction) +{ + struct iovec *iov; + int error; + struct vmspace *vm; + char *cp; + size_t resid, cnt; + int i; + + iov = uio->uio_iov; + vm = uio->uio_vmspace; + cp = buf; + resid = n; + + for (i = 0; i < uio->uio_iovcnt && resid > 0; i++) { + iov = &uio->uio_iov[i]; + if (iov->iov_len == 0) + continue; + cnt = MIN(resid, iov->iov_len); + + if (!VMSPACE_IS_KERNEL_P(vm) && + (curlwp->l_cpu->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) + != 0) { + preempt(); + } + if (direction == UIO_READ) { + error = copyout_vmspace(vm, cp, iov->iov_base, cnt); + } else { + error = copyin_vmspace(vm, iov->iov_base, cp, cnt); + } + if (error) + return (error); + cp += cnt; + resid -= cnt; + } + return (0); +} +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ + +int +_bus_dmatag_subregion(bus_dma_tag_t tag, bus_addr_t min_addr, + bus_addr_t max_addr, bus_dma_tag_t *newtag, int flags) +{ + +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + struct arm32_dma_range *dr; + bool subset = false; + size_t nranges = 0; + size_t i; + for (i = 0, dr = tag->_ranges; i < tag->_nranges; i++, dr++) { + if (dr->dr_sysbase <= min_addr + && max_addr <= dr->dr_sysbase + dr->dr_len - 1) { + subset = true; + } + if (min_addr <= dr->dr_sysbase + dr->dr_len + && max_addr >= dr->dr_sysbase) { + nranges++; + } + } + if (subset) { + *newtag = tag; + /* if the tag must be freed, add a reference */ + if (tag->_tag_needs_free) + (tag->_tag_needs_free)++; + return 0; + } + if (nranges == 0) { + nranges = 1; + } + + size_t mallocsize = sizeof(*tag) + nranges * sizeof(*dr); + if ((*newtag = malloc(mallocsize, M_DMAMAP, + (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) + return ENOMEM; + + dr = (void *)(*newtag + 1); + **newtag = *tag; + (*newtag)->_tag_needs_free = 1; + (*newtag)->_ranges = dr; + (*newtag)->_nranges = nranges; + + if (tag->_ranges == NULL) { + dr->dr_sysbase = min_addr; + dr->dr_busbase = min_addr; + dr->dr_len = max_addr + 1 - min_addr; + } else { + for (i = 0; i < nranges; i++) { + if (min_addr > dr->dr_sysbase + dr->dr_len + || max_addr < dr->dr_sysbase) + continue; + dr[0] = tag->_ranges[i]; + if (dr->dr_sysbase < min_addr) { + psize_t diff = min_addr - dr->dr_sysbase; + dr->dr_busbase += diff; + dr->dr_len -= diff; + dr->dr_sysbase += diff; + } + if (max_addr != 0xffffffff + && max_addr + 1 < dr->dr_sysbase + dr->dr_len) { + dr->dr_len = max_addr + 1 - dr->dr_sysbase; + } + dr++; + } + } + + return 0; +#else + return EOPNOTSUPP; +#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ +} + +void +_bus_dmatag_destroy(bus_dma_tag_t tag) +{ +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE + switch (tag->_tag_needs_free) { + case 0: + break; /* not allocated with malloc */ + case 1: + free(tag, M_DMAMAP); /* last reference to tag */ + break; + default: + (tag->_tag_needs_free)--; /* one less reference */ + } +#endif +} Index: src/sys/arch/arm/at91/at91_bus_dma.c diff -u src/sys/arch/arm/at91/at91_bus_dma.c:1.4 src/sys/arch/arm/at91/at91_bus_dma.c:1.5 --- src/sys/arch/arm/at91/at91_bus_dma.c:1.4 Fri Jul 1 19:31:16 2011 +++ src/sys/arch/arm/at91/at91_bus_dma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: at91_bus_dma.c,v 1.4 2011/07/01 19:31:16 dyoung Exp $ */ +/* $NetBSD: at91_bus_dma.c,v 1.5 2012/09/18 05:47:27 matt Exp $ */ /* * Copyright (c) 2004 Jesse Off @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: at91_bus_dma.c,v 1.4 2011/07/01 19:31:16 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: at91_bus_dma.c,v 1.5 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -47,24 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: at91_bus_dma #include <arm/at91/at91var.h> struct arm32_bus_dma_tag at91_bd_tag = { - NULL, /* _ranges: set by platform specific routine */ - 0, /* _nranges */ - - NULL, /* _cookie */ - - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMAMAP_FUNCS, }; Index: src/sys/arch/arm/broadcom/bcm2835_dma.c diff -u src/sys/arch/arm/broadcom/bcm2835_dma.c:1.1 src/sys/arch/arm/broadcom/bcm2835_dma.c:1.2 --- src/sys/arch/arm/broadcom/bcm2835_dma.c:1.1 Thu Jul 26 06:21:57 2012 +++ src/sys/arch/arm/broadcom/bcm2835_dma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_dma.c,v 1.1 2012/07/26 06:21:57 skrll Exp $ */ +/* $NetBSD: bcm2835_dma.c,v 1.2 2012/09/18 05:47:27 matt Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm2835_dma.c,v 1.1 2012/07/26 06:21:57 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm2835_dma.c,v 1.2 2012/09/18 05:47:27 matt Exp $"); #define _ARM32_BUS_DMA_PRIVATE @@ -38,24 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_dma. #include <sys/bus.h> struct arm32_bus_dma_tag bcm2835_bus_dma_tag = { - NULL, /* _ranges: set by platform specific routine */ - 0, /* _nranges */ - - NULL, /* _cookie */ - - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; Index: src/sys/arch/arm/broadcom/bcm53xx_board.c diff -u src/sys/arch/arm/broadcom/bcm53xx_board.c:1.2 src/sys/arch/arm/broadcom/bcm53xx_board.c:1.3 --- src/sys/arch/arm/broadcom/bcm53xx_board.c:1.2 Fri Sep 7 11:52:30 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_board.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm53xx_board.c,v 1.2 2012/09/07 11:52:30 matt Exp $ */ +/* $NetBSD: bcm53xx_board.c,v 1.3 2012/09/18 05:47:27 matt Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -34,7 +34,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: bcm53xx_board.c,v 1.2 2012/09/07 11:52:30 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: bcm53xx_board.c,v 1.3 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -64,20 +64,9 @@ static struct cpu_softc cpu_softc; static struct bcm53xx_clock_info clk_info; struct arm32_bus_dma_tag bcm53xx_dma_tag = { - ._dmamap_create = _bus_dmamap_create, - ._dmamap_destroy = _bus_dmamap_destroy, - ._dmamap_load = _bus_dmamap_load, - ._dmamap_load_mbuf = _bus_dmamap_load_mbuf, - ._dmamap_load_uio = _bus_dmamap_load_uio, - ._dmamap_load_raw = _bus_dmamap_load_raw, - ._dmamap_unload = _bus_dmamap_unload, - ._dmamap_sync_pre = _bus_dmamap_sync, - ._dmamap_sync_post = NULL, - ._dmamem_alloc = _bus_dmamem_alloc, - ._dmamem_free = _bus_dmamem_free, - ._dmamem_map = _bus_dmamem_map, - ._dmamem_unmap = _bus_dmamem_unmap, - ._dmamem_mmap = _bus_dmamem_mmap + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; #ifdef BCM53XX_CONSOLE_EARLY Index: src/sys/arch/arm/ep93xx/ep93xx_busdma.c diff -u src/sys/arch/arm/ep93xx/ep93xx_busdma.c:1.4 src/sys/arch/arm/ep93xx/ep93xx_busdma.c:1.5 --- src/sys/arch/arm/ep93xx/ep93xx_busdma.c:1.4 Fri Jul 1 19:31:17 2011 +++ src/sys/arch/arm/ep93xx/ep93xx_busdma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ep93xx_busdma.c,v 1.4 2011/07/01 19:31:17 dyoung Exp $ */ +/* $NetBSD: ep93xx_busdma.c,v 1.5 2012/09/18 05:47:27 matt Exp $ */ /* * Copyright (c) 2004 Jesse Off @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ep93xx_busdma.c,v 1.4 2011/07/01 19:31:17 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ep93xx_busdma.c,v 1.5 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -47,24 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: ep93xx_busdm #include <arm/ep93xx/ep93xxvar.h> struct arm32_bus_dma_tag ep93xx_bus_dma = { - NULL, /* _ranges: set by platform specific routine */ - 0, /* _nranges */ - - NULL, /* _cookie */ - - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; Index: src/sys/arch/arm/footbridge/footbridge_pci.c diff -u src/sys/arch/arm/footbridge/footbridge_pci.c:1.22 src/sys/arch/arm/footbridge/footbridge_pci.c:1.23 --- src/sys/arch/arm/footbridge/footbridge_pci.c:1.22 Sun Feb 12 16:34:07 2012 +++ src/sys/arch/arm/footbridge/footbridge_pci.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: footbridge_pci.c,v 1.22 2012/02/12 16:34:07 matt Exp $ */ +/* $NetBSD: footbridge_pci.c,v 1.23 2012/09/18 05:47:27 matt Exp $ */ /* * Copyright (c) 1997,1998 Mark Brinicombe. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: footbridge_pci.c,v 1.22 2012/02/12 16:34:07 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: footbridge_pci.c,v 1.23 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -102,23 +102,11 @@ struct arm32_dma_range footbridge_dma_ra * of these functions. */ struct arm32_bus_dma_tag footbridge_pci_bus_dma_tag = { - footbridge_dma_ranges, - 1, - NULL, - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, /* pre */ - NULL, /* post */ - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, + ._ranges = footbridge_dma_ranges, + ._nranges = 1, + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; /* Index: src/sys/arch/arm/gemini/gemini_dma.c diff -u src/sys/arch/arm/gemini/gemini_dma.c:1.2 src/sys/arch/arm/gemini/gemini_dma.c:1.3 --- src/sys/arch/arm/gemini/gemini_dma.c:1.2 Fri Jul 1 19:32:28 2011 +++ src/sys/arch/arm/gemini/gemini_dma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: gemini_dma.c,v 1.2 2011/07/01 19:32:28 dyoung Exp $ */ +/* $NetBSD: gemini_dma.c,v 1.3 2012/09/18 05:47:27 matt Exp $ */ /* adapted from: * NetBSD: pxa2x0_dma.c,v 1.4 2005/12/11 12:16:51 christos Exp @@ -43,7 +43,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gemini_dma.c,v 1.2 2011/07/01 19:32:28 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gemini_dma.c,v 1.3 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -57,22 +57,8 @@ __KERNEL_RCSID(0, "$NetBSD: gemini_dma.c #include <sys/bus.h> struct arm32_bus_dma_tag gemini_bus_dma_tag = { - 0, - 0, - NULL, /* _cookie */ - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; Index: src/sys/arch/arm/imx/imx_dma.c diff -u src/sys/arch/arm/imx/imx_dma.c:1.2 src/sys/arch/arm/imx/imx_dma.c:1.3 --- src/sys/arch/arm/imx/imx_dma.c:1.2 Fri Jul 1 20:27:50 2011 +++ src/sys/arch/arm/imx/imx_dma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: imx_dma.c,v 1.2 2011/07/01 20:27:50 dyoung Exp $ */ +/* $NetBSD: imx_dma.c,v 1.3 2012/09/18 05:47:27 matt Exp $ */ /* * Copyright (c) 2009 Genetec Corporation. All rights reserved. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx_dma.c,v 1.2 2011/07/01 20:27:50 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx_dma.c,v 1.3 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -46,22 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: imx_dma.c,v #include <sys/bus.h> struct arm32_bus_dma_tag imx_bus_dma_tag = { - 0, - 0, - NULL, /* _cookie */ - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; Index: src/sys/arch/arm/include/bus_defs.h diff -u src/sys/arch/arm/include/bus_defs.h:1.1 src/sys/arch/arm/include/bus_defs.h:1.2 --- src/sys/arch/arm/include/bus_defs.h:1.1 Fri Jul 1 17:09:58 2011 +++ src/sys/arch/arm/include/bus_defs.h Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_defs.h,v 1.1 2011/07/01 17:09:58 dyoung Exp $ */ +/* $NetBSD: bus_defs.h,v 1.2 2012/09/18 05:47:27 matt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. @@ -299,7 +299,7 @@ struct bus_space { /* * Private flags stored in the DMA map. */ -#define ARM32_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */ +#define _BUS_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */ /* Forwards needed by prototypes below. */ struct mbuf; @@ -398,6 +398,19 @@ struct arm32_bus_dma_tag { void (*_dmamem_unmap)(bus_dma_tag_t, void *, size_t); paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *, int, off_t, int, int); + + /* + * DMA tag utility functions + */ + int (*_dmatag_subregion)(bus_dma_tag_t, bus_addr_t, bus_addr_t, + bus_dma_tag_t *, int); + void (*_dmatag_destroy)(bus_dma_tag_t); + + /* + * State for bounce buffers + */ + int _tag_needs_free; + int (*_may_bounce)(bus_dma_tag_t, bus_dmamap_t, int, int *); }; /* @@ -430,15 +443,51 @@ struct arm32_bus_dmamap { bus_dma_segment_t dm_segs[1]; /* segments; variable length */ }; +/* _dm_buftype */ +#define _BUS_DMA_BUFTYPE_INVALID 0 +#define _BUS_DMA_BUFTYPE_LINEAR 1 +#define _BUS_DMA_BUFTYPE_MBUF 2 +#define _BUS_DMA_BUFTYPE_UIO 3 +#define _BUS_DMA_BUFTYPE_RAW 4 + #ifdef _ARM32_BUS_DMA_PRIVATE +#define _BUS_AVAIL_END physical_end +/* + * Cookie used for bounce buffers. A pointer to one of these it stashed in + * the DMA map. + */ +struct arm32_bus_dma_cookie { + int id_flags; /* flags; see below */ -/* _dm_buftype */ -#define ARM32_BUFTYPE_INVALID 0 -#define ARM32_BUFTYPE_LINEAR 1 -#define ARM32_BUFTYPE_MBUF 2 -#define ARM32_BUFTYPE_UIO 3 -#define ARM32_BUFTYPE_RAW 4 + /* + * Information about the original buffer used during + * DMA map syncs. Note that origibuflen is only used + * for ID_BUFTYPE_LINEAR. + */ + union { + void *un_origbuf; /* pointer to orig buffer if + bouncing */ + char *un_linearbuf; + struct mbuf *un_mbuf; + struct uio *un_uio; + } id_origbuf_un; +#define id_origbuf id_origbuf_un.un_origbuf +#define id_origlinearbuf id_origbuf_un.un_linearbuf +#define id_origmbuf id_origbuf_un.un_mbuf +#define id_origuio id_origbuf_un.un_uio + bus_size_t id_origbuflen; /* ...and size */ + + void *id_bouncebuf; /* pointer to the bounce buffer */ + bus_size_t id_bouncebuflen; /* ...and size */ + int id_nbouncesegs; /* number of valid bounce segs */ + bus_dma_segment_t id_bouncesegs[0]; /* array of bounce buffer + physical memory segments */ +}; +/* id_flags */ +#define _BUS_DMA_IS_BOUNCING 0x04 /* is bouncing current xfer */ +#define _BUS_DMA_HAS_BOUNCE 0x02 /* has bounce buffers */ #endif /* _ARM32_BUS_DMA_PRIVATE */ +#define _BUS_DMA_MIGHT_NEED_BOUNCE 0x01 /* may need bounce buffers */ #endif /* _ARM32_BUS_DEFS_H_ */ Index: src/sys/arch/arm/include/bus_funcs.h diff -u src/sys/arch/arm/include/bus_funcs.h:1.2 src/sys/arch/arm/include/bus_funcs.h:1.3 --- src/sys/arch/arm/include/bus_funcs.h:1.2 Sun Jul 15 20:44:20 2012 +++ src/sys/arch/arm/include/bus_funcs.h Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_funcs.h,v 1.2 2012/07/15 20:44:20 matt Exp $ */ +/* $NetBSD: bus_funcs.h,v 1.3 2012/09/18 05:47:27 matt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. @@ -606,11 +606,15 @@ do { \ #define bus_dmamem_mmap(t, sg, n, o, p, f) \ (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) -#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP -#define bus_dmatag_destroy(t) +#define bus_dmatag_subregion(t, mna, mxa, nt, f) \ + (*(t)->_dmatag_subregion)((t), (mna), (mxa), (nt), (f)) +#define bus_dmatag_destroy(t) \ + (*(t)->_dmatag_destroy)(t) #ifdef _ARM32_BUS_DMA_PRIVATE +extern paddr_t physical_start, physical_end; + int arm32_dma_range_intersect(struct arm32_dma_range *, int, paddr_t pa, psize_t size, paddr_t *pap, psize_t *sizep); @@ -629,6 +633,25 @@ void _bus_dmamap_unload(bus_dma_tag_t, b void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t, bus_size_t, int); +#ifdef _ARM32_NEED_BUS_DMA_BOUNCE +#define _BUS_DMAMAP_SYNC_FUNCS \ + ._dmamap_sync_pre = _bus_dmamap_sync, \ + ._dmamap_sync_post = _bus_dmamap_sync +#else +#define _BUS_DMAMAP_SYNC_FUNCS \ + ._dmamap_sync_pre = _bus_dmamap_sync +#endif + +#define _BUS_DMAMAP_FUNCS \ + ._dmamap_create = _bus_dmamap_create, \ + ._dmamap_destroy = _bus_dmamap_destroy, \ + ._dmamap_load = _bus_dmamap_load, \ + ._dmamap_load_mbuf = _bus_dmamap_load_mbuf, \ + ._dmamap_load_raw = _bus_dmamap_load_raw, \ + ._dmamap_load_uio = _bus_dmamap_load_uio, \ + ._dmamap_unload = _bus_dmamap_unload, \ + _BUS_DMAMAP_SYNC_FUNCS + int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size, bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); @@ -641,10 +664,26 @@ void _bus_dmamem_unmap(bus_dma_tag_t tag paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs, int nsegs, off_t off, int prot, int flags); +#define _BUS_DMAMEM_FUNCS \ + ._dmamem_alloc = _bus_dmamem_alloc, \ + ._dmamem_free = _bus_dmamem_free, \ + ._dmamem_map = _bus_dmamem_map, \ + ._dmamem_unmap = _bus_dmamem_unmap, \ + ._dmamem_mmap = _bus_dmamem_mmap + int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size, bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, vaddr_t low, vaddr_t high); + +int _bus_dmatag_subregion(bus_dma_tag_t, bus_addr_t, bus_addr_t, + bus_dma_tag_t *, int); +void _bus_dmatag_destroy(bus_dma_tag_t); + +#define _BUS_DMATAG_FUNCS \ + ._dmatag_subregion = _bus_dmatag_subregion, \ + ._dmatag_destroy = _bus_dmatag_destroy + #endif /* _ARM32_BUS_DMA_PRIVATE */ #endif /* _ARM32_BUS_FUNCS_H_ */ Index: src/sys/arch/arm/ixp12x0/ixp12x0_pci_dma.c diff -u src/sys/arch/arm/ixp12x0/ixp12x0_pci_dma.c:1.8 src/sys/arch/arm/ixp12x0/ixp12x0_pci_dma.c:1.9 --- src/sys/arch/arm/ixp12x0/ixp12x0_pci_dma.c:1.8 Fri Jul 1 20:27:50 2011 +++ src/sys/arch/arm/ixp12x0/ixp12x0_pci_dma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ixp12x0_pci_dma.c,v 1.8 2011/07/01 20:27:50 dyoung Exp $ */ +/* $NetBSD: ixp12x0_pci_dma.c,v 1.9 2012/09/18 05:47:27 matt Exp $ */ /* * Copyright (c) 2002, 2003 * Ichiro FUKUHARA <ich...@ichiro.org>. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ixp12x0_pci_dma.c,v 1.8 2011/07/01 20:27:50 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ixp12x0_pci_dma.c,v 1.9 2012/09/18 05:47:27 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -74,4 +74,7 @@ ixp12x0_pci_dma_init(struct ixp12x0_soft dmat->_dmamem_map = _bus_dmamem_map; dmat->_dmamem_unmap = _bus_dmamem_unmap; dmat->_dmamem_mmap = _bus_dmamem_mmap; + + dmat->_dmatag_subregion = _bus_dmatag_subregion; + dmat->_dmatag_destroy = _bus_dmatag_destroy; } Index: src/sys/arch/arm/marvell/mvsoc_dma.c diff -u src/sys/arch/arm/marvell/mvsoc_dma.c:1.2 src/sys/arch/arm/marvell/mvsoc_dma.c:1.3 --- src/sys/arch/arm/marvell/mvsoc_dma.c:1.2 Fri Jul 1 20:30:21 2011 +++ src/sys/arch/arm/marvell/mvsoc_dma.c Tue Sep 18 05:47:27 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsoc_dma.c,v 1.2 2011/07/01 20:30:21 dyoung Exp $ */ +/* $NetBSD: mvsoc_dma.c,v 1.3 2012/09/18 05:47:27 matt Exp $ */ /* * Copyright (c) 2004 Jesse Off @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mvsoc_dma.c,v 1.2 2011/07/01 20:30:21 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsoc_dma.c,v 1.3 2012/09/18 05:47:27 matt Exp $"); #define _ARM32_BUS_DMA_PRIVATE @@ -51,24 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: mvsoc_dma.c, #include <arm/marvell/mvsocvar.h> struct arm32_bus_dma_tag mvsoc_bus_dma_tag = { - NULL, /* _ranges: set by platform specific routine */ - 0, /* _nranges */ - - NULL, /* _cookie */ - - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; Index: src/sys/arch/arm/omap/omap_dma.c diff -u src/sys/arch/arm/omap/omap_dma.c:1.3 src/sys/arch/arm/omap/omap_dma.c:1.4 --- src/sys/arch/arm/omap/omap_dma.c:1.3 Fri Jul 1 20:30:21 2011 +++ src/sys/arch/arm/omap/omap_dma.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: omap_dma.c,v 1.3 2011/07/01 20:30:21 dyoung Exp $ */ +/* $NetBSD: omap_dma.c,v 1.4 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2010 Michael Lorenz @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: omap_dma.c,v 1.3 2011/07/01 20:30:21 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: omap_dma.c,v 1.4 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -40,22 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: omap_dma.c,v #include <sys/bus.h> struct arm32_bus_dma_tag omap_bus_dma_tag = { - 0, - 0, - NULL, /* _cookie */ - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; - Index: src/sys/arch/arm/s3c2xx0/s3c2xx0_busdma.c diff -u src/sys/arch/arm/s3c2xx0/s3c2xx0_busdma.c:1.4 src/sys/arch/arm/s3c2xx0/s3c2xx0_busdma.c:1.5 --- src/sys/arch/arm/s3c2xx0/s3c2xx0_busdma.c:1.4 Fri Jul 1 20:31:39 2011 +++ src/sys/arch/arm/s3c2xx0/s3c2xx0_busdma.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: s3c2xx0_busdma.c,v 1.4 2011/07/01 20:31:39 dyoung Exp $ */ +/* $NetBSD: s3c2xx0_busdma.c,v 1.5 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2002, 2003 Fujitsu Component Limited @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: s3c2xx0_busdma.c,v 1.4 2011/07/01 20:31:39 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: s3c2xx0_busdma.c,v 1.5 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -51,24 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: s3c2xx0_busd #include <arm/s3c2xx0/s3c2xx0var.h> struct arm32_bus_dma_tag s3c2xx0_bus_dma = { - NULL, /* _ranges: set by platform specific routine */ - 0, /* _nranges */ - - NULL, /* _cookie */ - - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; Index: src/sys/arch/arm/xscale/becc.c diff -u src/sys/arch/arm/xscale/becc.c:1.14 src/sys/arch/arm/xscale/becc.c:1.15 --- src/sys/arch/arm/xscale/becc.c:1.14 Fri Jul 1 20:32:51 2011 +++ src/sys/arch/arm/xscale/becc.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: becc.c,v 1.14 2011/07/01 20:32:51 dyoung Exp $ */ +/* $NetBSD: becc.c,v 1.15 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2002, 2003 Wasabi Systems, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: becc.c,v 1.14 2011/07/01 20:32:51 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: becc.c,v 1.15 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -297,6 +297,9 @@ becc_pci_dma_init(struct becc_softc *sc) dmat->_dmamem_map = _bus_dmamem_map; dmat->_dmamem_unmap = _bus_dmamem_unmap; dmat->_dmamem_mmap = _bus_dmamem_mmap; + + dmat->_dmatag_subregion = _bus_dmatag_subregion; + dmat->_dmatag_destroy = _bus_dmatag_destroy; } /* Index: src/sys/arch/arm/xscale/i80312.c diff -u src/sys/arch/arm/xscale/i80312.c:1.21 src/sys/arch/arm/xscale/i80312.c:1.22 --- src/sys/arch/arm/xscale/i80312.c:1.21 Fri Jul 1 20:32:51 2011 +++ src/sys/arch/arm/xscale/i80312.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: i80312.c,v 1.21 2011/07/01 20:32:51 dyoung Exp $ */ +/* $NetBSD: i80312.c,v 1.22 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2001, 2002 Wasabi Systems, Inc. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i80312.c,v 1.21 2011/07/01 20:32:51 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i80312.c,v 1.22 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -368,6 +368,9 @@ i80312_pci_dma_init(struct i80312_softc dmat->_dmamem_map = _bus_dmamem_map; dmat->_dmamem_unmap = _bus_dmamem_unmap; dmat->_dmamem_mmap = _bus_dmamem_mmap; + + dmat->_dmatag_subregion = _bus_dmatag_subregion; + dmat->_dmatag_destroy = _bus_dmatag_destroy; } /* Index: src/sys/arch/arm/xscale/i80321.c diff -u src/sys/arch/arm/xscale/i80321.c:1.23 src/sys/arch/arm/xscale/i80321.c:1.24 --- src/sys/arch/arm/xscale/i80321.c:1.23 Sun Feb 12 16:31:01 2012 +++ src/sys/arch/arm/xscale/i80321.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: i80321.c,v 1.23 2012/02/12 16:31:01 matt Exp $ */ +/* $NetBSD: i80321.c,v 1.24 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2002 Wasabi Systems, Inc. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i80321.c,v 1.23 2012/02/12 16:31:01 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i80321.c,v 1.24 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -337,6 +337,9 @@ i80321_pci_dma_init(struct i80321_softc dmat->_dmamem_map = _bus_dmamem_map; dmat->_dmamem_unmap = _bus_dmamem_unmap; dmat->_dmamem_mmap = _bus_dmamem_mmap; + + dmat->_dmatag_subregion = _bus_dmatag_subregion; + dmat->_dmatag_destroy = _bus_dmatag_destroy; } /* Index: src/sys/arch/arm/xscale/ixp425_ixme.c diff -u src/sys/arch/arm/xscale/ixp425_ixme.c:1.3 src/sys/arch/arm/xscale/ixp425_ixme.c:1.4 --- src/sys/arch/arm/xscale/ixp425_ixme.c:1.3 Fri Jul 1 20:32:51 2011 +++ src/sys/arch/arm/xscale/ixp425_ixme.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ixp425_ixme.c,v 1.3 2011/07/01 20:32:51 dyoung Exp $ */ +/* $NetBSD: ixp425_ixme.c,v 1.4 2012/09/18 05:47:28 matt Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ixp425_ixme.c,v 1.3 2011/07/01 20:32:51 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ixp425_ixme.c,v 1.4 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -99,12 +99,16 @@ ixme_attach(struct device *parent, struc sc->sc_dt._dmamap_unload = _bus_dmamap_unload; sc->sc_dt._dmamap_sync_pre = _bus_dmamap_sync; sc->sc_dt._dmamap_sync_post = NULL; + sc->sc_dt._dmamem_alloc = _bus_dmamem_alloc; sc->sc_dt._dmamem_free = _bus_dmamem_free; sc->sc_dt._dmamem_map = _bus_dmamem_map; sc->sc_dt._dmamem_unmap = _bus_dmamem_unmap; sc->sc_dt._dmamem_mmap = _bus_dmamem_mmap; + sc->sc_dt._dmatag_subregion = _bus_dmatag_subregion; + sc->sc_dt._dmatag_destroy = _bus_dmatag_destroy; + config_search_ia(ixme_search, self, "ixme", NULL); } Index: src/sys/arch/arm/xscale/ixp425_pci_dma.c diff -u src/sys/arch/arm/xscale/ixp425_pci_dma.c:1.5 src/sys/arch/arm/xscale/ixp425_pci_dma.c:1.6 --- src/sys/arch/arm/xscale/ixp425_pci_dma.c:1.5 Fri Jul 1 20:32:51 2011 +++ src/sys/arch/arm/xscale/ixp425_pci_dma.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ixp425_pci_dma.c,v 1.5 2011/07/01 20:32:51 dyoung Exp $ */ +/* $NetBSD: ixp425_pci_dma.c,v 1.6 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2003 @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ixp425_pci_dma.c,v 1.5 2011/07/01 20:32:51 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ixp425_pci_dma.c,v 1.6 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -74,4 +74,7 @@ ixp425_pci_dma_init(struct ixp425_softc dmat->_dmamem_map = _bus_dmamem_map; dmat->_dmamem_unmap = _bus_dmamem_unmap; dmat->_dmamem_mmap = _bus_dmamem_mmap; + + dmat->_dmatag_subregion = _bus_dmatag_subregion; + dmat->_dmatag_destroy = _bus_dmatag_destroy; } Index: src/sys/arch/arm/xscale/pxa2x0_dma.c diff -u src/sys/arch/arm/xscale/pxa2x0_dma.c:1.5 src/sys/arch/arm/xscale/pxa2x0_dma.c:1.6 --- src/sys/arch/arm/xscale/pxa2x0_dma.c:1.5 Fri Jul 1 20:32:51 2011 +++ src/sys/arch/arm/xscale/pxa2x0_dma.c Tue Sep 18 05:47:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pxa2x0_dma.c,v 1.5 2011/07/01 20:32:51 dyoung Exp $ */ +/* $NetBSD: pxa2x0_dma.c,v 1.6 2012/09/18 05:47:28 matt Exp $ */ /* * Copyright (c) 2002 Genetec Corporation. All rights reserved. @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pxa2x0_dma.c,v 1.5 2011/07/01 20:32:51 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pxa2x0_dma.c,v 1.6 2012/09/18 05:47:28 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -53,22 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: pxa2x0_dma.c #include <sys/bus.h> struct arm32_bus_dma_tag pxa2x0_bus_dma_tag = { - 0, - 0, - NULL, /* _cookie */ - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - NULL, /* sync_post */ - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap + _BUS_DMAMAP_FUNCS, + _BUS_DMAMEM_FUNCS, + _BUS_DMATAG_FUNCS, }; -