Skip to contentSkip to conversation

swiotlb: fallback to swiotlb for consistent DMA mappings

PATCH New Suresh Siddha 1 participant 1 message Oct 7, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 swiotlb: fallback to swiotlb for consistent DMA mappings

This is mainly needed for EM64T platforms and makes sense for ia64 too. Need of this was broughtup sometime(long time?) back on lkml.
http://www.ussg.iu.edu/hypermail/linux/kernel/0406.3/0112.html

Appended patch does this.

thanks,
suresh
--

Fallback to swiotlb for pci consistent DMA mappings. On EM64T, this will increase the practical size limit of pci_alloc_consistent mappings above 16MB. This makes sense on IA64 too under extreme conditions.

arch/ia64/lib/swiotlb.c +15 -3
diff -Nrup linux/arch/ia64/lib/swiotlb.c linux-swiotlb/arch/ia64/lib/swiotlb.c
@@ -305,8 +305,15 @@ swiotlb_alloc_coherent (struct device *h
 	flags |= GFP_DMA;
 
 	ret = (void *)__get_free_pages(flags, get_order(size));
-	if (!ret)
-		return NULL;
+	if (!ret) {
+		 /* DMA_FROM_DEVICE is to avoid the memcpy in map_single */
+		dma_addr_t handle;
+		handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE);
+		if (dma_mapping_error(handle))
+			return NULL;
+
+		ret = phys_to_virt(handle);
+	}
 
 	memset(ret, 0, size);
 	dev_addr = virt_to_phys(ret);
@@ -319,7 +326,12 @@ swiotlb_alloc_coherent (struct device *h
 void
 swiotlb_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
-	free_pages((unsigned long) vaddr, get_order(size));
+	if (!(vaddr >= (void *)io_tlb_start
+                    && vaddr < (void *)io_tlb_end))
+		free_pages((unsigned long) vaddr, get_order(size));
+	else
+		/* DMA_TO_DEVICE to avoid memcpy in unmap_single */
+		swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE);
 }
 
 static void swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)