diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c index 2aff3f8a150..e1c1b81c19d 100644 --- a/sys/arm/arm/busdma_machdep-v6.c +++ b/sys/arm/arm/busdma_machdep-v6.c @@ -302,13 +302,14 @@ exclusion_bounce(bus_dma_tag_t dmat) } /* - * Return true if the given address does not fall on the alignment boundary. + * Return true if the given physical address does not fall on the alignment + * boundary. */ static __inline int -alignment_bounce(bus_dma_tag_t dmat, bus_addr_t addr) +alignment_bounce(bus_dma_tag_t dmat, bus_addr_t paddr) { - return (addr & (dmat->alignment - 1)); + return (paddr & (dmat->alignment - 1)); } /* @@ -337,18 +338,17 @@ cacheline_bounce(bus_dmamap_t map, bus_addr_t addr, bus_size_t size) * This is used to quick-check whether we need to do the more expensive work of * checking the DMA page-by-page looking for alignment and exclusion bounces. * - * Note that the addr argument might be either virtual or physical. It doesn't - * matter because we only look at the low-order bits, which are the same in both - * address spaces. + * Note that the paddr argument must be physical address because requested + * alignment can be bigger that page size. */ static __inline int -might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr, +might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr, bus_size_t size) { return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) || - alignment_bounce(dmat, addr) || - cacheline_bounce(map, addr, size)); + alignment_bounce(dmat, paddr) || + cacheline_bounce(map, paddr, size)); } /* @@ -1028,7 +1028,7 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, counter_u64_add(maploads_total, 1); counter_u64_add(maploads_physmem, 1); - if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) { + if (might_bounce(dmat, map, pmap_kextract((vm_offset_t)buf), buflen)) { _bus_dmamap_count_phys(dmat, map, buf, buflen, flags); if (map->pagesneeded != 0) { counter_u64_add(maploads_bounced, 1); @@ -1124,7 +1124,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, map->flags |= DMAMAP_MBUF; } - if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) { + if (might_bounce(dmat, map, pmap_kextract((vm_offset_t)buf), buflen)) { _bus_dmamap_count_pages(dmat, pmap, map, buf, buflen, flags); if (map->pagesneeded != 0) { counter_u64_add(maploads_bounced, 1);