diff options
Diffstat (limited to 'sys/arm64/arm64/busdma_bounce.c')
-rw-r--r-- | sys/arm64/arm64/busdma_bounce.c | 69 |
1 files changed, 14 insertions, 55 deletions
diff --git a/sys/arm64/arm64/busdma_bounce.c b/sys/arm64/arm64/busdma_bounce.c index e62794da2753..f218bc062642 100644 --- a/sys/arm64/arm64/busdma_bounce.c +++ b/sys/arm64/arm64/busdma_bounce.c @@ -121,12 +121,16 @@ static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, static MALLOC_DEFINE(M_BUSDMA, "busdma", "busdma metadata"); #define dmat_alignment(dmat) ((dmat)->common.alignment) +#define dmat_bounce_flags(dmat) ((dmat)->bounce_flags) +#define dmat_boundary(dmat) ((dmat)->common.boundary) #define dmat_domain(dmat) ((dmat)->common.domain) #define dmat_flags(dmat) ((dmat)->common.flags) #define dmat_highaddr(dmat) ((dmat)->common.highaddr) #define dmat_lowaddr(dmat) ((dmat)->common.lowaddr) #define dmat_lockfunc(dmat) ((dmat)->common.lockfunc) #define dmat_lockfuncarg(dmat) ((dmat)->common.lockfuncarg) +#define dmat_maxsegsz(dmat) ((dmat)->common.maxsegsz) +#define dmat_nsegments(dmat) ((dmat)->common.nsegments) #include "../../kern/subr_busdma_bounce.c" @@ -639,7 +643,7 @@ _bus_dmamap_pagesneeded(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, count = 0; curaddr = buf; while (buflen != 0) { - sgsize = MIN(buflen, dmat->common.maxsegsz); + sgsize = buflen; if (must_bounce(dmat, map, curaddr, sgsize)) { sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK)); @@ -692,15 +696,13 @@ _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, vendaddr = (vm_offset_t)buf + buflen; while (vaddr < vendaddr) { - sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK); - sg_len = MIN(sg_len, dmat->common.maxsegsz); + sg_len = MIN(vendaddr - vaddr, + PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK)); if (pmap == kernel_pmap) paddr = pmap_kextract(vaddr); else paddr = pmap_extract(pmap, vaddr); - if (must_bounce(dmat, map, paddr, - min(vendaddr - vaddr, (PAGE_SIZE - ((vm_offset_t)vaddr & - PAGE_MASK)))) != 0) { + if (must_bounce(dmat, map, paddr, sg_len) != 0) { sg_len = roundup2(sg_len, dmat->common.alignment); map->pagesneeded++; @@ -712,47 +714,6 @@ _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, } /* - * Add a single contiguous physical range to the segment list. - */ -static bus_size_t -_bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr, - bus_size_t sgsize, bus_dma_segment_t *segs, int *segp) -{ - int seg; - - /* - * Make sure we don't cross any boundaries. - */ - if (!vm_addr_bound_ok(curaddr, sgsize, dmat->common.boundary)) - sgsize = roundup2(curaddr, dmat->common.boundary) - curaddr; - - /* - * Insert chunk into a segment, coalescing with - * previous segment if possible. - */ - seg = *segp; - if (seg == -1) { - seg = 0; - segs[seg].ds_addr = curaddr; - segs[seg].ds_len = sgsize; - } else { - if (curaddr == segs[seg].ds_addr + segs[seg].ds_len && - (segs[seg].ds_len + sgsize) <= dmat->common.maxsegsz && - vm_addr_bound_ok(segs[seg].ds_addr, - segs[seg].ds_len + sgsize, dmat->common.boundary)) - segs[seg].ds_len += sgsize; - else { - if (++seg >= dmat->common.nsegments) - return (0); - segs[seg].ds_addr = curaddr; - segs[seg].ds_len = sgsize; - } - } - *segp = seg; - return (sgsize); -} - -/* * Utility function to load a physical buffer. segp contains * the starting segment on entrace, and the ending segment on exit. */ @@ -783,7 +744,7 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, while (buflen > 0) { curaddr = buf; - sgsize = MIN(buflen, dmat->common.maxsegsz); + sgsize = buflen; if (map->pagesneeded != 0 && must_bounce(dmat, map, curaddr, sgsize)) { /* @@ -817,9 +778,8 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, } else sl->datacount += sgsize; } - sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs, - segp); - if (sgsize == 0) + if (!_bus_dmamap_addsegs(dmat, map, curaddr, sgsize, segs, + segp)) break; buf += sgsize; buflen -= sgsize; @@ -895,7 +855,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, /* * Compute the segment size, and adjust counts. */ - sgsize = MIN(buflen, dmat->common.maxsegsz); + sgsize = buflen; if ((map->flags & DMAMAP_FROM_DMAMEM) == 0) sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK)); @@ -934,9 +894,8 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, } else sl->datacount += sgsize; } - sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs, - segp); - if (sgsize == 0) + if (!_bus_dmamap_addsegs(dmat, map, curaddr, sgsize, segs, + segp)) break; vaddr += sgsize; buflen -= sgsize; |