aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
commit7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch)
treee730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/pci/quirks.c
parent41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff)
parent0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff)
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c208
1 files changed, 120 insertions, 88 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c880dd0bbfb5..0b60ed884d98 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,14 @@
24#include <linux/kallsyms.h> 24#include <linux/kallsyms.h>
25#include "pci.h" 25#include "pci.h"
26 26
27int isa_dma_bridge_buggy;
28EXPORT_SYMBOL(isa_dma_bridge_buggy);
29int pci_pci_problems;
30EXPORT_SYMBOL(pci_pci_problems);
31int pcie_mch_quirk;
32EXPORT_SYMBOL(pcie_mch_quirk);
33
34#ifdef CONFIG_PCI_QUIRKS
27/* The Mellanox Tavor device gives false positive parity errors 35/* The Mellanox Tavor device gives false positive parity errors
28 * Mark this device with a broken_parity_status, to allow 36 * Mark this device with a broken_parity_status, to allow
29 * PCI scanning code to "skip" this now blacklisted device. 37 * PCI scanning code to "skip" this now blacklisted device.
@@ -35,6 +43,20 @@ static void __devinit quirk_mellanox_tavor(struct pci_dev *dev)
35DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor); 43DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor);
36DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor); 44DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor);
37 45
46/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
47int forbid_dac __read_mostly;
48EXPORT_SYMBOL(forbid_dac);
49
50static __devinit void via_no_dac(struct pci_dev *dev)
51{
52 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
53 dev_info(&dev->dev,
54 "VIA PCI bridge detected. Disabling DAC.\n");
55 forbid_dac = 1;
56 }
57}
58DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
59
38/* Deal with broken BIOS'es that neglect to enable passive release, 60/* Deal with broken BIOS'es that neglect to enable passive release,
39 which can cause problems in combination with the 82441FX/PPro MTRRs */ 61 which can cause problems in combination with the 82441FX/PPro MTRRs */
40static void quirk_passive_release(struct pci_dev *dev) 62static void quirk_passive_release(struct pci_dev *dev)
@@ -62,8 +84,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p
62 84
63 This appears to be BIOS not version dependent. So presumably there is a 85 This appears to be BIOS not version dependent. So presumably there is a
64 chipset level fix */ 86 chipset level fix */
65int isa_dma_bridge_buggy;
66EXPORT_SYMBOL(isa_dma_bridge_buggy);
67 87
68static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) 88static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
69{ 89{
@@ -84,9 +104,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_d
84DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs); 104DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs);
85DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); 105DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs);
86 106
87int pci_pci_problems;
88EXPORT_SYMBOL(pci_pci_problems);
89
90/* 107/*
91 * Chipsets where PCI->PCI transfers vanish or hang 108 * Chipsets where PCI->PCI transfers vanish or hang
92 */ 109 */
@@ -902,6 +919,19 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev)
902} 919}
903DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); 920DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode);
904 921
922/*
923 * Some ATA devices break if put into D3
924 */
925
926static void __devinit quirk_no_ata_d3(struct pci_dev *pdev)
927{
928 /* Quirk the legacy ATA devices only. The AHCI ones are ok */
929 if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE)
930 pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
931}
932DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3);
933DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3);
934
905/* This was originally an Alpha specific thing, but it really fits here. 935/* This was originally an Alpha specific thing, but it really fits here.
906 * The i82375 PCI/EISA bridge appears as non-classified. Fix that. 936 * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
907 */ 937 */
@@ -1328,9 +1358,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
1328DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic); 1358DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic);
1329#endif 1359#endif
1330 1360
1331int pcie_mch_quirk;
1332EXPORT_SYMBOL(pcie_mch_quirk);
1333
1334static void __devinit quirk_pcie_mch(struct pci_dev *pdev) 1361static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
1335{ 1362{
1336 pcie_mch_quirk = 1; 1363 pcie_mch_quirk = 1;
@@ -1670,85 +1697,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
1670} 1697}
1671DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); 1698DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
1672 1699
1673static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
1674{
1675 while (f < end) {
1676 if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
1677 (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
1678#ifdef DEBUG
1679 dev_dbg(&dev->dev, "calling ");
1680 print_fn_descriptor_symbol("%s\n", f->hook);
1681#endif
1682 f->hook(dev);
1683 }
1684 f++;
1685 }
1686}
1687
1688extern struct pci_fixup __start_pci_fixups_early[];
1689extern struct pci_fixup __end_pci_fixups_early[];
1690extern struct pci_fixup __start_pci_fixups_header[];
1691extern struct pci_fixup __end_pci_fixups_header[];
1692extern struct pci_fixup __start_pci_fixups_final[];
1693extern struct pci_fixup __end_pci_fixups_final[];
1694extern struct pci_fixup __start_pci_fixups_enable[];
1695extern struct pci_fixup __end_pci_fixups_enable[];
1696extern struct pci_fixup __start_pci_fixups_resume[];
1697extern struct pci_fixup __end_pci_fixups_resume[];
1698extern struct pci_fixup __start_pci_fixups_resume_early[];
1699extern struct pci_fixup __end_pci_fixups_resume_early[];
1700extern struct pci_fixup __start_pci_fixups_suspend[];
1701extern struct pci_fixup __end_pci_fixups_suspend[];
1702
1703
1704void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
1705{
1706 struct pci_fixup *start, *end;
1707
1708 switch(pass) {
1709 case pci_fixup_early:
1710 start = __start_pci_fixups_early;
1711 end = __end_pci_fixups_early;
1712 break;
1713
1714 case pci_fixup_header:
1715 start = __start_pci_fixups_header;
1716 end = __end_pci_fixups_header;
1717 break;
1718
1719 case pci_fixup_final:
1720 start = __start_pci_fixups_final;
1721 end = __end_pci_fixups_final;
1722 break;
1723
1724 case pci_fixup_enable:
1725 start = __start_pci_fixups_enable;
1726 end = __end_pci_fixups_enable;
1727 break;
1728
1729 case pci_fixup_resume:
1730 start = __start_pci_fixups_resume;
1731 end = __end_pci_fixups_resume;
1732 break;
1733
1734 case pci_fixup_resume_early:
1735 start = __start_pci_fixups_resume_early;
1736 end = __end_pci_fixups_resume_early;
1737 break;
1738
1739 case pci_fixup_suspend:
1740 start = __start_pci_fixups_suspend;
1741 end = __end_pci_fixups_suspend;
1742 break;
1743
1744 default:
1745 /* stupid compiler warning, you would think with an enum... */
1746 return;
1747 }
1748 pci_do_fixups(dev, start, end);
1749}
1750EXPORT_SYMBOL(pci_fixup_device);
1751
1752/* Enable 1k I/O space granularity on the Intel P64H2 */ 1700/* Enable 1k I/O space granularity on the Intel P64H2 */
1753static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) 1701static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
1754{ 1702{
@@ -1871,9 +1819,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_c
1871 */ 1819 */
1872static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev) 1820static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
1873{ 1821{
1874 /* Only disable the VPD capability for 5706, 5708, and 5709 rev. A */ 1822 /*
1823 * Only disable the VPD capability for 5706, 5706S, 5708,
1824 * 5708S and 5709 rev. A
1825 */
1875 if ((dev->device == PCI_DEVICE_ID_NX2_5706) || 1826 if ((dev->device == PCI_DEVICE_ID_NX2_5706) ||
1827 (dev->device == PCI_DEVICE_ID_NX2_5706S) ||
1876 (dev->device == PCI_DEVICE_ID_NX2_5708) || 1828 (dev->device == PCI_DEVICE_ID_NX2_5708) ||
1829 (dev->device == PCI_DEVICE_ID_NX2_5708S) ||
1877 ((dev->device == PCI_DEVICE_ID_NX2_5709) && 1830 ((dev->device == PCI_DEVICE_ID_NX2_5709) &&
1878 (dev->revision & 0xf0) == 0x0)) { 1831 (dev->revision & 0xf0) == 0x0)) {
1879 if (dev->vpd) 1832 if (dev->vpd)
@@ -2117,3 +2070,82 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
2117 quirk_msi_intx_disable_bug); 2070 quirk_msi_intx_disable_bug);
2118 2071
2119#endif /* CONFIG_PCI_MSI */ 2072#endif /* CONFIG_PCI_MSI */
2073
2074static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
2075{
2076 while (f < end) {
2077 if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
2078 (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
2079 dev_dbg(&dev->dev, "calling %pF\n", f->hook);
2080 f->hook(dev);
2081 }
2082 f++;
2083 }
2084}
2085
2086extern struct pci_fixup __start_pci_fixups_early[];
2087extern struct pci_fixup __end_pci_fixups_early[];
2088extern struct pci_fixup __start_pci_fixups_header[];
2089extern struct pci_fixup __end_pci_fixups_header[];
2090extern struct pci_fixup __start_pci_fixups_final[];
2091extern struct pci_fixup __end_pci_fixups_final[];
2092extern struct pci_fixup __start_pci_fixups_enable[];
2093extern struct pci_fixup __end_pci_fixups_enable[];
2094extern struct pci_fixup __start_pci_fixups_resume[];
2095extern struct pci_fixup __end_pci_fixups_resume[];
2096extern struct pci_fixup __start_pci_fixups_resume_early[];
2097extern struct pci_fixup __end_pci_fixups_resume_early[];
2098extern struct pci_fixup __start_pci_fixups_suspend[];
2099extern struct pci_fixup __end_pci_fixups_suspend[];
2100
2101
2102void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
2103{
2104 struct pci_fixup *start, *end;
2105
2106 switch(pass) {
2107 case pci_fixup_early:
2108 start = __start_pci_fixups_early;
2109 end = __end_pci_fixups_early;
2110 break;
2111
2112 case pci_fixup_header:
2113 start = __start_pci_fixups_header;
2114 end = __end_pci_fixups_header;
2115 break;
2116
2117 case pci_fixup_final:
2118 start = __start_pci_fixups_final;
2119 end = __end_pci_fixups_final;
2120 break;
2121
2122 case pci_fixup_enable:
2123 start = __start_pci_fixups_enable;
2124 end = __end_pci_fixups_enable;
2125 break;
2126
2127 case pci_fixup_resume:
2128 start = __start_pci_fixups_resume;
2129 end = __end_pci_fixups_resume;
2130 break;
2131
2132 case pci_fixup_resume_early:
2133 start = __start_pci_fixups_resume_early;
2134 end = __end_pci_fixups_resume_early;
2135 break;
2136
2137 case pci_fixup_suspend:
2138 start = __start_pci_fixups_suspend;
2139 end = __end_pci_fixups_suspend;
2140 break;
2141
2142 default:
2143 /* stupid compiler warning, you would think with an enum... */
2144 return;
2145 }
2146 pci_do_fixups(dev, start, end);
2147}
2148#else
2149void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
2150#endif
2151EXPORT_SYMBOL(pci_fixup_device);