[PATCH 09/11] swiotlb: add swiotlb_map/unmap_page

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Becky Bruce
Date: Thursday, December 18, 2008 - 10:11 pm

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

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 00 of 14] swiotlb/x86: lay groundwork for xen dom0 ..., Jeremy Fitzhardinge, (Tue Dec 16, 1:17 pm)
Re: [PATCH 00 of 14] swiotlb/x86: lay groundwork for xen d ..., Jeremy Fitzhardinge, (Wed Dec 17, 9:31 am)
Re: [PATCH 00 of 14] swiotlb/x86: lay groundwork for xen d ..., Jeremy Fitzhardinge, (Wed Dec 17, 11:58 am)
Re: [PATCH 00 of 14] swiotlb/x86: lay groundwork for xen d ..., Jeremy Fitzhardinge, (Thu Dec 18, 1:09 pm)
swiotlb highmem for ppc series, Becky Bruce, (Thu Dec 18, 10:11 pm)
[PATCH 01/11] swiotlb: Drop SG_ENT_VIRT_ADDRESS macro, Becky Bruce, (Thu Dec 18, 10:11 pm)
[PATCH 09/11] swiotlb: add swiotlb_map/unmap_page, Becky Bruce, (Thu Dec 18, 10:11 pm)
Re: swiotlb highmem for ppc series, Becky Bruce, (Thu Dec 18, 10:16 pm)
Re: [PATCH 00 of 14] swiotlb/x86: lay groundwork for xen d ..., Jeremy Fitzhardinge, (Fri Dec 19, 12:02 am)
Re: [PATCH 06/11] swiotlb: Store phys address in io_tlb_or ..., Jeremy Fitzhardinge, (Fri Dec 19, 10:39 am)
Re: [PATCH 07/11] swiotlb: Add support for systems with hi ..., Jeremy Fitzhardinge, (Fri Dec 19, 10:46 am)
Re: [PATCH 00 of 14] swiotlb/x86: lay groundwork for xen d ..., Jeremy Fitzhardinge, (Fri Dec 19, 10:48 am)