Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pci-swiotlb.c
Go to the documentation of this file.
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 #include <asm/xen/swiotlb-xen.h>
14 #include <asm/iommu_table.h>
16 
17 static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
19  struct dma_attrs *attrs)
20 {
21  void *vaddr;
22 
23  vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags,
24  attrs);
25  if (vaddr)
26  return vaddr;
27 
28  return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
29 }
30 
31 static void x86_swiotlb_free_coherent(struct device *dev, size_t size,
32  void *vaddr, dma_addr_t dma_addr,
33  struct dma_attrs *attrs)
34 {
35  swiotlb_free_coherent(dev, size, vaddr, dma_addr);
36 }
37 
38 static struct dma_map_ops swiotlb_dma_ops = {
39  .mapping_error = swiotlb_dma_mapping_error,
40  .alloc = x86_swiotlb_alloc_coherent,
41  .free = x86_swiotlb_free_coherent,
42  .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
43  .sync_single_for_device = swiotlb_sync_single_for_device,
44  .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
45  .sync_sg_for_device = swiotlb_sync_sg_for_device,
46  .map_sg = swiotlb_map_sg_attrs,
47  .unmap_sg = swiotlb_unmap_sg_attrs,
48  .map_page = swiotlb_map_page,
49  .unmap_page = swiotlb_unmap_page,
50  .dma_supported = NULL,
51 };
52 
53 /*
54  * pci_swiotlb_detect_override - set swiotlb to 1 if necessary
55  *
56  * This returns non-zero if we are forced to use swiotlb (by the boot
57  * option).
58  */
60 {
61  int use_swiotlb = swiotlb | swiotlb_force;
62 
63  if (swiotlb_force)
64  swiotlb = 1;
65 
66  return use_swiotlb;
67 }
70  pci_swiotlb_init,
72 
73 /*
74  * if 4GB or more detected (and iommu=off not set) return 1
75  * and set swiotlb to 1.
76  */
78 {
79  /* don't initialize swiotlb if iommu=off (no_iommu=1) */
80 #ifdef CONFIG_X86_64
81  if (!no_iommu && max_pfn > MAX_DMA32_PFN)
82  swiotlb = 1;
83 #endif
84  return swiotlb;
85 }
88  pci_swiotlb_init,
90 
92 {
93  if (swiotlb) {
94  swiotlb_init(0);
96  }
97 }
98 
100 {
101  /* An IOMMU turned us off. */
102  if (!swiotlb)
103  swiotlb_free();
104  else {
105  printk(KERN_INFO "PCI-DMA: "
106  "Using software bounce buffering for IO (SWIOTLB)\n");
108  }
109 }