1/* Glue code to lib/swiotlb.c */ 2 3#include <linux/pci.h> 4#include <linux/cache.h> 5#include <linux/module.h> 6#include <linux/swiotlb.h> 7#include <linux/bootmem.h> 8#include <linux/dma-mapping.h> 9 10#include <asm/iommu.h> 11#include <asm/swiotlb.h> 12#include <asm/dma.h> 13 14int swiotlb __read_mostly; 15 16static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 17 dma_addr_t *dma_handle, gfp_t flags) 18{ 19 void *vaddr; 20 21 vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags); 22 if (vaddr) 23 return vaddr; 24 25 return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); 26} 27 28static struct dma_map_ops swiotlb_dma_ops = { 29 .mapping_error = swiotlb_dma_mapping_error, 30 .alloc_coherent = x86_swiotlb_alloc_coherent, 31 .free_coherent = swiotlb_free_coherent, 32 .sync_single_for_cpu = swiotlb_sync_single_for_cpu, 33 .sync_single_for_device = swiotlb_sync_single_for_device, 34 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, 35 .sync_sg_for_device = swiotlb_sync_sg_for_device, 36 .map_sg = swiotlb_map_sg_attrs, 37 .unmap_sg = swiotlb_unmap_sg_attrs, 38 .map_page = swiotlb_map_page, 39 .unmap_page = swiotlb_unmap_page, 40 .dma_supported = NULL, 41}; 42 43/* 44 * pci_swiotlb_detect - set swiotlb to 1 if necessary 45 * 46 * This returns non-zero if we are forced to use swiotlb (by the boot 47 * option). 48 */ 49int __init pci_swiotlb_detect(void) 50{ 51 int use_swiotlb = swiotlb | swiotlb_force; 52 53 /* don't initialize swiotlb if iommu=off (no_iommu=1) */ 54#ifdef CONFIG_X86_64 55 if (!no_iommu && max_pfn > MAX_DMA32_PFN) 56 swiotlb = 1; 57#endif 58 if (swiotlb_force) 59 swiotlb = 1; 60 61 return use_swiotlb; 62} 63 64void __init pci_swiotlb_init(void) 65{ 66 if (swiotlb) { 67 swiotlb_init(0); 68 dma_ops = &swiotlb_dma_ops; 69 } 70} 71