[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 8 of 9] swiotlb: cleanups to swiotlb_bounce()
Make swiotlb_bounce test each page for highness rather than relying on CONFIG_HIGHMEM, and a couple of other cleanups. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx> --- lib/swiotlb.c | 61 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -25,6 +25,7 @@ #include <linux/swiotlb.h> #include <linux/string.h> #include <linux/swiotlb.h> +#include <linux/pfn.h> #include <linux/types.h> #include <linux/ctype.h> #include <linux/highmem.h> @@ -330,40 +331,42 @@ /* * Bounce: copy the swiotlb buffer back to the original dma location */ -void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, - enum dma_data_direction dir) +static void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, + enum dma_data_direction dir) { -#ifdef CONFIG_HIGHMEM - /* The buffer may not have a mapping. Map it in and copy */ - unsigned int offset = ((unsigned long)phys & - ((1 << PAGE_SHIFT) - 1)); - char *buffer; - unsigned int sz = 0; - unsigned long flags; + unsigned long pfn = PFN_DOWN(phys); - while (size) { - sz = ((PAGE_SIZE - offset) > size) ? size : - PAGE_SIZE - offset; - local_irq_save(flags); - buffer = kmap_atomic(pfn_to_page(phys >> PAGE_SHIFT), - KM_BOUNCE_READ); + if (PageHighMem(pfn_to_page(pfn))) { + /* The buffer does not have a mapping. Map it in and copy */ + unsigned int offset = phys & ~PAGE_MASK; + char *buffer; + unsigned int sz = 0; + unsigned long flags; + + while (size) { + sz = min(PAGE_SIZE - offset, size); + + local_irq_save(flags); + buffer = kmap_atomic(pfn_to_page(pfn), + KM_BOUNCE_READ); + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, buffer + offset, sz); + else + memcpy(buffer + offset, dma_addr, sz); + kunmap_atomic(buffer, KM_BOUNCE_READ); + local_irq_restore(flags); + + size -= sz; + pfn++; + dma_addr += sz; + offset = 0; + } + } else { if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, buffer + offset, sz); + memcpy(dma_addr, phys_to_virt(phys), size); else - memcpy(buffer + offset, dma_addr, sz); - kunmap_atomic(buffer, KM_BOUNCE_READ); - local_irq_restore(flags); - size -= sz; - phys += sz; - dma_addr += sz; - offset = 0; + memcpy(phys_to_virt(phys), dma_addr, size); } -#else - if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, phys_to_virt(phys), size); - else - memcpy(phys_to_virt(phys), dma_addr, size); -#endif } /* _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |