[PATCH 1/2] Staging: VME: Convert TSI148 to use dma_map_single

Martyn Welch martyn.welch at ge.com
Thu Mar 22 13:27:29 UTC 2012


The DMA functionality fails to work on some Intel based platforms. Some
recent Intel platforms have an IOMMU. Transferring the DMA descriptors,
which were mapped using virt_to_phys(), failed. This patch updates the
driver to use dma_map_single().

Signed-off-by: Martyn Welch <martyn.welch at ge.com>
---
 drivers/staging/vme/bridges/vme_tsi148.c |   22 +++++++++++++++-------
 drivers/staging/vme/bridges/vme_tsi148.h |    1 +
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index f505821..cd3c821 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -1614,7 +1614,6 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
 	struct vme_dma_pattern *pattern_attr;
 	struct vme_dma_pci *pci_attr;
 	struct vme_dma_vme *vme_attr;
-	dma_addr_t desc_ptr;
 	int retval = 0;
 	struct vme_bridge *tsi148_bridge;
 
@@ -1739,9 +1738,12 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
 		prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
 			list);
 		/* We need the bus address for the pointer */
-		desc_ptr = virt_to_bus(&entry->descriptor);
-		reg_split(desc_ptr, &prev->descriptor.dnlau,
-			&prev->descriptor.dnlal);
+		entry->dma_handle = dma_map_single(tsi148_bridge->parent,
+			&entry->descriptor,
+			sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
+
+		reg_split((unsigned long long)entry->dma_handle,
+			&prev->descriptor.dnlau, &prev->descriptor.dnlal);
 	}
 
 	return 0;
@@ -1784,7 +1786,6 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
 	struct vme_dma_resource *ctrlr;
 	int channel, retval = 0;
 	struct tsi148_dma_entry *entry;
-	dma_addr_t bus_addr;
 	u32 bus_addr_high, bus_addr_low;
 	u32 val, dctlreg = 0;
 	struct vme_bridge *tsi148_bridge;
@@ -1817,11 +1818,13 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
 	entry = list_first_entry(&list->entries, struct tsi148_dma_entry,
 		list);
 
-	bus_addr = virt_to_bus(&entry->descriptor);
+	entry->dma_handle = dma_map_single(tsi148_bridge->parent,
+		&entry->descriptor,
+		sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
 
 	mutex_unlock(&ctrlr->mtx);
 
-	reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
+	reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low);
 
 	iowrite32be(bus_addr_high, bridge->base +
 		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
@@ -1864,10 +1867,15 @@ static int tsi148_dma_list_empty(struct vme_dma_list *list)
 	struct list_head *pos, *temp;
 	struct tsi148_dma_entry *entry;
 
+	struct vme_bridge *tsi148_bridge = list->parent->parent;
+
 	/* detach and free each entry */
 	list_for_each_safe(pos, temp, &list->entries) {
 		list_del(pos);
 		entry = list_entry(pos, struct tsi148_dma_entry, list);
+
+		dma_unmap_single(tsi148_bridge->parent, entry->dma_handle,
+			sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
 		kfree(entry);
 	}
 
diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h
index a3ac2fe..00b1160 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.h
+++ b/drivers/staging/vme/bridges/vme_tsi148.h
@@ -75,6 +75,7 @@ struct tsi148_dma_entry {
 	 */
 	struct tsi148_dma_descriptor descriptor;
 	struct list_head list;
+	dma_addr_t dma_handle;
 };
 
 /*
-- 
1.7.0.4




More information about the devel mailing list