Messages in this thread Patch in this message | | | From | Becky Bruce <> | Subject | [PATCH 09/11] swiotlb: add swiotlb_map/unmap_page | Date | Thu, 18 Dec 2008 23:11:20 -0600 |
| |
Also, change swiotlb_map/unmap_single to call the page versions by converting the arguments into a page address and offset.
Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- include/linux/swiotlb.h | 10 +++++++ lib/swiotlb.c | 63 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 20 deletions(-)
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index f4d1be3..ecb5eac 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -79,6 +79,16 @@ swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, enum dma_data_direction dir); +extern dma_addr_t +swiotlb_map_page_attrs(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs); + +extern void +swiotlb_unmap_page_attrs(struct device *hwdev, dma_addr_t dev_addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs); + extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); diff --git a/lib/swiotlb.c b/lib/swiotlb.c index fc906d5..166aa78 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -606,19 +606,17 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir, } } -/* - * Map a single buffer of the indicated size for DMA in streaming mode. The - * physical address to use is returned. - * - * Once the device is given the dma address, the device owns this memory until - * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. - */ -dma_addr_t -swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, - enum dma_data_direction dir, struct dma_attrs *attrs) +dma_addr_t swiotlb_map_page_attrs(struct device *hwdev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) { - dma_addr_t dev_addr = virt_to_dma_addr(hwdev, ptr); + dma_addr_t dev_addr; void *map; + phys_addr_t phys; + + phys = page_to_phys(page) + offset; + dev_addr = phys_to_dma_addr(hwdev, phys); BUG_ON(dir == DMA_NONE); /* @@ -633,7 +631,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, /* * Oh well, have to allocate and map a bounce buffer. */ - map = map_single(hwdev, virt_to_phys(ptr), size, dir); + map = map_single(hwdev, phys, size, dir); if (!map) { swiotlb_full(hwdev, size, dir, 1); map = io_tlb_overflow_buffer; @@ -646,9 +644,40 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, */ if (swiotlb_addr_needs_mapping(hwdev, dev_addr, size)) panic("map_single: bounce buffer is not DMA'ble"); - return dev_addr; } +EXPORT_SYMBOL(swiotlb_map_page_attrs); + +void swiotlb_unmap_page_attrs(struct device *hwdev, dma_addr_t dev_addr, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + char *dma_addr = dma_addr_to_virt(hwdev, dev_addr); + + BUG_ON(dir == DMA_NONE); + if (is_swiotlb_buffer(dma_addr)) + unmap_single(hwdev, dma_addr, size, dir); + else if (dir == DMA_FROM_DEVICE) + dma_mark_clean(dma_addr, size); + +} +EXPORT_SYMBOL(swiotlb_unmap_page_attrs); + +/* + * Map a single buffer of the indicated size for DMA in streaming mode. The + * physical address to use is returned. + * + * Once the device is given the dma address, the device owns this memory until + * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. + */ +dma_addr_t +swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) +{ + return swiotlb_map_page_attrs(hwdev, virt_to_page(ptr), + (unsigned long)ptr % PAGE_SIZE, + size, dir, attrs); +} EXPORT_SYMBOL(swiotlb_map_single_attrs); dma_addr_t @@ -671,13 +700,7 @@ swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - char *dma_addr = dma_addr_to_virt(hwdev, dev_addr); - - BUG_ON(dir == DMA_NONE); - if (is_swiotlb_buffer(dma_addr)) - unmap_single(hwdev, dma_addr, size, dir); - else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(dma_addr, size); + return swiotlb_unmap_page_attrs(hwdev, dev_addr, size, dir, attrs); } EXPORT_SYMBOL(swiotlb_unmap_single_attrs); -- 1.5.6.5
| |