diff options
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a0c20d9e8396..89ed181cd90c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -91,6 +91,19 @@ static void __devinit quirk_resource_alignment(struct pci_dev *dev) | |||
91 | } | 91 | } |
92 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | 92 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); |
93 | 93 | ||
94 | /* | ||
95 | * Decoding should be disabled for a PCI device during BAR sizing to avoid | ||
96 | * conflict. But doing so may cause problems on host bridge and perhaps other | ||
97 | * key system devices. For devices that need to have mmio decoding always-on, | ||
98 | * we need to set the dev->mmio_always_on bit. | ||
99 | */ | ||
100 | static void __devinit quirk_mmio_always_on(struct pci_dev *dev) | ||
101 | { | ||
102 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
103 | dev->mmio_always_on = 1; | ||
104 | } | ||
105 | DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on); | ||
106 | |||
94 | /* The Mellanox Tavor device gives false positive parity errors | 107 | /* The Mellanox Tavor device gives false positive parity errors |
95 | * Mark this device with a broken_parity_status, to allow | 108 | * Mark this device with a broken_parity_status, to allow |
96 | * PCI scanning code to "skip" this now blacklisted device. | 109 | * PCI scanning code to "skip" this now blacklisted device. |
@@ -2121,6 +2134,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disabl | |||
2121 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi); | 2134 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi); |
2122 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); | 2135 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); |
2123 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi); | 2136 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi); |
2137 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi); | ||
2124 | 2138 | ||
2125 | /* Disable MSI on chipsets that are known to not support it */ | 2139 | /* Disable MSI on chipsets that are known to not support it */ |
2126 | static void __devinit quirk_disable_msi(struct pci_dev *dev) | 2140 | static void __devinit quirk_disable_msi(struct pci_dev *dev) |
@@ -2132,12 +2146,29 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) | |||
2132 | } | 2146 | } |
2133 | } | 2147 | } |
2134 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); | 2148 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); |
2135 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi); | ||
2136 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi); | ||
2137 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi); | ||
2138 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); | 2149 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); |
2139 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi); | 2150 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi); |
2140 | 2151 | ||
2152 | /* | ||
2153 | * The APC bridge device in AMD 780 family northbridges has some random | ||
2154 | * OEM subsystem ID in its vendor ID register (erratum 18), so instead | ||
2155 | * we use the possible vendor/device IDs of the host bridge for the | ||
2156 | * declared quirk, and search for the APC bridge by slot number. | ||
2157 | */ | ||
2158 | static void __devinit quirk_amd_780_apc_msi(struct pci_dev *host_bridge) | ||
2159 | { | ||
2160 | struct pci_dev *apc_bridge; | ||
2161 | |||
2162 | apc_bridge = pci_get_slot(host_bridge->bus, PCI_DEVFN(1, 0)); | ||
2163 | if (apc_bridge) { | ||
2164 | if (apc_bridge->device == 0x9602) | ||
2165 | quirk_disable_msi(apc_bridge); | ||
2166 | pci_dev_put(apc_bridge); | ||
2167 | } | ||
2168 | } | ||
2169 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9600, quirk_amd_780_apc_msi); | ||
2170 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi); | ||
2171 | |||
2141 | /* Go through the list of Hypertransport capabilities and | 2172 | /* Go through the list of Hypertransport capabilities and |
2142 | * return 1 if a HT MSI capability is found and enabled */ | 2173 | * return 1 if a HT MSI capability is found and enabled */ |
2143 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | 2174 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) |
@@ -2396,6 +2427,9 @@ static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) | |||
2396 | int pos; | 2427 | int pos; |
2397 | int found; | 2428 | int found; |
2398 | 2429 | ||
2430 | if (!pci_msi_enabled()) | ||
2431 | return; | ||
2432 | |||
2399 | /* check if there is HT MSI cap or enabled on this device */ | 2433 | /* check if there is HT MSI cap or enabled on this device */ |
2400 | found = ht_check_msi_mapping(dev); | 2434 | found = ht_check_msi_mapping(dev); |
2401 | 2435 | ||
@@ -2748,7 +2782,7 @@ static int __init pci_apply_final_quirks(void) | |||
2748 | printk(KERN_DEBUG "PCI: CLS %u bytes\n", | 2782 | printk(KERN_DEBUG "PCI: CLS %u bytes\n", |
2749 | pci_cache_line_size << 2); | 2783 | pci_cache_line_size << 2); |
2750 | 2784 | ||
2751 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 2785 | for_each_pci_dev(dev) { |
2752 | pci_fixup_device(pci_fixup_final, dev); | 2786 | pci_fixup_device(pci_fixup_final, dev); |
2753 | /* | 2787 | /* |
2754 | * If arch hasn't set it explicitly yet, use the CLS | 2788 | * If arch hasn't set it explicitly yet, use the CLS |