lkml.org 
[lkml]   [2007]   [Jun]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH for 2.6.22] [4/10] x86: Disable DAC on VIA bridges
    Date

    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>

    ---
    arch/i386/kernel/pci-dma.c | 27 +++++++++++++++++++++++++++
    arch/x86_64/kernel/pci-dma.c | 12 ++++++++++++
    include/asm-i386/dma-mapping.h | 6 ++++++
    3 files changed, 45 insertions(+)
    Index: linux/arch/x86_64/kernel/pci-dma.c
    ===================================================================
    --- linux.orig/arch/x86_64/kernel/pci-dma.c
    +++ linux/arch/x86_64/kernel/pci-dma.c
    @@ -322,5 +322,17 @@ static int __init pci_iommu_init(void)
    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 */
    fs_initcall(pci_iommu_init);
    Index: linux/arch/i386/kernel/pci-dma.c
    ===================================================================
    --- linux.orig/arch/i386/kernel/pci-dma.c
    +++ linux/arch/i386/kernel/pci-dma.c
    @@ -12,6 +12,7 @@
    #include <linux/string.h>
    #include <linux/pci.h>
    #include <linux/module.h>
    +#include <linux/pci.h>
    #include <asm/io.h>

    struct dma_coherent_mem {
    @@ -148,3 +149,29 @@ void *dma_mark_declared_memory_occupied(
    return mem->virt_base + (pos << PAGE_SHIFT);
    }
    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
    Index: linux/include/asm-i386/dma-mapping.h
    ===================================================================
    --- linux.orig/include/asm-i386/dma-mapping.h
    +++ linux/include/asm-i386/dma-mapping.h
    @@ -123,6 +123,8 @@ dma_mapping_error(dma_addr_t dma_addr)
    return 0;
    }

    +extern int forbid_dac;
    +
    static inline int
    dma_supported(struct device *dev, u64 mask)
    {
    @@ -134,6 +136,10 @@ dma_supported(struct device *dev, u64 ma
    if(mask < 0x00ffffff)
    return 0;

    + /* Work around chipset bugs */
    + if (forbid_dac > 0 && mask > 0xffffffffULL)
    + return 0;
    +
    return 1;
    }

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-06-20 12:27    [from the cache]
    ©2003-2014 Jasper Spaans. hosted at Digital Ocean