]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/amd_iommu_init.c
x86, amd-iommu: propagate PCI device enabling error
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / amd_iommu_init.c
index 505fc04e896900bbcc0b068e7b3a027416212cfc..4cd8083c58be75d2eea19124ddf3758b15e860aa 100644 (file)
@@ -122,6 +122,7 @@ LIST_HEAD(amd_iommu_unity_map);             /* a list of required unity mappings
                                           we find in ACPI */
 unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */
 int amd_iommu_isolate;                 /* if 1, device isolation is enabled */
+bool amd_iommu_unmap_flush;            /* if true, flush on every unmap */
 
 LIST_HEAD(amd_iommu_list);             /* list of all AMD IOMMUs in the
                                           system */
@@ -296,6 +297,14 @@ static void __init iommu_unmap_mmio_space(struct amd_iommu *iommu)
  *
  ****************************************************************************/
 
+/*
+ * This function calculates the length of a given IVHD entry
+ */
+static inline int ivhd_entry_length(u8 *ivhd)
+{
+       return 0x04 << (*ivhd >> 6);
+}
+
 /*
  * This function reads the last device id the IOMMU has to handle from the PCI
  * capability header for this IOMMU
@@ -340,7 +349,7 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h)
                default:
                        break;
                }
-               p += 0x04 << (*p >> 6);
+               p += ivhd_entry_length(p);
        }
 
        WARN_ON(p != end);
@@ -425,7 +434,8 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
 
 static void __init free_command_buffer(struct amd_iommu *iommu)
 {
-       free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE));
+       free_pages((unsigned long)iommu->cmd_buf,
+                  get_order(iommu->cmd_buf_size));
 }
 
 /* allocates the memory where the IOMMU will log its events to */
@@ -641,7 +651,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
                        break;
                }
 
-               p += 0x04 << (e->type >> 6);
+               p += ivhd_entry_length(p);
        }
 }
 
@@ -713,9 +723,7 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
        init_iommu_from_acpi(iommu, h);
        init_iommu_devices(iommu);
 
-       pci_enable_device(iommu->dev);
-
-       return 0;
+       return pci_enable_device(iommu->dev);
 }
 
 /*
@@ -1135,7 +1143,7 @@ int __init amd_iommu_init(void)
        else
                printk("disabled\n");
 
-       if (iommu_fullflush)
+       if (amd_iommu_unmap_flush)
                printk(KERN_INFO "AMD IOMMU: IO/TLB flush on unmap enabled\n");
        else
                printk(KERN_INFO "AMD IOMMU: Lazy IO/TLB flushing enabled\n");
@@ -1205,6 +1213,8 @@ static int __init parse_amd_iommu_options(char *str)
        for (; *str; ++str) {
                if (strncmp(str, "isolate", 7) == 0)
                        amd_iommu_isolate = 1;
+               if (strncmp(str, "fullflush", 11) == 0)
+                       amd_iommu_unmap_flush = true;
        }
 
        return 1;