* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.94 2008/08/15 20:51:31 kmacy Exp $
- * $DragonFly: src/sys/platform/pc32/i386/busdma_machdep.c,v 1.23 2008/06/05 18:06:32 swildner Exp $
*/
#include <sys/param.h>
if (alignment == 0)
alignment = 1;
if (alignment & (alignment - 1))
- panic("alignment must be power of 2\n");
+ panic("alignment must be power of 2");
if (boundary != 0) {
if (boundary & (boundary - 1))
- panic("boundary must be power of 2\n");
+ panic("boundary must be power of 2");
if (boundary < maxsegsz) {
kprintf("boundary < maxsegsz:\n");
print_backtrace(-1);
uintptr_t vaddr = (uintptr_t)vaddr0;
if ((vaddr ^ (vaddr + dmat->maxsize - 1)) & ~PAGE_MASK) {
- if (verify || bootverbose)
- kprintf("boundary check failed\n");
if (verify)
- print_backtrace(-1); /* XXX panic */
+ panic("boundary check failed\n");
+ if (bootverbose)
+ kprintf("boundary check failed\n");
maxsize = dmat->maxsize;
}
if (vaddr & (dmat->alignment - 1)) {
- if (verify || bootverbose)
- kprintf("alignment check failed\n");
if (verify)
- print_backtrace(-1); /* XXX panic */
+ panic("alignment check failed\n");
+ if (bootverbose)
+ kprintf("alignment check failed\n");
if (dmat->maxsize < dmat->alignment)
maxsize = dmat->alignment;
else
*/
maxsize = check_kmalloc(dmat, *vaddr, 0);
if (maxsize) {
- size_t size;
-
kfree(*vaddr, M_DEVBUF);
- /* XXX check for overflow? */
- for (size = 1; size <= maxsize; size <<= 1)
- ;
- *vaddr = kmalloc(size, M_DEVBUF, mflags);
+ *vaddr = kmalloc_powerof2(maxsize, M_DEVBUF, mflags);
check_kmalloc(dmat, *vaddr, 1);
}
} else {
* NULL
*/
if (map != NULL)
- panic("bus_dmamem_free: Invalid map freed\n");
+ panic("bus_dmamem_free: Invalid map freed");
if (BUS_DMAMEM_KMALLOC(dmat))
kfree(vaddr, M_DEVBUF);
else
paddr = _bus_dma_extract(pmap, vaddr);
if (run_filter(dmat, paddr) != 0)
map->pagesneeded++;
- vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
+ vaddr += (PAGE_SIZE - (vaddr & PAGE_MASK));
}
}
(BUS_DMA_PRIVBZONE | BUS_DMA_ALLOCALL));
if (dmat->flags & BUS_DMA_PROTECTED)
- panic("protected dmamap callback will be defered\n");
+ panic("protected dmamap callback will be defered");
bus_dma_tag_unlock(dmat);
return error;
M_ASSERTPKTHDR(m0);
- KASSERT(maxsegs >= 1, ("invalid maxsegs %d\n", maxsegs));
+ KASSERT(maxsegs >= 1, ("invalid maxsegs %d", maxsegs));
KASSERT(maxsegs <= dmat->nsegments,
- ("%d too many segments, dmat only support %d segments\n",
+ ("%d too many segments, dmat only supports %d segments",
maxsegs, dmat->nsegments));
KASSERT(flags & BUS_DMA_NOWAIT,
- ("only BUS_DMA_NOWAIT is supported\n"));
+ ("only BUS_DMA_NOWAIT is supported"));
if (m0->m_pkthdr.len <= dmat->maxsize) {
int first = 1;
struct bounce_zone *bz, *new_bz;
KASSERT(dmat->bounce_zone == NULL,
- ("bounce zone was already assigned\n"));
+ ("bounce zone was already assigned"));
new_bz = kmalloc(sizeof(*new_bz), M_DEVBUF, M_INTWAIT | M_ZERO);
KKASSERT(bz->free_bpages > 0);
bz->free_bpages--;
+ BZ_UNLOCK(bz);
contigfree((void *)bpage->vaddr, PAGE_SIZE, M_DEVBUF);
kfree(bpage, M_DEVBUF);
+ BZ_LOCK(bz);
}
if (bz->total_bpages) {
kprintf("#%d bounce pages are still in use\n",
BZ_UNLOCK(bz);
+ if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /* Page offset needs to be preserved. */
+ bpage->vaddr |= vaddr & PAGE_MASK;
+ bpage->busaddr |= vaddr & PAGE_MASK;
+ }
bpage->datavaddr = vaddr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&map->bpages, bpage, links);
bpage->datavaddr = 0;
bpage->datacount = 0;
+ if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /*
+ * Reset the bounce page to start at offset 0. Other uses
+ * of this bounce page may need to store a full page of
+ * data and/or assume it starts on a page boundary.
+ */
+ bpage->vaddr &= ~PAGE_MASK;
+ bpage->busaddr &= ~PAGE_MASK;
+ }
+
BZ_LOCK(bz);
STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);