mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 08:31:13 +00:00
x86: Disable DAC on VIA bridges
Several reports that VIA bridges don't support DAC and corrupt data. I don't know if it's fixed, but let's just blacklist them all for now. It can be overwritten with iommu=usedac Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
0b62233021
commit
388c19e176
3 changed files with 45 additions and 0 deletions
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
struct dma_coherent_mem {
|
struct dma_coherent_mem {
|
||||||
|
@ -148,3 +149,29 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
|
||||||
return mem->virt_base + (pos << PAGE_SHIFT);
|
return mem->virt_base + (pos << PAGE_SHIFT);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
|
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
|
||||||
|
|
||||||
|
int forbid_dac;
|
||||||
|
EXPORT_SYMBOL(forbid_dac);
|
||||||
|
|
||||||
|
static __devinit void via_no_dac(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
|
||||||
|
printk(KERN_INFO "PCI: VIA PCI bridge detected. Disabling DAC.\n");
|
||||||
|
forbid_dac = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
|
||||||
|
|
||||||
|
static int check_iommu(char *s)
|
||||||
|
{
|
||||||
|
if (!strcmp(s, "usedac")) {
|
||||||
|
forbid_dac = -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
__setup("iommu=", check_iommu);
|
||||||
|
#endif
|
||||||
|
|
|
@ -322,5 +322,17 @@ static int __init pci_iommu_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
|
||||||
|
|
||||||
|
static __devinit void via_no_dac(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
|
||||||
|
printk(KERN_INFO "PCI: VIA PCI bridge detected. Disabling DAC.\n");
|
||||||
|
forbid_dac = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
|
||||||
|
#endif
|
||||||
/* Must execute after PCI subsystem */
|
/* Must execute after PCI subsystem */
|
||||||
fs_initcall(pci_iommu_init);
|
fs_initcall(pci_iommu_init);
|
||||||
|
|
|
@ -123,6 +123,8 @@ dma_mapping_error(dma_addr_t dma_addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int forbid_dac;
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
dma_supported(struct device *dev, u64 mask)
|
dma_supported(struct device *dev, u64 mask)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +136,10 @@ dma_supported(struct device *dev, u64 mask)
|
||||||
if(mask < 0x00ffffff)
|
if(mask < 0x00ffffff)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Work around chipset bugs */
|
||||||
|
if (forbid_dac > 0 && mask > 0xffffffffULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue