Hi Greg, Any chance these can be included in the staging tree soon? They form some fairly fundamental bug fixing for the DMA support on the tsi148. Martyn On 22/03/12 13:27, Martyn Welch wrote: > 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@xxxxxx> > --- > 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; > }; > > /* -- Martyn Welch (Lead Software Engineer) | Registered in England and Wales GE Intelligent Platforms | (3828642) at 100 Barbirolli Square T +44(0)1327322748 | Manchester, M2 3AB E martyn.welch@xxxxxx | VAT:GB 927559189 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel