include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / arch / x86 / kernel / pci-dma.c
index 90f5b9e..4b7e3d8 100644 (file)
@@ -2,7 +2,9 @@
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
+#include <linux/kmemleak.h>
 
 #include <asm/proto.h>
 #include <asm/dma.h>
 #include <asm/gart.h>
 #include <asm/calgary.h>
 #include <asm/amd_iommu.h>
+#include <asm/x86_init.h>
 
 static int forbid_dac __read_mostly;
 
-struct dma_map_ops *dma_ops;
+struct dma_map_ops *dma_ops = &nommu_dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
 static int iommu_sac_force __read_mostly;
@@ -32,15 +35,19 @@ int no_iommu __read_mostly;
 /* Set this to 1 if there is a HW IOMMU in the system */
 int iommu_detected __read_mostly = 0;
 
-dma_addr_t bad_dma_address __read_mostly = 0;
-EXPORT_SYMBOL(bad_dma_address);
+/*
+ * This variable becomes 1 if iommu=pt is passed on the kernel command line.
+ * If this variable is 1, IOMMU implementations do no DMA translation for
+ * devices and allow every device to access to whole physical memory. This is
+ * useful if a user wants to use an IOMMU only for KVM device assignment to
+ * guests and not for driver dma translation.
+ */
+int iommu_pass_through __read_mostly;
 
-/* Dummy device used for NULL arguments (normally ISA). Better would
-   be probably a smaller DMA mask, but this is bug-to-bug compatible
-   to older i386. */
+/* Dummy device used for NULL arguments (normally ISA). */
 struct device x86_dma_fallback_dev = {
        .init_name = "fallback device",
-       .coherent_dma_mask = DMA_32BIT_MASK,
+       .coherent_dma_mask = ISA_DMA_BIT_MASK,
        .dma_mask = &x86_dma_fallback_dev.coherent_dma_mask,
 };
 EXPORT_SYMBOL(x86_dma_fallback_dev);
@@ -59,7 +66,7 @@ int dma_set_mask(struct device *dev, u64 mask)
 }
 EXPORT_SYMBOL(dma_set_mask);
 
-#ifdef CONFIG_X86_64
+#if defined(CONFIG_X86_64) && !defined(CONFIG_NUMA)
 static __initdata void *dma32_bootmem_ptr;
 static unsigned long dma32_bootmem_size __initdata = (128ULL<<20);
 
@@ -86,6 +93,11 @@ void __init dma32_reserve_bootmem(void)
        size = roundup(dma32_bootmem_size, align);
        dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
                                 512ULL<<20);
+       /*
+        * Kmemleak should not scan this block as it may not be mapped via the
+        * kernel direct mapping.
+        */
+       kmemleak_ignore(dma32_bootmem_ptr);
        if (dma32_bootmem_ptr)
                dma32_bootmem_size = size;
        else
@@ -105,27 +117,33 @@ static void __init dma32_free_bootmem(void)
        dma32_bootmem_ptr = NULL;
        dma32_bootmem_size = 0;
 }
+#else
+void __init dma32_reserve_bootmem(void)
+{
+}
+static void __init dma32_free_bootmem(void)
+{
+}
+
 #endif
 
 void __init pci_iommu_alloc(void)
 {
-#ifdef CONFIG_X86_64
        /* free the range so iommu could get some range less than 4G */
        dma32_free_bootmem();
-#endif
 
-       /*
-        * The order of these functions is important for
-        * fall-back/fail-over reasons
-        */
+       if (pci_swiotlb_detect())
+               goto out;
+
        gart_iommu_hole_init();
 
        detect_calgary();
 
        detect_intel_iommu();
 
+       /* needs to be called after gart_iommu_hole_init */
        amd_iommu_detect();
-
+out:
        pci_swiotlb_init();
 }
 
@@ -145,10 +163,10 @@ again:
                return NULL;
 
        addr = page_to_phys(page);
-       if (!is_buffer_dma_capable(dma_mask, addr, size)) {
+       if (addr + size > dma_mask) {
                __free_pages(page, get_order(size));
 
-               if (dma_mask < DMA_32BIT_MASK && !(flag & GFP_DMA)) {
+               if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
                        flag = (flag & ~GFP_DMA32) | GFP_DMA;
                        goto again;
                }
@@ -201,7 +219,7 @@ static __init int iommu_setup(char *p)
                if (!strncmp(p, "allowdac", 8))
                        forbid_dac = 0;
                if (!strncmp(p, "nodac", 5))
-                       forbid_dac = -1;
+                       forbid_dac = 1;
                if (!strncmp(p, "usedac", 6)) {
                        forbid_dac = -1;
                        return 1;
@@ -210,6 +228,8 @@ static __init int iommu_setup(char *p)
                if (!strncmp(p, "soft", 4))
                        swiotlb = 1;
 #endif
+               if (!strncmp(p, "pt", 2))
+                       iommu_pass_through = 1;
 
                gart_parse_options(p);
 
@@ -243,7 +263,7 @@ int dma_supported(struct device *dev, u64 mask)
        /* Copied from i386. Doesn't make much sense, because it will
           only work for pci_alloc_coherent.
           The caller just has to use GFP_DMA in this case. */
-       if (mask < DMA_24BIT_MASK)
+       if (mask < DMA_BIT_MASK(24))
                return 0;
 
        /* Tell the device to use SAC when IOMMU force is on.  This
@@ -258,7 +278,7 @@ int dma_supported(struct device *dev, u64 mask)
           SAC for these.  Assume all masks <= 40 bits are of this
           type. Normally this doesn't make any difference, but gives
           more gentle handling of IOMMU overflow. */
-       if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+       if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
                dev_info(dev, "Force SAC with mask %Lx\n", mask);
                return 0;
        }
@@ -274,25 +294,19 @@ static int __init pci_iommu_init(void)
 #ifdef CONFIG_PCI
        dma_debug_add_bus(&pci_bus_type);
 #endif
+       x86_init.iommu.iommu_init();
 
-       calgary_iommu_init();
+       if (swiotlb) {
+               printk(KERN_INFO "PCI-DMA: "
+                      "Using software bounce buffering for IO (SWIOTLB)\n");
+               swiotlb_print_info();
+       } else
+               swiotlb_free();
 
-       intel_iommu_init();
-
-       amd_iommu_init();
-
-       gart_iommu_init();
-
-       no_iommu_init();
        return 0;
 }
-
-void pci_iommu_shutdown(void)
-{
-       gart_iommu_shutdown();
-}
 /* Must execute after PCI subsystem */
-fs_initcall(pci_iommu_init);
+rootfs_initcall(pci_iommu_init);
 
 #ifdef CONFIG_PCI
 /* Many VIA bridges seem to corrupt data for DAC. Disable it here */