--- include/linux/pci.h.orig 2018-03-26 16:51:18.050000000 +0000 +++ include/linux/pci.h 2018-04-30 09:50:57.660000000 +0000 @@ -193,6 +193,7 @@ enum pci_bus_flags { PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2, + PCI_BUS_FLAGS_COMPAT_CFG_SPACE = (__force pci_bus_flags_t) 4, }; /* These values come from the PCI Express Spec */ --- drivers/pci/probe.c.orig 2018-01-22 09:29:52.000000000 +0000 +++ drivers/pci/probe.c 2018-04-30 13:29:50.600000000 +0000 @@ -754,6 +754,35 @@ PCI_EXP_RTCTL_CRSSVE); } +static void pci_bus_check_compat_cfg_space(struct pci_bus *bus) +{ + struct pci_dev *dev = bus->self; + bool pci_compat_cfg_space = false; + int pos; + u32 status; + + if (bus->bus_flags & PCI_BUS_FLAGS_COMPAT_CFG_SPACE) + return; + + if (!pci_is_pcie(dev) || /* PCI/PCI bridge */ + (pci_pcie_type(dev) == PCI_EXP_TYPE_PCIE_BRIDGE) || /* PCIe/PCI bridge in forward mode */ + (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)) { /* PCIe/PCI bridge in reverse mode */ + pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); + if (pos) { + pci_read_config_dword(dev, pos + PCI_X_STATUS, &status); + if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ))) + pci_compat_cfg_space = true; + } else { + pci_compat_cfg_space = true; + } + if (pci_compat_cfg_space) { + dev_info(&dev->dev, "bus %02x limited to PCI-Compatible config space\n", + bus->number); + bus->bus_flags |= PCI_BUS_FLAGS_COMPAT_CFG_SPACE; + } + } +} + /* * If it's a bridge, configure it and scan the bus behind it. * For CardBus bridges, we don't scan behind as the devices will @@ -827,6 +856,7 @@ child->primary = primary; pci_bus_insert_busn_res(child, secondary, subordinate); child->bridge_ctl = bctl; + pci_bus_check_compat_cfg_space(child); } cmax = pci_scan_child_bus(child); @@ -1084,6 +1114,9 @@ u32 status; u16 class; + if (dev->bus->bus_flags & PCI_BUS_FLAGS_COMPAT_CFG_SPACE) + return PCI_CFG_SPACE_SIZE; + class = dev->class >> 8; if (class == PCI_CLASS_BRIDGE_HOST) return pci_cfg_space_size_ext(dev);