diff options
-rw-r--r-- | arch/i386/kernel/pci-dma.c | 27 | ||||
-rw-r--r-- | arch/x86_64/kernel/pci-dma.c | 12 | ||||
-rw-r--r-- | include/asm-i386/dma-mapping.h | 6 |
3 files changed, 45 insertions, 0 deletions
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c index 30b754f7cbec..048f09b62553 100644 --- a/arch/i386/kernel/pci-dma.c +++ b/arch/i386/kernel/pci-dma.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/pci.h> | ||
15 | #include <asm/io.h> | 16 | #include <asm/io.h> |
16 | 17 | ||
17 | struct dma_coherent_mem { | 18 | struct dma_coherent_mem { |
@@ -148,3 +149,29 @@ void *dma_mark_declared_memory_occupied(struct device *dev, | |||
148 | return mem->virt_base + (pos << PAGE_SHIFT); | 149 | return mem->virt_base + (pos << PAGE_SHIFT); |
149 | } | 150 | } |
150 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | 151 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); |
152 | |||
153 | #ifdef CONFIG_PCI | ||
154 | /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ | ||
155 | |||
156 | int forbid_dac; | ||
157 | EXPORT_SYMBOL(forbid_dac); | ||
158 | |||
159 | static __devinit void via_no_dac(struct pci_dev *dev) | ||
160 | { | ||
161 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | ||
162 | printk(KERN_INFO "PCI: VIA PCI bridge detected. Disabling DAC.\n"); | ||
163 | forbid_dac = 1; | ||
164 | } | ||
165 | } | ||
166 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); | ||
167 | |||
168 | static int check_iommu(char *s) | ||
169 | { | ||
170 | if (!strcmp(s, "usedac")) { | ||
171 | forbid_dac = -1; | ||
172 | return 1; | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | __setup("iommu=", check_iommu); | ||
177 | #endif | ||
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 651ccfb06697..9f80aad3fe2d 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c | |||
@@ -322,5 +322,17 @@ static int __init pci_iommu_init(void) | |||
322 | return 0; | 322 | return 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | #ifdef CONFIG_PCI | ||
326 | /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ | ||
327 | |||
328 | static __devinit void via_no_dac(struct pci_dev *dev) | ||
329 | { | ||
330 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | ||
331 | printk(KERN_INFO "PCI: VIA PCI bridge detected. Disabling DAC.\n"); | ||
332 | forbid_dac = 1; | ||
333 | } | ||
334 | } | ||
335 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); | ||
336 | #endif | ||
325 | /* Must execute after PCI subsystem */ | 337 | /* Must execute after PCI subsystem */ |
326 | fs_initcall(pci_iommu_init); | 338 | fs_initcall(pci_iommu_init); |
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h index 183eebeebbdc..f1d72d177f68 100644 --- a/include/asm-i386/dma-mapping.h +++ b/include/asm-i386/dma-mapping.h | |||
@@ -123,6 +123,8 @@ dma_mapping_error(dma_addr_t dma_addr) | |||
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
125 | 125 | ||
126 | extern int forbid_dac; | ||
127 | |||
126 | static inline int | 128 | static inline int |
127 | dma_supported(struct device *dev, u64 mask) | 129 | dma_supported(struct device *dev, u64 mask) |
128 | { | 130 | { |
@@ -134,6 +136,10 @@ dma_supported(struct device *dev, u64 mask) | |||
134 | if(mask < 0x00ffffff) | 136 | if(mask < 0x00ffffff) |
135 | return 0; | 137 | return 0; |
136 | 138 | ||
139 | /* Work around chipset bugs */ | ||
140 | if (forbid_dac > 0 && mask > 0xffffffffULL) | ||
141 | return 0; | ||
142 | |||
137 | return 1; | 143 | return 1; |
138 | } | 144 | } |
139 | 145 | ||