diff options
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 235fb7a5a8a5..f3f686581a90 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -61,6 +61,8 @@ | |||
61 | /* global iommu list, set NULL for ignored DMAR units */ | 61 | /* global iommu list, set NULL for ignored DMAR units */ |
62 | static struct intel_iommu **g_iommus; | 62 | static struct intel_iommu **g_iommus; |
63 | 63 | ||
64 | static int rwbf_quirk; | ||
65 | |||
64 | /* | 66 | /* |
65 | * 0: Present | 67 | * 0: Present |
66 | * 1-11: Reserved | 68 | * 1-11: Reserved |
@@ -268,7 +270,12 @@ static long list_size; | |||
268 | 270 | ||
269 | static void domain_remove_dev_info(struct dmar_domain *domain); | 271 | static void domain_remove_dev_info(struct dmar_domain *domain); |
270 | 272 | ||
271 | int dmar_disabled; | 273 | #ifdef CONFIG_DMAR_DEFAULT_ON |
274 | int dmar_disabled = 0; | ||
275 | #else | ||
276 | int dmar_disabled = 1; | ||
277 | #endif /*CONFIG_DMAR_DEFAULT_ON*/ | ||
278 | |||
272 | static int __initdata dmar_map_gfx = 1; | 279 | static int __initdata dmar_map_gfx = 1; |
273 | static int dmar_forcedac; | 280 | static int dmar_forcedac; |
274 | static int intel_iommu_strict; | 281 | static int intel_iommu_strict; |
@@ -284,9 +291,12 @@ static int __init intel_iommu_setup(char *str) | |||
284 | if (!str) | 291 | if (!str) |
285 | return -EINVAL; | 292 | return -EINVAL; |
286 | while (*str) { | 293 | while (*str) { |
287 | if (!strncmp(str, "off", 3)) { | 294 | if (!strncmp(str, "on", 2)) { |
295 | dmar_disabled = 0; | ||
296 | printk(KERN_INFO "Intel-IOMMU: enabled\n"); | ||
297 | } else if (!strncmp(str, "off", 3)) { | ||
288 | dmar_disabled = 1; | 298 | dmar_disabled = 1; |
289 | printk(KERN_INFO"Intel-IOMMU: disabled\n"); | 299 | printk(KERN_INFO "Intel-IOMMU: disabled\n"); |
290 | } else if (!strncmp(str, "igfx_off", 8)) { | 300 | } else if (!strncmp(str, "igfx_off", 8)) { |
291 | dmar_map_gfx = 0; | 301 | dmar_map_gfx = 0; |
292 | printk(KERN_INFO | 302 | printk(KERN_INFO |
@@ -438,7 +448,8 @@ static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn) | |||
438 | continue; | 448 | continue; |
439 | 449 | ||
440 | for (i = 0; i < drhd->devices_cnt; i++) | 450 | for (i = 0; i < drhd->devices_cnt; i++) |
441 | if (drhd->devices[i]->bus->number == bus && | 451 | if (drhd->devices[i] && |
452 | drhd->devices[i]->bus->number == bus && | ||
442 | drhd->devices[i]->devfn == devfn) | 453 | drhd->devices[i]->devfn == devfn) |
443 | return drhd->iommu; | 454 | return drhd->iommu; |
444 | 455 | ||
@@ -776,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu) | |||
776 | u32 val; | 787 | u32 val; |
777 | unsigned long flag; | 788 | unsigned long flag; |
778 | 789 | ||
779 | if (!cap_rwbf(iommu->cap)) | 790 | if (!rwbf_quirk && !cap_rwbf(iommu->cap)) |
780 | return; | 791 | return; |
781 | val = iommu->gcmd | DMA_GCMD_WBF; | 792 | val = iommu->gcmd | DMA_GCMD_WBF; |
782 | 793 | ||
@@ -3128,3 +3139,15 @@ static struct iommu_ops intel_iommu_ops = { | |||
3128 | .unmap = intel_iommu_unmap_range, | 3139 | .unmap = intel_iommu_unmap_range, |
3129 | .iova_to_phys = intel_iommu_iova_to_phys, | 3140 | .iova_to_phys = intel_iommu_iova_to_phys, |
3130 | }; | 3141 | }; |
3142 | |||
3143 | static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | ||
3144 | { | ||
3145 | /* | ||
3146 | * Mobile 4 Series Chipset neglects to set RWBF capability, | ||
3147 | * but needs it: | ||
3148 | */ | ||
3149 | printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); | ||
3150 | rwbf_quirk = 1; | ||
3151 | } | ||
3152 | |||
3153 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); | ||