Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
Hi all, Here''s a work in progress series whcih does a partial revert of the previous swiotlb changes, and does a partial replacement with Becky Bruce''s series. The most important difference is Becky''s use of phys_addr_t rather than page+offset to represent arbitrary pages. This turns out to be simpler. I didn''t replicate the map_single_page changes, since I''m not exactly sure of ppc''s requirements here, and it seemed like something that could be easily added. Quick testing showed no problems, but I haven''t had the chance to do anything extensive. I''ve made some small changes to Becky''s patches to make them apply, but I''ve separated any functional changes into separate patches with appropriate authorship. J _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 1 of 9] revert "swiotlb: support bouncing of HighMem pages."
git commit ef9b189352f2eb78f14e52996f4780a523b04a49 --- lib/swiotlb.c | 122 +++++++++++++++------------------------------------------ 1 file changed, 33 insertions(+), 89 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -26,7 +26,6 @@ #include <linux/swiotlb.h> #include <linux/types.h> #include <linux/ctype.h> -#include <linux/highmem.h> #include <asm/io.h> #include <asm/dma.h> @@ -39,6 +38,9 @@ #define OFFSET(val,align) ((unsigned long) \ ( (val) & ( (align) - 1))) +#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) +#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) + #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) /* @@ -89,10 +91,7 @@ * We need to save away the original address corresponding to a mapped entry * for the sync operations. */ -static struct swiotlb_phys_addr { - struct page *page; - unsigned int offset; -} *io_tlb_orig_addr; +static unsigned char **io_tlb_orig_addr; /* * Protect the above data structures in the map and unmap calls @@ -151,11 +150,6 @@ return 0; } -static dma_addr_t swiotlb_sg_to_bus(struct scatterlist *sg) -{ - return swiotlb_phys_to_bus(page_to_phys(sg_page(sg)) + sg->offset); -} - static void swiotlb_print_info(unsigned long bytes) { phys_addr_t pstart, pend; @@ -215,7 +209,7 @@ for (i = 0; i < io_tlb_nslabs; i++) io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(struct swiotlb_phys_addr)); + io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); /* * Get the overflow emergency buffer @@ -289,12 +283,12 @@ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = (struct swiotlb_phys_addr *)__get_free_pages(GFP_KERNEL, - get_order(io_tlb_nslabs * sizeof(struct swiotlb_phys_addr))); + io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, + get_order(io_tlb_nslabs * sizeof(char *))); if (!io_tlb_orig_addr) goto cleanup3; - memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(struct swiotlb_phys_addr)); + memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); /* * Get the overflow emergency buffer @@ -341,59 +335,20 @@ return addr >= io_tlb_start && addr < io_tlb_end; } -static struct swiotlb_phys_addr swiotlb_bus_to_phys_addr(char *dma_addr) +static void +__sync_single(char *buffer, char *dma_addr, size_t size, int dir) { - int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - struct swiotlb_phys_addr buffer = io_tlb_orig_addr[index]; - buffer.offset += (long)dma_addr & ((1 << IO_TLB_SHIFT) - 1); - buffer.page += buffer.offset >> PAGE_SHIFT; - buffer.offset &= PAGE_SIZE - 1; - return buffer; -} - -static void -__sync_single(struct swiotlb_phys_addr buffer, char *dma_addr, size_t size, int dir) -{ - if (PageHighMem(buffer.page)) { - size_t len, bytes; - char *dev, *host, *kmp; - - len = size; - while (len != 0) { - unsigned long flags; - - bytes = len; - if ((bytes + buffer.offset) > PAGE_SIZE) - bytes = PAGE_SIZE - buffer.offset; - local_irq_save(flags); /* protects KM_BOUNCE_READ */ - kmp = kmap_atomic(buffer.page, KM_BOUNCE_READ); - dev = dma_addr + size - len; - host = kmp + buffer.offset; - if (dir == DMA_FROM_DEVICE) - memcpy(host, dev, bytes); - else - memcpy(dev, host, bytes); - kunmap_atomic(kmp, KM_BOUNCE_READ); - local_irq_restore(flags); - len -= bytes; - buffer.page++; - buffer.offset = 0; - } - } else { - void *v = page_address(buffer.page) + buffer.offset; - - if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, v, size); - else - memcpy(v, dma_addr, size); - } + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, buffer, size); + else + memcpy(buffer, dma_addr, size); } /* * Allocates bounce buffer and returns its kernel virtual address. */ static void * -map_single(struct device *hwdev, struct swiotlb_phys_addr buffer, size_t size, int dir) +map_single(struct device *hwdev, char *buffer, size_t size, int dir) { unsigned long flags; char *dma_addr; @@ -403,7 +358,6 @@ unsigned long mask; unsigned long offset_slots; unsigned long max_slots; - struct swiotlb_phys_addr slot_buf; mask = dma_get_seg_boundary(hwdev); start_dma_addr = swiotlb_virt_to_bus(io_tlb_start) & mask; @@ -488,13 +442,8 @@ * This is needed when we sync the memory. Then we sync the buffer if * needed. */ - slot_buf = buffer; - for (i = 0; i < nslots; i++) { - slot_buf.page += slot_buf.offset >> PAGE_SHIFT; - slot_buf.offset &= PAGE_SIZE - 1; - io_tlb_orig_addr[index+i] = slot_buf; - slot_buf.offset += 1 << IO_TLB_SHIFT; - } + for (i = 0; i < nslots; i++) + io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); @@ -510,12 +459,12 @@ unsigned long flags; int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - struct swiotlb_phys_addr buffer = swiotlb_bus_to_phys_addr(dma_addr); + char *buffer = io_tlb_orig_addr[index]; /* * First, sync the memory before unmapping the entry */ - if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)) + if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) /* * bounce... copy the data back into the original buffer * and * delete the bounce buffer. @@ -552,7 +501,10 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir, int target) { - struct swiotlb_phys_addr buffer = swiotlb_bus_to_phys_addr(dma_addr); + int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; + char *buffer = io_tlb_orig_addr[index]; + + buffer += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); switch (target) { case SYNC_FOR_CPU: @@ -600,10 +552,7 @@ * swiotlb_map_single(), which will grab memory from * the lowest available address range. */ - struct swiotlb_phys_addr buffer; - buffer.page = virt_to_page(NULL); - buffer.offset = 0; - ret = map_single(hwdev, buffer, size, DMA_FROM_DEVICE); + ret = map_single(hwdev, NULL, size, DMA_FROM_DEVICE); if (!ret) return NULL; } @@ -671,7 +620,6 @@ { dma_addr_t dev_addr = swiotlb_virt_to_bus(ptr); void *map; - struct swiotlb_phys_addr buffer; BUG_ON(dir == DMA_NONE); /* @@ -686,9 +634,7 @@ /* * Oh well, have to allocate and map a bounce buffer. */ - buffer.page = virt_to_page(ptr); - buffer.offset = (unsigned long)ptr & ~PAGE_MASK; - map = map_single(hwdev, buffer, size, dir); + map = map_single(hwdev, ptr, size, dir); if (!map) { swiotlb_full(hwdev, size, dir, 1); map = io_tlb_overflow_buffer; @@ -833,20 +779,18 @@ int dir, struct dma_attrs *attrs) { struct scatterlist *sg; - struct swiotlb_phys_addr buffer; + void *addr; dma_addr_t dev_addr; int i; BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - dev_addr = swiotlb_sg_to_bus(sg); + addr = SG_ENT_VIRT_ADDRESS(sg); + dev_addr = swiotlb_virt_to_bus(addr); if (range_needs_mapping(sg_virt(sg), sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { - void *map; - buffer.page = sg_page(sg); - buffer.offset = sg->offset; - map = map_single(hwdev, buffer, sg->length, dir); + void *map = map_single(hwdev, addr, sg->length, dir); if (!map) { /* Don''t panic here, we expect map_sg users to do proper error handling. */ @@ -886,11 +830,11 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != swiotlb_sg_to_bus(sg)) + if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); + dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } } EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); @@ -919,11 +863,11 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != swiotlb_sg_to_bus(sg)) + if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir, target); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); + dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 2 of 9] revert "swiotlb: factor out copy to/from device."
git commit 1b548f667c1487d92e794a9f7a67788f49b952d8 --- lib/swiotlb.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -335,15 +335,6 @@ return addr >= io_tlb_start && addr < io_tlb_end; } -static void -__sync_single(char *buffer, char *dma_addr, size_t size, int dir) -{ - if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, buffer, size); - else - memcpy(buffer, dma_addr, size); -} - /* * Allocates bounce buffer and returns its kernel virtual address. */ @@ -445,7 +436,7 @@ for (i = 0; i < nslots; i++) io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) - __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); + memcpy(dma_addr, buffer, size); return dma_addr; } @@ -469,7 +460,7 @@ * bounce... copy the data back into the original buffer * and * delete the bounce buffer. */ - __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); + memcpy(buffer, dma_addr, size); /* * Return the buffer to the free list by setting the corresponding @@ -509,13 +500,13 @@ switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); + memcpy(buffer, dma_addr, size); else BUG_ON(dir != DMA_TO_DEVICE); break; case SYNC_FOR_DEVICE: if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) - __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); + memcpy(dma_addr, buffer, size); else BUG_ON(dir != DMA_FROM_DEVICE); break; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 3 of 9] swiotlb: add hwdev to swiotlb_phys_to_bus
Some architectures need it. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> --- arch/x86/kernel/pci-swiotlb_64.c | 2 - include/linux/swiotlb.h | 3 +- lib/swiotlb.c | 45 +++++++++++++++----------------------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -23,7 +23,7 @@ return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order); } -dma_addr_t swiotlb_phys_to_bus(phys_addr_t paddr) +dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) { return paddr; } diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -27,7 +27,8 @@ extern void *swiotlb_alloc_boot(size_t bytes, unsigned long nslabs); extern void *swiotlb_alloc(unsigned order, unsigned long nslabs); -extern dma_addr_t swiotlb_phys_to_bus(phys_addr_t address); +extern dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, + phys_addr_t address); extern phys_addr_t swiotlb_bus_to_phys(dma_addr_t address); extern int swiotlb_arch_range_needs_mapping(void *ptr, size_t size); diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -125,7 +125,7 @@ return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order); } -dma_addr_t __weak swiotlb_phys_to_bus(phys_addr_t paddr) +dma_addr_t __weak swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) { return paddr; } @@ -135,9 +135,10 @@ return baddr; } -static dma_addr_t swiotlb_virt_to_bus(volatile void *address) +static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, + volatile void *address) { - return swiotlb_phys_to_bus(virt_to_phys(address)); + return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); } static void *swiotlb_bus_to_virt(dma_addr_t address) @@ -153,27 +154,15 @@ static void swiotlb_print_info(unsigned long bytes) { phys_addr_t pstart, pend; - dma_addr_t bstart, bend; pstart = virt_to_phys(io_tlb_start); pend = virt_to_phys(io_tlb_end); - bstart = swiotlb_phys_to_bus(pstart); - bend = swiotlb_phys_to_bus(pend); - printk(KERN_INFO "Placing %luMB software IO TLB between %p - %p\n", bytes >> 20, io_tlb_start, io_tlb_end); - if (pstart != bstart || pend != bend) - printk(KERN_INFO "software IO TLB at phys %#llx - %#llx" - " bus %#llx - %#llx\n", - (unsigned long long)pstart, - (unsigned long long)pend, - (unsigned long long)bstart, - (unsigned long long)bend); - else - printk(KERN_INFO "software IO TLB at phys %#llx - %#llx\n", - (unsigned long long)pstart, - (unsigned long long)pend); + printk(KERN_INFO "software IO TLB at phys %#llx - %#llx\n", + (unsigned long long)pstart, + (unsigned long long)pend); } /* @@ -351,7 +340,7 @@ unsigned long max_slots; mask = dma_get_seg_boundary(hwdev); - start_dma_addr = swiotlb_virt_to_bus(io_tlb_start) & mask; + start_dma_addr = swiotlb_virt_to_bus(hwdev, io_tlb_start) & mask; offset_slots = ALIGN(start_dma_addr, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; @@ -528,7 +517,9 @@ dma_mask = hwdev->coherent_dma_mask; ret = (void *)__get_free_pages(flags, order); - if (ret && !is_buffer_dma_capable(dma_mask, swiotlb_virt_to_bus(ret), size)) { + if (ret && + !is_buffer_dma_capable(dma_mask, swiotlb_virt_to_bus(hwdev, ret), + size)) { /* * The allocated memory isn''t reachable by the device. * Fall back on swiotlb_map_single(). @@ -549,7 +540,7 @@ } memset(ret, 0, size); - dev_addr = swiotlb_virt_to_bus(ret); + dev_addr = swiotlb_virt_to_bus(hwdev, ret); /* Confirm address can be DMA''d by device */ if (!is_buffer_dma_capable(dma_mask, dev_addr, size)) { @@ -609,7 +600,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, int dir, struct dma_attrs *attrs) { - dma_addr_t dev_addr = swiotlb_virt_to_bus(ptr); + dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, ptr); void *map; BUG_ON(dir == DMA_NONE); @@ -631,7 +622,7 @@ map = io_tlb_overflow_buffer; } - dev_addr = swiotlb_virt_to_bus(map); + dev_addr = swiotlb_virt_to_bus(hwdev, map); /* * Ensure that the address returned is DMA''ble @@ -778,7 +769,7 @@ for_each_sg(sgl, sg, nelems, i) { addr = SG_ENT_VIRT_ADDRESS(sg); - dev_addr = swiotlb_virt_to_bus(addr); + dev_addr = swiotlb_virt_to_bus(hwdev, addr); if (range_needs_mapping(sg_virt(sg), sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { void *map = map_single(hwdev, addr, sg->length, dir); @@ -791,7 +782,7 @@ sgl[0].dma_length = 0; return 0; } - sg->dma_address = swiotlb_virt_to_bus(map); + sg->dma_address = swiotlb_virt_to_bus(hwdev, map); } else sg->dma_address = dev_addr; sg->dma_length = sg->length; @@ -879,7 +870,7 @@ int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) { - return (dma_addr == swiotlb_virt_to_bus(io_tlb_overflow_buffer)); + return (dma_addr == swiotlb_virt_to_bus(hwdev, io_tlb_overflow_buffer)); } /* @@ -891,7 +882,7 @@ int swiotlb_dma_supported(struct device *hwdev, u64 mask) { - return swiotlb_virt_to_bus(io_tlb_end - 1) <= mask; + return swiotlb_virt_to_bus(hwdev, io_tlb_end - 1) <= mask; } EXPORT_SYMBOL(swiotlb_map_single); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 4 of 9] swiotlb: Drop SG_ENT_VIRT_ADDRESS macro
From: Becky Bruce <beckyb@kernel.crashing.org> All SG_ENT_VIRT_ADDRESS does is call sg_virt(), get rid of this needless layer of complexity. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -38,8 +38,7 @@ #define OFFSET(val,align) ((unsigned long) \ ( (val) & ( (align) - 1))) -#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) -#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) +#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(sg_virt(sg)) #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) @@ -768,9 +767,9 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - addr = SG_ENT_VIRT_ADDRESS(sg); + addr = sg_virt(sg); dev_addr = swiotlb_virt_to_bus(hwdev, addr); - if (range_needs_mapping(sg_virt(sg), sg->length) || + if (range_needs_mapping(addr, sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { void *map = map_single(hwdev, addr, sg->length, dir); if (!map) { @@ -816,7 +815,7 @@ unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); + dma_mark_clean(sg_virt(sg), sg->dma_length); } } EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); @@ -849,7 +848,7 @@ sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir, target); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); + dma_mark_clean(sg_virt(sg), sg->dma_length); } } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 5 of 9] swiotlb: Rename SG_ENT_PHYS_ADDRESS to SG_ENT_BUS_ADDRESS
From: Becky Bruce <beckyb@kernel.crashing.org> Also add hwdev argument - some platforms will need this to calculate an actual bus address. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -38,7 +38,7 @@ #define OFFSET(val,align) ((unsigned long) \ ( (val) & ( (align) - 1))) -#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(sg_virt(sg)) +#define SG_ENT_BUS_ADDRESS(hwdev, sg) swiotlb_virt_to_bus(hwdev, sg_virt(sg)) #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) @@ -811,7 +811,7 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) + if (sg->dma_address != SG_ENT_BUS_ADDRESS(hwdev, sg)) unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) @@ -844,7 +844,7 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) + if (sg->dma_address != SG_ENT_BUS_ADDRESS(hwdev, sg)) sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir, target); else if (dir == DMA_FROM_DEVICE) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 6 of 9] swiotlb: Store phys address in io_tlb_orig_addr array
From: Becky Bruce <beckyb@kernel.crashing.org> When we enable swiotlb for platforms that support HIGHMEM, we can no longer store the virtual address of the original dma buffer, because that buffer might not have a permament mapping. Change the iotlb code to instead store the physical address of the original buffer. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 47 ++++++++++++++++++++++++----------------------- 1 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -90,7 +90,7 @@ * We need to save away the original address corresponding to a mapped entry * for the sync operations. */ -static unsigned char **io_tlb_orig_addr; +static phys_addr_t *io_tlb_orig_addr; /* * Protect the above data structures in the map and unmap calls @@ -197,7 +197,7 @@ for (i = 0; i < io_tlb_nslabs; i++) io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); + io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(phys_addr_t)); /* * Get the overflow emergency buffer @@ -271,12 +271,14 @@ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, - get_order(io_tlb_nslabs * sizeof(char *))); + io_tlb_orig_addr = (phys_addr_t *) + __get_free_pages(GFP_KERNEL, + get_order(io_tlb_nslabs * + sizeof(phys_addr_t))); if (!io_tlb_orig_addr) goto cleanup3; - memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); + memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(phys_addr_t)); /* * Get the overflow emergency buffer @@ -291,8 +293,8 @@ return 0; cleanup4: - free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs * - sizeof(char *))); + free_pages((unsigned long)io_tlb_orig_addr, + get_order(io_tlb_nslabs * sizeof(phys_addr_t))); io_tlb_orig_addr = NULL; cleanup3: free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * @@ -327,7 +329,7 @@ * Allocates bounce buffer and returns its kernel virtual address. */ static void * -map_single(struct device *hwdev, char *buffer, size_t size, int dir) +map_single(struct device *hwdev, phys_addr_t phys, size_t size, int dir) { unsigned long flags; char *dma_addr; @@ -422,9 +424,9 @@ * needed. */ for (i = 0; i < nslots; i++) - io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); + io_tlb_orig_addr[index+i] = phys + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) - memcpy(dma_addr, buffer, size); + memcpy(dma_addr, phys_to_virt(phys), size); return dma_addr; } @@ -438,17 +440,17 @@ unsigned long flags; int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - char *buffer = io_tlb_orig_addr[index]; + phys_addr_t phys = io_tlb_orig_addr[index]; /* * First, sync the memory before unmapping the entry */ - if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) + if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) /* * bounce... copy the data back into the original buffer * and * delete the bounce buffer. */ - memcpy(buffer, dma_addr, size); + memcpy(phys_to_virt(phys), dma_addr, size); /* * Return the buffer to the free list by setting the corresponding @@ -481,20 +483,20 @@ int dir, int target) { int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - char *buffer = io_tlb_orig_addr[index]; + phys_addr_t phys = io_tlb_orig_addr[index]; - buffer += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); + phys += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(buffer, dma_addr, size); + memcpy(phys_to_virt(phys), dma_addr, size); else BUG_ON(dir != DMA_TO_DEVICE); break; case SYNC_FOR_DEVICE: if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(dma_addr, buffer, size); + memcpy(dma_addr, phys_to_virt(phys), size); else BUG_ON(dir != DMA_FROM_DEVICE); break; @@ -533,7 +535,7 @@ * swiotlb_map_single(), which will grab memory from * the lowest available address range. */ - ret = map_single(hwdev, NULL, size, DMA_FROM_DEVICE); + ret = map_single(hwdev, 0, size, DMA_FROM_DEVICE); if (!ret) return NULL; } @@ -615,7 +617,7 @@ /* * Oh well, have to allocate and map a bounce buffer. */ - map = map_single(hwdev, ptr, size, dir); + map = map_single(hwdev, virt_to_phys(ptr), size, dir); if (!map) { swiotlb_full(hwdev, size, dir, 1); map = io_tlb_overflow_buffer; @@ -760,18 +762,18 @@ int dir, struct dma_attrs *attrs) { struct scatterlist *sg; - void *addr; - dma_addr_t dev_addr; int i; BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - addr = sg_virt(sg); - dev_addr = swiotlb_virt_to_bus(hwdev, addr); + void *addr = sg_virt(sg); + dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, addr); + if (range_needs_mapping(addr, sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { - void *map = map_single(hwdev, addr, sg->length, dir); + void *map = map_single(hwdev, sg_phys(sg), + sg->length, dir); if (!map) { /* Don''t panic here, we expect map_sg users to do proper error handling. */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 7 of 9] swiotlb: Add support for systems with highmem
From: Becky Bruce <beckyb@kernel.crashing.org> On highmem systems, the original dma buffer might not have a virtual mapping - we need to kmap it in to perform the bounce. Extract the code that does the actual copy into a function that does the kmap if highmem is enabled, and defaults to the normal swiotlb memcpy if not. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 45 insertions(+), 8 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -14,6 +14,7 @@ * 04/07/.. ak Better overflow handling. Assorted fixes. * 05/09/10 linville Add support for syncing ranges, support syncing for * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup. + * 08/12/11 beckyb Add highmem support */ #include <linux/cache.h> @@ -26,6 +27,7 @@ #include <linux/swiotlb.h> #include <linux/types.h> #include <linux/ctype.h> +#include <linux/highmem.h> #include <asm/io.h> #include <asm/dma.h> @@ -326,6 +328,45 @@ } /* + * 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) +{ +#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; + + 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 (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; + phys += sz; + dma_addr += sz; + offset = 0; + } +#else + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, phys_to_virt(phys), size); + else + memcpy(phys_to_virt(phys), dma_addr, size); +#endif +} + +/* * Allocates bounce buffer and returns its kernel virtual address. */ static void * @@ -426,7 +467,7 @@ for (i = 0; i < nslots; i++) io_tlb_orig_addr[index+i] = phys + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) - memcpy(dma_addr, phys_to_virt(phys), size); + swiotlb_bounce(phys, dma_addr, size, DMA_TO_DEVICE); return dma_addr; } @@ -446,11 +487,7 @@ * First, sync the memory before unmapping the entry */ if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) - /* - * bounce... copy the data back into the original buffer * and - * delete the bounce buffer. - */ - memcpy(phys_to_virt(phys), dma_addr, size); + swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); /* * Return the buffer to the free list by setting the corresponding @@ -490,13 +527,13 @@ switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(phys_to_virt(phys), dma_addr, size); + swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); else BUG_ON(dir != DMA_TO_DEVICE); break; case SYNC_FOR_DEVICE: if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(dma_addr, phys_to_virt(phys), size); + swiotlb_bounce(phys, dma_addr, size, DMA_TO_DEVICE); else BUG_ON(dir != DMA_FROM_DEVICE); break; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[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@citrix.com> --- 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@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-22 18:26 UTC
[Xen-devel] [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops
From: Becky Bruce <beckyb@kernel.crashing.org> SWIOTLB currently uses "int" as the type of the dma direction, not "enum dma_data_direction as documented in DMA_API.txt. Now that this code is about to become shared with powerpc, which uses the enum, update the swiotlb code to use the enum as well. Doing this requires changing all the arch''s that use swiotlb use the enum also. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ arch/ia64/hp/common/sba_iommu.c | 12 ++++--- arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ arch/ia64/kernel/machvec.c | 6 ++- arch/ia64/sn/kernel/io_common.c | 3 +- arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- arch/ia64/sn/pci/tioca_provider.c | 3 +- arch/x86/include/asm/dma-mapping.h | 50 ++++++++++++++++++-------------- arch/x86/include/asm/swiotlb.h | 24 +++++++++------ arch/x86/include/asm/tce.h | 3 +- arch/x86/kernel/amd_iommu.c | 16 +++++----- arch/x86/kernel/pci-calgary_64.c | 11 ++++--- arch/x86/kernel/pci-gart_64.c | 19 ++++++++---- arch/x86/kernel/pci-nommu.c | 4 +- arch/x86/kernel/pci-swiotlb_64.c | 2 +- arch/x86/kernel/tce_64.c | 3 +- drivers/pci/intel-iommu.c | 13 ++++---- include/linux/intel-iommu.h | 12 +++++-- include/linux/swiotlb.h | 33 ++++++++++++--------- lib/swiotlb.c | 54 ++++++++++++++++++++--------------- 23 files changed, 219 insertions(+), 159 deletions(-) diff --git a/arch/ia64/dig/dig_vtd_iommu.c b/arch/ia64/dig/dig_vtd_iommu.c --- a/arch/ia64/dig/dig_vtd_iommu.c +++ b/arch/ia64/dig/dig_vtd_iommu.c @@ -21,7 +21,7 @@ dma_addr_t vtd_map_single_attrs(struct device *dev, void *addr, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { return intel_map_single(dev, (phys_addr_t)addr, size, dir); } @@ -29,7 +29,7 @@ void vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { intel_unmap_single(dev, iova, size, dir); } @@ -37,7 +37,7 @@ int vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { return intel_map_sg(dev, sglist, nents, dir); } @@ -45,7 +45,8 @@ void vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, - int nents, int dir, struct dma_attrs *attrs) + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) { intel_unmap_sg(dev, sglist, nents, dir); } diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -91,8 +91,8 @@ } dma_addr_t -hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, - struct dma_attrs *attrs) +hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_map_single_attrs(dev, addr, size, dir, attrs); @@ -103,7 +103,7 @@ void hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs); @@ -114,7 +114,7 @@ int hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs); @@ -125,7 +125,7 @@ void hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs); @@ -135,7 +135,8 @@ EXPORT_SYMBOL(hwsw_unmap_sg_attrs); void -hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir) +hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_single_for_cpu(dev, addr, size, dir); @@ -144,7 +145,8 @@ } void -hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir) +hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir); @@ -153,7 +155,8 @@ } void -hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir) +hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_single_for_device(dev, addr, size, dir); @@ -162,7 +165,8 @@ } void -hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir) +hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_sg_for_device(dev, sg, nelems, dir); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -909,8 +909,8 @@ * See Documentation/DMA-mapping.txt */ dma_addr_t -sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, - struct dma_attrs *attrs) +sba_map_single_attrs(struct device *dev, void *addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) { struct ioc *ioc; dma_addr_t iovp; @@ -1027,7 +1027,8 @@ * See Documentation/DMA-mapping.txt */ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, + struct dma_attrs *attrs) { struct ioc *ioc; #if DELAYED_RESOURCE_CNT > 0 @@ -1423,7 +1424,7 @@ * See Documentation/DMA-mapping.txt */ int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { struct ioc *ioc; int coalesced, filled = 0; @@ -1515,7 +1516,8 @@ * See Documentation/DMA-mapping.txt */ void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, - int nents, int dir, struct dma_attrs *attrs) + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) { #ifdef ASSERT_PDIR_SANITY struct ioc *ioc; diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -17,32 +17,32 @@ void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_single)(struct device *hwdev, unsigned long ptr, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*unmap_single)(struct device *dev, dma_addr_t addr, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*sync_single_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_for_device)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_range_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*sync_single_range_for_device)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*sync_sg_for_cpu)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); void (*sync_sg_for_device)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); int (*map_sg)(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); void (*unmap_sg)(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); int (*dma_supported_op)(struct device *hwdev, u64 mask); int is_phys; }; @@ -70,25 +70,26 @@ } #define dma_map_single_attrs platform_dma_map_single_attrs static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, - size_t size, int dir) + size_t size, + enum dma_data_direction dir) { return dma_map_single_attrs(dev, cpu_addr, size, dir, NULL); } #define dma_map_sg_attrs platform_dma_map_sg_attrs static inline int dma_map_sg(struct device *dev, struct scatterlist *sgl, - int nents, int dir) + int nents, enum dma_data_direction dir) { return dma_map_sg_attrs(dev, sgl, nents, dir, NULL); } #define dma_unmap_single_attrs platform_dma_unmap_single_attrs static inline void dma_unmap_single(struct device *dev, dma_addr_t cpu_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { return dma_unmap_single_attrs(dev, cpu_addr, size, dir, NULL); } #define dma_unmap_sg_attrs platform_dma_unmap_sg_attrs static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl, - int nents, int dir) + int nents, enum dma_data_direction dir) { return dma_unmap_sg_attrs(dev, sgl, nents, dir, NULL); } diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h --- a/arch/ia64/include/asm/swiotlb.h +++ b/arch/ia64/include/asm/swiotlb.h @@ -6,35 +6,41 @@ /* SWIOTLB interface */ extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c --- a/arch/ia64/kernel/machvec.c +++ b/arch/ia64/kernel/machvec.c @@ -75,14 +75,16 @@ EXPORT_SYMBOL(machvec_timer_interrupt); void -machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, size_t size, int dir) +machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir) { mb(); } EXPORT_SYMBOL(machvec_dma_sync_single); void -machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, int dir) +machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, + enum dma_data_direction dir) { mb(); } diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -60,7 +60,8 @@ } static void -sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) +sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, + enum dma_data_direction direction) { return; } diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -174,7 +174,8 @@ * figure out how to save dmamap handle so can use two step. */ dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr, - size_t size, int direction, + size_t size, + enum dma_data_direction direction, struct dma_attrs *attrs) { dma_addr_t dma_addr; @@ -216,7 +217,8 @@ * coherent, so we just need to free any ATEs associated with this mapping. */ void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction, + size_t size, + enum dma_data_direction direction, struct dma_attrs *attrs) { struct pci_dev *pdev = to_pci_dev(dev); @@ -239,7 +241,7 @@ * Unmap a set of streaming mode DMA translations. */ void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl, - int nhwentries, int direction, + int nhwentries, enum dma_data_direction direction, struct dma_attrs *attrs) { int i; @@ -273,7 +275,8 @@ * Maps each entry of @sg for DMA. */ int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, - int nhwentries, int direction, struct dma_attrs *attrs) + int nhwentries, enum dma_data_direction direction, + struct dma_attrs *attrs) { unsigned long phys_addr; struct scatterlist *saved_sg = sgl, *sg; @@ -323,28 +326,30 @@ EXPORT_SYMBOL(sn_dma_map_sg_attrs); void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, + enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } EXPORT_SYMBOL(sn_dma_sync_single_for_cpu); void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, + enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } EXPORT_SYMBOL(sn_dma_sync_single_for_device); void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu); void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -205,7 +205,8 @@ * DMA mappings for Direct 64 and 32 do not have any DMA maps. */ void -pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction) +pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, + enum dma_data_direction direction) { struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); struct pcibus_info *pcibus_info diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -467,7 +467,8 @@ * resources to release. */ static void -tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) +tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, + enum dma_data_direction dir) { int i, entry; struct tioca_common *tioca_common; diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -25,32 +25,36 @@ void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*unmap_single)(struct device *dev, dma_addr_t addr, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*sync_single_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_for_device)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_range_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*sync_single_range_for_device)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*sync_sg_for_cpu)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); void (*sync_sg_for_device)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); int (*map_sg)(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); void (*unmap_sg)(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); int (*dma_supported)(struct device *hwdev, u64 mask); int is_phys; }; @@ -91,7 +95,7 @@ static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -102,7 +106,7 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(dev); @@ -113,7 +117,7 @@ static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction) + int nents, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -123,7 +127,7 @@ static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -134,7 +138,7 @@ static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -146,7 +150,7 @@ static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -158,7 +162,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, - unsigned long offset, size_t size, int direction) + unsigned long offset, size_t size, + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -172,7 +177,7 @@ static inline void dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -185,7 +190,7 @@ static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -197,7 +202,7 @@ static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -210,7 +215,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(dev); @@ -220,7 +225,8 @@ } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, - size_t size, int direction) + size_t size, + enum dma_data_direction direction) { dma_unmap_single(dev, addr, size, direction); } diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h --- a/arch/x86/include/asm/swiotlb.h +++ b/arch/x86/include/asm/swiotlb.h @@ -6,35 +6,39 @@ /* SWIOTLB interface */ extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); diff --git a/arch/x86/include/asm/tce.h b/arch/x86/include/asm/tce.h --- a/arch/x86/include/asm/tce.h +++ b/arch/x86/include/asm/tce.h @@ -39,7 +39,8 @@ #define TCE_RPN_MASK 0x0000fffffffff000ULL extern void tce_build(struct iommu_table *tbl, unsigned long index, - unsigned int npages, unsigned long uaddr, int direction); + unsigned int npages, unsigned long uaddr, + enum dma_data_direction direction); extern void tce_free(struct iommu_table *tbl, long index, unsigned int npages); extern void * __init alloc_tce_table(void); extern void __init free_tce_table(void *tbl); diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -873,7 +873,7 @@ struct dma_ops_domain *dom, unsigned long address, phys_addr_t paddr, - int direction) + enum dma_data_direction direction) { u64 *pte, __pte; @@ -933,7 +933,7 @@ struct dma_ops_domain *dma_dom, phys_addr_t paddr, size_t size, - int dir, + enum dma_data_direction dir, bool align, u64 dma_mask) { @@ -980,7 +980,7 @@ struct dma_ops_domain *dma_dom, dma_addr_t dma_addr, size_t size, - int dir) + enum dma_data_direction dir) { dma_addr_t i, start; unsigned int pages; @@ -1010,7 +1010,7 @@ * The exported map_single function for dma_ops. */ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1048,7 +1048,7 @@ * The exported unmap_single function for dma_ops. */ static void unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1074,7 +1074,7 @@ * device which is not handled by an AMD IOMMU in the system. */ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -1092,7 +1092,7 @@ * lists). */ static int map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1154,7 +1154,7 @@ * lists). */ static void unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -297,7 +297,8 @@ } static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl, - void *vaddr, unsigned int npages, int direction) + void *vaddr, unsigned int npages, + enum dma_data_direction direction) { unsigned long entry; dma_addr_t ret = bad_dma_address; @@ -381,7 +382,7 @@ } static void calgary_unmap_sg(struct device *dev, - struct scatterlist *sglist, int nelems, int direction) + struct scatterlist *sglist, int nelems, enum dma_data_direction dir) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -404,7 +405,7 @@ } static int calgary_map_sg(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -446,7 +447,7 @@ } static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { void *vaddr = phys_to_virt(paddr); unsigned long uaddr; @@ -460,7 +461,7 @@ } static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -188,7 +188,8 @@ # define CLEAR_LEAK(x) #endif -static void iommu_full(struct device *dev, size_t size, int dir) +static void +iommu_full(struct device *dev, size_t size, enum dma_data_direction dir) { /* * Ran out of IOMMU space for this operation. This is very bad. @@ -231,7 +232,8 @@ * Caller needs to check if the iommu is needed and flush. */ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, - size_t size, int dir, unsigned long align_mask) + size_t size, enum dma_data_direction dir, + unsigned long align_mask) { unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); @@ -256,7 +258,8 @@ /* Map a single area into the IOMMU */ static dma_addr_t -gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) +gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { unsigned long bus; @@ -276,7 +279,7 @@ * Free a DMA mapping. */ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { unsigned long iommu_page; int npages; @@ -299,7 +302,8 @@ * Wrapper for pci_unmap_single working with scatterlists. */ static void -gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) +gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -313,7 +317,7 @@ /* Fallback for dma_map_sg in case of overflow */ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, - int nents, int dir) + int nents, enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -401,7 +405,8 @@ * Merge chunks that have page aligned sizes into a continuous mapping. */ static int -gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) +gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) { struct scatterlist *s, *ps, *start_sg, *sgmap; int need = 0, nextneed, i, out, start; diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -27,7 +27,7 @@ static dma_addr_t nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, - int direction) + enum dma_data_direction direction) { dma_addr_t bus = paddr; WARN_ON(size == 0); @@ -54,7 +54,7 @@ * the same here. */ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction) + int nents, enum dma_data_direction direction) { struct scatterlist *s; int i; diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -40,7 +40,7 @@ static dma_addr_t swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, - int direction) + enum dma_data_direction direction) { return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } diff --git a/arch/x86/kernel/tce_64.c b/arch/x86/kernel/tce_64.c --- a/arch/x86/kernel/tce_64.c +++ b/arch/x86/kernel/tce_64.c @@ -46,7 +46,8 @@ } void tce_build(struct iommu_table *tbl, unsigned long index, - unsigned int npages, unsigned long uaddr, int direction) + unsigned int npages, unsigned long uaddr, + enum dma_data_direction direction) { u64* tp; u64 t; diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1819,7 +1819,8 @@ } static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, - size_t size, int dir, u64 dma_mask) + size_t size, + enum dma_data_direction dir, u64 dma_mask) { struct pci_dev *pdev = to_pci_dev(hwdev); struct dmar_domain *domain; @@ -1881,7 +1882,7 @@ } dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { return __intel_map_single(hwdev, paddr, size, dir, to_pci_dev(hwdev)->dma_mask); @@ -1946,7 +1947,7 @@ } void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, - int dir) + enum dma_data_direction dir) { struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; @@ -2026,7 +2027,7 @@ #define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { int i; struct pci_dev *pdev = to_pci_dev(hwdev); @@ -2066,7 +2067,7 @@ } static int intel_nontranslate_map_sg(struct device *hddev, - struct scatterlist *sglist, int nelems, int dir) + struct scatterlist *sglist, int nelems, enum dma_data_direction dir) { int i; struct scatterlist *sg; @@ -2080,7 +2081,7 @@ } int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, - int dir) + enum dma_data_direction dir) { void *addr; int i; diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -355,9 +355,13 @@ extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); -extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int); -extern void intel_unmap_single(struct device *, dma_addr_t, size_t, int); -extern int intel_map_sg(struct device *, struct scatterlist *, int, int); -extern void intel_unmap_sg(struct device *, struct scatterlist *, int, int); +extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, + enum dma_data_direction); +extern void intel_unmap_single(struct device *, dma_addr_t, size_t, + enum dma_data_direction); +extern int intel_map_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); +extern void intel_unmap_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); #endif diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -42,60 +42,65 @@ void *vaddr, dma_addr_t dma_handle); extern dma_addr_t -swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir); +swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, + enum dma_data_direction dir); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern dma_addr_t swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, - int dir, struct dma_attrs *attrs); + enum dma_data_direction dir, + struct dma_attrs *attrs); extern void swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir, struct dma_attrs *attrs); + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); extern int swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir, struct dma_attrs *attrs); + enum dma_data_direction dir, struct dma_attrs *attrs); extern void swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, - int nelems, int dir, struct dma_attrs *attrs); + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir); + int nelems, enum dma_data_direction dir); extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir); + int nelems, enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir); + unsigned long offset, size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, - int dir); + enum dma_data_direction dir); extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -373,7 +373,8 @@ * Allocates bounce buffer and returns its kernel virtual address. */ static void * -map_single(struct device *hwdev, phys_addr_t phys, size_t size, int dir) +map_single(struct device *hwdev, phys_addr_t phys, size_t size, + enum dma_data_direction dir) { unsigned long flags; char *dma_addr; @@ -479,7 +480,8 @@ * dma_addr is the kernel virtual address of the bounce buffer to unmap. */ static void -unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) +unmap_single(struct device *hwdev, char *dma_addr, size_t size, + enum dma_data_direction dir) { unsigned long flags; int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; @@ -520,7 +522,7 @@ static void sync_single(struct device *hwdev, char *dma_addr, size_t size, - int dir, int target) + enum dma_data_direction dir, int target) { int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; phys_addr_t phys = io_tlb_orig_addr[index]; @@ -610,7 +612,8 @@ } static void -swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) +swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir, + int do_panic) { /* * Ran out of IOMMU space for this operation. This is very bad. @@ -639,7 +642,7 @@ */ dma_addr_t swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, ptr); void *map; @@ -676,7 +679,8 @@ EXPORT_SYMBOL(swiotlb_map_single_attrs); dma_addr_t -swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) +swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, + enum dma_data_direction dir) { return swiotlb_map_single_attrs(hwdev, ptr, size, dir, NULL); } @@ -691,7 +695,8 @@ */ void swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir, struct dma_attrs *attrs) + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { char *dma_addr = swiotlb_bus_to_virt(dev_addr); @@ -705,7 +710,7 @@ void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, - int dir) + enum dma_data_direction dir) { return swiotlb_unmap_single_attrs(hwdev, dev_addr, size, dir, NULL); } @@ -721,7 +726,7 @@ */ static void swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir, int target) + size_t size, enum dma_data_direction dir, int target) { char *dma_addr = swiotlb_bus_to_virt(dev_addr); @@ -734,14 +739,14 @@ void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); } void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); } @@ -752,7 +757,7 @@ static void swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, - int dir, int target) + enum dma_data_direction dir, int target) { char *dma_addr = swiotlb_bus_to_virt(dev_addr) + offset; @@ -765,7 +770,8 @@ void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir) + unsigned long offset, size_t size, + enum dma_data_direction dir) { swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, SYNC_FOR_CPU); @@ -773,14 +779,15 @@ void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir) + unsigned long offset, size_t size, + enum dma_data_direction dir) { swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, SYNC_FOR_DEVICE); } -void swiotlb_unmap_sg_attrs(struct device *, struct scatterlist *, int, int, - struct dma_attrs *); +void swiotlb_unmap_sg_attrs(struct device *, struct scatterlist *, int, + enum dma_data_direction, struct dma_attrs *); /* * Map a set of buffers described by scatterlist in streaming mode for DMA. * This is the scatter-gather version of the above swiotlb_map_single @@ -799,7 +806,7 @@ */ int swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { struct scatterlist *sg; int i; @@ -834,7 +841,7 @@ int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir) + enum dma_data_direction dir) { return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL); } @@ -845,7 +852,8 @@ */ void swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, - int nelems, int dir, struct dma_attrs *attrs) + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs) { struct scatterlist *sg; int i; @@ -864,7 +872,7 @@ void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir) + enum dma_data_direction dir) { return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL); } @@ -878,7 +886,7 @@ */ static void swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl, - int nelems, int dir, int target) + int nelems, enum dma_data_direction dir, int target) { struct scatterlist *sg; int i; @@ -896,14 +904,14 @@ void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); } void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-27 10:48 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* Jeremy Fitzhardinge <jeremy@goop.org> wrote:> Hi all, > > Here''s a work in progress series whcih does a partial revert of the > previous swiotlb changes, and does a partial replacement with Becky > Bruce''s series. > > The most important difference is Becky''s use of phys_addr_t rather than > page+offset to represent arbitrary pages. This turns out to be simpler. > > I didn''t replicate the map_single_page changes, since I''m not exactly > sure of ppc''s requirements here, and it seemed like something that could > be easily added. > > Quick testing showed no problems, but I haven''t had the chance to do > anything extensive. > > I''ve made some small changes to Becky''s patches to make them apply, but > I''ve separated any functional changes into separate patches with > appropriate authorship.looks good to me in principle. Fujita-san, do you have any principal objections against these generalizations? Also, this patch will interact with ia64 materially: Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops So we''ll need a bit more confidence in the testing status of this queue, and we probably want to wait until Tony merged the pending .29 ia64 changes, and also get an Ack from Tony for these bits: arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ arch/ia64/hp/common/sba_iommu.c | 12 ++++--- arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ arch/ia64/kernel/machvec.c | 6 ++- arch/ia64/sn/kernel/io_common.c | 3 +- arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- arch/ia64/sn/pci/tioca_provider.c | 3 +- (Tony Cc:-ed) Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-27 16:56 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:> On Sat, 27 Dec 2008 11:48:23 +0100 > Ingo Molnar <mingo@elte.hu> wrote: > > > Also, this patch will interact with ia64 materially: > > > > Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops > > > > So we''ll need a bit more confidence in the testing status of this queue, > > and we probably want to wait until Tony merged the pending .29 ia64 > > changes, and also get an Ack from Tony for these bits: > > > > arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- > > arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ > > arch/ia64/hp/common/sba_iommu.c | 12 ++++--- > > arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- > > arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ > > arch/ia64/kernel/machvec.c | 6 ++- > > arch/ia64/sn/kernel/io_common.c | 3 +- > > arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- > > arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- > > arch/ia64/sn/pci/tioca_provider.c | 3 +- > > > > (Tony Cc:-ed) > > BTW, the above patch breaks IA64 build. > > It''s fixable but I think that it would be better to just drop this huge > patch and add some cast in powerpc code. the types of SWIOTBL function > arguments don''t need to mach to DAM_API.txt though it might be nice if > so. There are other type mismatches. If we really want to do this > cleanups, we should fix up all the mismatches.hm, we shouldnt do ugly typecasts - lets fix all the places. As Jeremy indicated, this is work in progress. Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2008-Dec-28 05:01 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
FUJITA Tomonori wrote:> Well, I asked Jeremy to use Becky''s approach so I don''t have though > this patchset isn''t enough for Becky (possibly for Xen too) since > Jeremy didn''t put Becky''s map_single_page changes. These changes are > necessary to support map_map_page with highmem. I think that we can do > it simpler than his patch. I''ll send patches to that in a different > way soon. > > It''s not principal objection, but as I said, the patches to revert > Jeremy''s highmem patches in this patchset like the following are > pointless. >I don''t mind either way. I was hoping to go with something that I''ve actually tested, but I don''t see any reason why Becky''s patches won''t work in principle for Xen. I''m on vacation at the moment, but I can test things out when I get back in a couple of weeks and apply whatever fixes are needed at whatever stage we''re at then. J _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-28 09:37 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:> If we really want to clean up the dma mapping operations, we should > define struct dma_mapping_ops in a generic place (such as > include/linux/dma-mapping.h) instead each architecture define the own > struct dma_mapping_ops. These dma_mapping_ops structures are very > similar but a bit different. That''s the root cause of the dma mapping > operation ugliness. > > If we do, X86 and IA64 can share swiotlb and intel VTD code cleanly, > X86, IA64, and POWERPC can share swiotlb cleanly too. For example, we > can define swiotlb_dma_ops in lib/swiotlb.c and then everyone can share > it. Currently, X86 and IA64 define the own swiotlb_dma_ops (and X86 > needs swiotlb_map_single_phys hack). It doesn''t make sense.Sure. Note that we went through this process (of unifying dma_mapping_ops) recently on x86 recently - 32-bit and 64-bit x86 had such differences. Note that the main complication wasnt even the small variations in signatures, but the different _semantics_: one dma_mapping_ops implementation passed in kernel-virtual addresses, the other physical addresses. Unifying that was invasive and non-trivial, and it can break stuff not at the build level but at the runtime level. We can expect similar complications when done over 20 architectures as well. But yes, it''s all desired. Obviously extending swiotlb to highmem and using it on xen and powerpc is an essential first step in the direction of generalizing all this code. Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-28 09:50 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* Jeremy Fitzhardinge <jeremy@goop.org> wrote:> FUJITA Tomonori wrote: >> Well, I asked Jeremy to use Becky''s approach so I don''t have though >> this patchset isn''t enough for Becky (possibly for Xen too) since >> Jeremy didn''t put Becky''s map_single_page changes. These changes are >> necessary to support map_map_page with highmem. I think that we can do >> it simpler than his patch. I''ll send patches to that in a different >> way soon. >> >> It''s not principal objection, but as I said, the patches to revert >> Jeremy''s highmem patches in this patchset like the following are >> pointless. >> > > I don''t mind either way. I was hoping to go with something that I''ve > actually tested, but I don''t see any reason why Becky''s patches won''t > work in principle for Xen. I''m on vacation at the moment, but I can > test things out when I get back in a couple of weeks and apply whatever > fixes are needed at whatever stage we''re at then.yes, obviously we prefer append-only - i kept your patches and added the Becky lineup and Fujita''s cleanups on top of that. If they break your Xen swiotlb use it should all be easily bisectable. Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-28 10:34 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:> > Note that the main complication wasnt even the small variations in > > signatures, but the different _semantics_: one dma_mapping_ops > > implementation passed in kernel-virtual addresses, the other physical > > addresses. Unifying that was invasive and non-trivial, and it can > > break > > I guess that you are talking about the dma_map_single difference between > x86_32 and x86_64. As far as I know, Only x64_64 uses physical address > with dma_map_single.yes - dma_map_single() has this signature: static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) on x86 dma_mapping_ops.map_single has this signature: dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, size_t size, int direction); ia64 and powerpc uses kernel-virt addresses for map_single(). So there''s material semantic differences between the dma_mapping_ops implementations.> > stuff not at the build level but at the runtime level. We can expect > > similar complications when done over 20 architectures as well. > > We don''t need to touch 20 architectures. We are talking about unifying > dma_mapping_ops. Only architectures that need to handle multiple dma > mapping operations use the dma_mapping_ops scheme; X86, IA64, POWERPC, > SPARC, and PARISC. Unifying X86, IA64 and POWERPC is a must since they > actually share dma_mapping_ops.if it''s just dma_mapping_ops - then it''s those 3 architectures. But there''s no reason why the various DMA bouncing implementations in other architectures couldnt use the common code - for example couldnt arch/arm/common/dmabounce.c use the swiotlb too?> > But yes, it''s all desired. Obviously extending swiotlb to highmem and > > using it on xen and powerpc is an essential first step in the > > direction of generalizing all this code. > > No, it''s not about swiotlb highmem patchset. > > Due to this problem, IA64 and X86_64 share swiotlb in a very hacky way. > We added more hacky code due to this problem again when we added VT-d > support to IA64. > > This problem has been for long time. We added ugly hacks again and again > instead of fixing the root cause.well the swiotlb highmem patches are what enable xen (and now powerpc too) to make full use of the swiotlb dma bouncing facilities. And that gives a common platform for unifying all the rest of the lowlevel DMA mapping APIs as well. Without that, the swiotlb code is limited, life is going on in separate islands, with everyone doing their own private variations and hacks. We would still probably be nowhere with this had Jeremy not sent the highmem patches. Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-28 11:56 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:> You brought up a different topic, DMA bouncing implementations > unification. DMA bouncing implementations unification is a very nice > cleanup. But it''s not related with Becky''s patch to break IA64 build at > all.All i''m saying is that obviously neither Jeremy''s nor Becky''s patches were created in a vacuum, and had it not been for the need and desire to extend swiotlb we''d not have seen Becky''s 9/9 cleanup patch either. Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ingo Molnar
2008-Dec-28 12:49 UTC
[Xen-devel] Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
* FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:> Ok, I''ll try to fix the root cause. We need lots of changes to IA64 > especially. Hopefully, I can get Tony''s ACK on these changes.great - let me know if you need testing help on the x86 side as well. I.e. we can test some preliminary patch series from you as well, without committing it to anything stable (i.e. keeping open the ability to rebase/redo it) - while waiting for Tony''s ACK. Ingo _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Reasonably Related Threads
- [RFC v3 00/45] dma-mapping: Use unsigned long for dma_attrs
- [PATCH v8 0/19] enable swiotlb-xen on arm and arm64
- [PATCH 00 of 38] xen: add more Xen dom0 support
- [PATCH 35/35] x86: Don't panic if can not alloc buffer for swiotlb
- [PATCH 35/35] x86: Don't panic if can not alloc buffer for swiotlb