svn commit: r216305 - stable/8/sys/i386/i386
Colin Percival
cperciva at FreeBSD.org
Wed Dec 8 19:48:30 UTC 2010
Author: cperciva
Date: Wed Dec 8 19:48:29 2010
New Revision: 216305
URL: http://svn.freebsd.org/changeset/base/216305
Log:
MFC r216194 / MFamd64 r206610: Enforce stronger alignment semantics in
order to unbreak the Xen blkfront driver.
Approved by: re (kib)
Modified:
stable/8/sys/i386/i386/busdma_machdep.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
Modified: stable/8/sys/i386/i386/busdma_machdep.c
==============================================================================
--- stable/8/sys/i386/i386/busdma_machdep.c Wed Dec 8 19:42:21 2010 (r216304)
+++ stable/8/sys/i386/i386/busdma_machdep.c Wed Dec 8 19:48:29 2010 (r216305)
@@ -249,8 +249,7 @@ bus_dma_tag_create(bus_dma_tag_t parent,
newtag->alignment = alignment;
newtag->boundary = boundary;
newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
- newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
- (PAGE_SIZE - 1);
+ newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1);
newtag->filter = filter;
newtag->filterarg = filterarg;
newtag->maxsize = maxsize;
@@ -597,15 +596,19 @@ _bus_dmamap_count_pages(bus_dma_tag_t dm
vendaddr = (vm_offset_t)buf + buflen;
while (vaddr < vendaddr) {
+ bus_size_t sg_len;
+
+ sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
if (pmap)
paddr = pmap_extract(pmap, vaddr);
else
paddr = pmap_kextract(vaddr);
if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
run_filter(dmat, paddr) != 0) {
+ sg_len = roundup2(sg_len, dmat->alignment);
map->pagesneeded++;
}
- vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
+ vaddr += sg_len;
}
CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
}
@@ -672,6 +675,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
bmask = ~(dmat->boundary - 1);
for (seg = *segp; buflen > 0 ; ) {
+ bus_size_t max_sgsize;
+
/*
* Get the physical address for this segment.
*/
@@ -683,11 +688,16 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
/*
* Compute the segment size, and adjust counts.
*/
- sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
- if (sgsize > dmat->maxsegsz)
- sgsize = dmat->maxsegsz;
- if (buflen < sgsize)
- sgsize = buflen;
+ max_sgsize = MIN(buflen, dmat->maxsegsz);
+ sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
+ if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+ map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
+ sgsize = roundup2(sgsize, dmat->alignment);
+ sgsize = MIN(sgsize, max_sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ } else {
+ sgsize = MIN(sgsize, max_sgsize);
+ }
/*
* Make sure we don't cross any boundaries.
@@ -698,10 +708,6 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
sgsize = (baddr - curaddr);
}
- if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
- map->pagesneeded != 0 && run_filter(dmat, curaddr))
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
-
/*
* Insert chunk into a segment, coalescing with
* previous segment if possible.
More information about the svn-src-all
mailing list