Skip to content

Commit

Permalink
arm64: properly bounce short unaligned buffers.
Browse files Browse the repository at this point in the history
  • Loading branch information
strejda committed Jan 14, 2021
1 parent a5ebafe commit f6f7fbc
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions sys/arm64/arm64/busdma_bounce.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,9 +845,7 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
KASSERT(dmat->common.alignment <= PAGE_SIZE,
("bounced buffer cannot have alignment bigger "
"than PAGE_SIZE: %lu", dmat->common.alignment));
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
sgsize = roundup2(sgsize, dmat->common.alignment);
sgsize = MIN(sgsize, dmat->common.maxsegsz);
sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));
curaddr = add_bounce_page(dmat, map, 0, curaddr,
sgsize);
} else if ((map->flags & DMAMAP_COHERENT) == 0) {
Expand Down Expand Up @@ -879,7 +877,11 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
/*
* Did we fit?
*/
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
if (buflen != 0) {
bus_dmamap_unload(dmat, map);
return (EFBIG); /* XXX better return value here? */
}
return (0);
}

/*
Expand All @@ -892,7 +894,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
int *segp)
{
struct sync_list *sl;
bus_size_t sgsize, max_sgsize;
bus_size_t sgsize;
bus_addr_t curaddr, sl_pend;
vm_offset_t kvaddr, vaddr, sl_vend;
int error;
Expand Down Expand Up @@ -931,7 +933,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
/*
* Get the physical address for this segment.
*/
if (pmap == kernel_pmap) {
if (__predict_true(pmap == kernel_pmap)) {
curaddr = pmap_kextract(vaddr);
kvaddr = vaddr;
} else {
Expand All @@ -942,23 +944,16 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
/*
* Compute the segment size, and adjust counts.
*/
max_sgsize = MIN(buflen, dmat->common.maxsegsz);
if ((map->flags & DMAMAP_FROM_DMAMEM) != 0) {
sgsize = max_sgsize;
} else {
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
sgsize = MIN(sgsize, max_sgsize);
}
sgsize = MIN(buflen, dmat->common.maxsegsz);
if ((map->flags & DMAMAP_FROM_DMAMEM) == 0)
sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));

if (map->pagesneeded != 0 &&
must_bounce(dmat, map, curaddr, sgsize)) {
/* See comment in bounce_bus_dmamap_load_phys */
KASSERT(dmat->common.alignment <= PAGE_SIZE,
("bounced buffer cannot have alignment bigger "
"than PAGE_SIZE: %lu", dmat->common.alignment));
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
sgsize = roundup2(sgsize, dmat->common.alignment);
sgsize = MIN(sgsize, max_sgsize);
curaddr = add_bounce_page(dmat, map, kvaddr, curaddr,
sgsize);
} else if ((map->flags & DMAMAP_COHERENT) == 0) {
Expand Down Expand Up @@ -999,7 +994,11 @@ bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
/*
* Did we fit?
*/
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
if (buflen != 0) {
bus_dmamap_unload(dmat, map);
return (EFBIG); /* XXX better return value here? */
}
return (0);
}

static void
Expand Down

0 comments on commit f6f7fbc

Please sign in to comment.