X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/26bf27137b277ad30fc9d766aac6a6add8dc5e20..cd12dbe89814861db12480fa250d9ee570701751:/sys/platform/pc32/i386/busdma_machdep.c diff --git a/sys/platform/pc32/i386/busdma_machdep.c b/sys/platform/pc32/i386/busdma_machdep.c index 7d3708fc96..ae451fb6d1 100644 --- a/sys/platform/pc32/i386/busdma_machdep.c +++ b/sys/platform/pc32/i386/busdma_machdep.c @@ -24,7 +24,6 @@ * 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 @@ -260,11 +259,11 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, 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); @@ -512,17 +511,17 @@ check_kmalloc(bus_dma_tag_t dmat, const void *vaddr0, int verify) 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 @@ -574,13 +573,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, */ 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 { @@ -609,7 +603,7 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) * 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 @@ -677,7 +671,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, 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)); } } @@ -849,7 +843,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, (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; @@ -905,12 +899,12 @@ bus_dmamap_load_mbuf_segment(bus_dma_tag_t dmat, bus_dmamap_t map, 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; @@ -1104,7 +1098,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) 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); @@ -1259,8 +1253,10 @@ free_bounce_pages_all(bus_dma_tag_t dmat) 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", @@ -1370,6 +1366,11 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, 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); @@ -1385,6 +1386,16 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage) 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);