diff options
-rw-r--r-- | drivers/pci/probe.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 490031fd2108..b47c2dd5b9e1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -984,6 +984,43 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
984 | 984 | ||
985 | 985 | ||
986 | /** | 986 | /** |
987 | * pci_ext_cfg_is_aliased - is ext config space just an alias of std config? | ||
988 | * @dev: PCI device | ||
989 | * | ||
990 | * PCI Express to PCI/PCI-X Bridge Specification, rev 1.0, 4.1.4 says that | ||
991 | * when forwarding a type1 configuration request the bridge must check that | ||
992 | * the extended register address field is zero. The bridge is not permitted | ||
993 | * to forward the transactions and must handle it as an Unsupported Request. | ||
994 | * Some bridges do not follow this rule and simply drop the extended register | ||
995 | * bits, resulting in the standard config space being aliased, every 256 | ||
996 | * bytes across the entire configuration space. Test for this condition by | ||
997 | * comparing the first dword of each potential alias to the vendor/device ID. | ||
998 | * Known offenders: | ||
999 | * ASM1083/1085 PCIe-to-PCI Reversible Bridge (1b21:1080, rev 01 & 03) | ||
1000 | * AMD/ATI SBx00 PCI to PCI Bridge (1002:4384, rev 40) | ||
1001 | */ | ||
1002 | static bool pci_ext_cfg_is_aliased(struct pci_dev *dev) | ||
1003 | { | ||
1004 | #ifdef CONFIG_PCI_QUIRKS | ||
1005 | int pos; | ||
1006 | u32 header, tmp; | ||
1007 | |||
1008 | pci_read_config_dword(dev, PCI_VENDOR_ID, &header); | ||
1009 | |||
1010 | for (pos = PCI_CFG_SPACE_SIZE; | ||
1011 | pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) { | ||
1012 | if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL | ||
1013 | || header != tmp) | ||
1014 | return false; | ||
1015 | } | ||
1016 | |||
1017 | return true; | ||
1018 | #else | ||
1019 | return false; | ||
1020 | #endif | ||
1021 | } | ||
1022 | |||
1023 | /** | ||
987 | * pci_cfg_space_size - get the configuration space size of the PCI device. | 1024 | * pci_cfg_space_size - get the configuration space size of the PCI device. |
988 | * @dev: PCI device | 1025 | * @dev: PCI device |
989 | * | 1026 | * |
@@ -1001,7 +1038,7 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev) | |||
1001 | 1038 | ||
1002 | if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) | 1039 | if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) |
1003 | goto fail; | 1040 | goto fail; |
1004 | if (status == 0xffffffff) | 1041 | if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev)) |
1005 | goto fail; | 1042 | goto fail; |
1006 | 1043 | ||
1007 | return PCI_CFG_SPACE_EXP_SIZE; | 1044 | return PCI_CFG_SPACE_EXP_SIZE; |