diff options
Diffstat (limited to 'arch/x86_64/kernel/pci-dma.c')
-rw-r--r-- | arch/x86_64/kernel/pci-dma.c | 93 |
1 files changed, 56 insertions, 37 deletions
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 4dcb671bd19f..f8d857453f8a 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c | |||
@@ -170,8 +170,20 @@ void dma_free_coherent(struct device *dev, size_t size, | |||
170 | } | 170 | } |
171 | EXPORT_SYMBOL(dma_free_coherent); | 171 | EXPORT_SYMBOL(dma_free_coherent); |
172 | 172 | ||
173 | static int forbid_dac __read_mostly; | ||
174 | |||
173 | int dma_supported(struct device *dev, u64 mask) | 175 | int dma_supported(struct device *dev, u64 mask) |
174 | { | 176 | { |
177 | #ifdef CONFIG_PCI | ||
178 | if (mask > 0xffffffff && forbid_dac > 0) { | ||
179 | |||
180 | |||
181 | |||
182 | printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", dev->bus_id); | ||
183 | return 0; | ||
184 | } | ||
185 | #endif | ||
186 | |||
175 | if (dma_ops->dma_supported) | 187 | if (dma_ops->dma_supported) |
176 | return dma_ops->dma_supported(dev, mask); | 188 | return dma_ops->dma_supported(dev, mask); |
177 | 189 | ||
@@ -231,57 +243,64 @@ EXPORT_SYMBOL(dma_set_mask); | |||
231 | allowed overwrite iommu off workarounds for specific chipsets. | 243 | allowed overwrite iommu off workarounds for specific chipsets. |
232 | soft Use software bounce buffering (default for Intel machines) | 244 | soft Use software bounce buffering (default for Intel machines) |
233 | noaperture Don't touch the aperture for AGP. | 245 | noaperture Don't touch the aperture for AGP. |
246 | allowdac Allow DMA >4GB | ||
247 | nodac Forbid DMA >4GB | ||
248 | panic Force panic when IOMMU overflows | ||
234 | */ | 249 | */ |
235 | __init int iommu_setup(char *p) | 250 | __init int iommu_setup(char *p) |
236 | { | 251 | { |
237 | iommu_merge = 1; | 252 | iommu_merge = 1; |
238 | 253 | ||
239 | if (!p) | 254 | if (!p) |
240 | return -EINVAL; | 255 | return -EINVAL; |
241 | 256 | ||
242 | while (*p) { | 257 | while (*p) { |
243 | if (!strncmp(p,"off",3)) | 258 | if (!strncmp(p,"off",3)) |
244 | no_iommu = 1; | 259 | no_iommu = 1; |
245 | /* gart_parse_options has more force support */ | 260 | /* gart_parse_options has more force support */ |
246 | if (!strncmp(p,"force",5)) | 261 | if (!strncmp(p,"force",5)) |
247 | force_iommu = 1; | 262 | force_iommu = 1; |
248 | if (!strncmp(p,"noforce",7)) { | 263 | if (!strncmp(p,"noforce",7)) { |
249 | iommu_merge = 0; | 264 | iommu_merge = 0; |
250 | force_iommu = 0; | 265 | force_iommu = 0; |
251 | } | 266 | } |
252 | 267 | ||
253 | if (!strncmp(p, "biomerge",8)) { | 268 | if (!strncmp(p, "biomerge",8)) { |
254 | iommu_bio_merge = 4096; | 269 | iommu_bio_merge = 4096; |
255 | iommu_merge = 1; | 270 | iommu_merge = 1; |
256 | force_iommu = 1; | 271 | force_iommu = 1; |
257 | } | 272 | } |
258 | if (!strncmp(p, "panic",5)) | 273 | if (!strncmp(p, "panic",5)) |
259 | panic_on_overflow = 1; | 274 | panic_on_overflow = 1; |
260 | if (!strncmp(p, "nopanic",7)) | 275 | if (!strncmp(p, "nopanic",7)) |
261 | panic_on_overflow = 0; | 276 | panic_on_overflow = 0; |
262 | if (!strncmp(p, "merge",5)) { | 277 | if (!strncmp(p, "merge",5)) { |
263 | iommu_merge = 1; | 278 | iommu_merge = 1; |
264 | force_iommu = 1; | 279 | force_iommu = 1; |
265 | } | 280 | } |
266 | if (!strncmp(p, "nomerge",7)) | 281 | if (!strncmp(p, "nomerge",7)) |
267 | iommu_merge = 0; | 282 | iommu_merge = 0; |
268 | if (!strncmp(p, "forcesac",8)) | 283 | if (!strncmp(p, "forcesac",8)) |
269 | iommu_sac_force = 1; | 284 | iommu_sac_force = 1; |
285 | if (!strncmp(p, "allowdac", 8)) | ||
286 | forbid_dac = 0; | ||
287 | if (!strncmp(p, "nodac", 5)) | ||
288 | forbid_dac = -1; | ||
270 | 289 | ||
271 | #ifdef CONFIG_SWIOTLB | 290 | #ifdef CONFIG_SWIOTLB |
272 | if (!strncmp(p, "soft",4)) | 291 | if (!strncmp(p, "soft",4)) |
273 | swiotlb = 1; | 292 | swiotlb = 1; |
274 | #endif | 293 | #endif |
275 | 294 | ||
276 | #ifdef CONFIG_IOMMU | 295 | #ifdef CONFIG_IOMMU |
277 | gart_parse_options(p); | 296 | gart_parse_options(p); |
278 | #endif | 297 | #endif |
279 | 298 | ||
280 | p += strcspn(p, ","); | 299 | p += strcspn(p, ","); |
281 | if (*p == ',') | 300 | if (*p == ',') |
282 | ++p; | 301 | ++p; |
283 | } | 302 | } |
284 | return 0; | 303 | return 0; |
285 | } | 304 | } |
286 | early_param("iommu", iommu_setup); | 305 | early_param("iommu", iommu_setup); |
287 | 306 | ||