Merge branch 'pci/enumeration'

- neaten pci=earlydump output (Andy Shevchenko)

  - avoid errors when extended config space inaccessible (Gilles Buloz)

  - prevent sysfs disable of device while driver attached (Christoph
    Hellwig)

  - use core interface to report PCIe link properties in bnx2x, bnxt_en,
    cxgb4, ixgbe (Bjorn Helgaas)

  - remove unused pcie_get_minimum_link() (Bjorn Helgaas)

* pci/enumeration:
  PCI: Remove unused pcie_get_minimum_link()
  ixgbe: Report PCIe link properties with pcie_print_link_status()
  cxgb4: Report PCIe link properties with pcie_print_link_status()
  bnxt_en: Report PCIe link properties with pcie_print_link_status()
  bnx2x: Report PCIe link properties with pcie_print_link_status()
  PCI: Prevent sysfs disable of device while driver is attached
  PCI: Check whether bridges allow access to extended config space
  x86/PCI: Make pci=earlydump output neat
This commit is contained in:
Bjorn Helgaas
2018-06-06 16:10:08 -05:00
9 changed files with 76 additions and 220 deletions

View File

@@ -883,6 +883,45 @@ free:
return err;
}
static bool pci_bridge_child_ext_cfg_accessible(struct pci_dev *bridge)
{
int pos;
u32 status;
/*
* If extended config space isn't accessible on a bridge's primary
* bus, we certainly can't access it on the secondary bus.
*/
if (bridge->bus->bus_flags & PCI_BUS_FLAGS_NO_EXTCFG)
return false;
/*
* PCIe Root Ports and switch ports are PCIe on both sides, so if
* extended config space is accessible on the primary, it's also
* accessible on the secondary.
*/
if (pci_is_pcie(bridge) &&
(pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT ||
pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM ||
pci_pcie_type(bridge) == PCI_EXP_TYPE_DOWNSTREAM))
return true;
/*
* For the other bridge types:
* - PCI-to-PCI bridges
* - PCIe-to-PCI/PCI-X forward bridges
* - PCI/PCI-X-to-PCIe reverse bridges
* extended config space on the secondary side is only accessible
* if the bridge supports PCI-X Mode 2.
*/
pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX);
if (!pos)
return false;
pci_read_config_dword(bridge, pos + PCI_X_STATUS, &status);
return status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ);
}
static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
struct pci_dev *bridge, int busnr)
{
@@ -924,6 +963,16 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
pci_set_bus_of_node(child);
pci_set_bus_speed(child);
/*
* Check whether extended config space is accessible on the child
* bus. Note that we currently assume it is always accessible on
* the root bus.
*/
if (!pci_bridge_child_ext_cfg_accessible(bridge)) {
child->bus_flags |= PCI_BUS_FLAGS_NO_EXTCFG;
pci_info(child, "extended config space not accessible\n");
}
/* Set up default resource pointers and names */
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
@@ -1394,6 +1443,9 @@ int pci_cfg_space_size(struct pci_dev *dev)
u32 status;
u16 class;
if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_EXTCFG)
return PCI_CFG_SPACE_SIZE;
class = dev->class >> 8;
if (class == PCI_CLASS_BRIDGE_HOST)
return pci_cfg_space_size_ext(dev);