From 3abc48ae35ef7cff845a8d57322c19cc153fb482 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 22 Mar 2012 13:27:29 +0000 Subject: [PATCH] Staging: VME: Convert TSI148 to use dma_map_single 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 Signed-off-by: Greg Kroah-Hartman --- 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 f50582169b24..cd3c821eb0a6 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 a3ac2fe98816..00b116087d73 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; }; /* -- 2.20.1