diff options
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index b8c95a293f64..9f1bfbd81168 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -554,7 +554,8 @@ mvebu_pcie_find_port(struct mvebu_pcie *pcie, struct pci_bus *bus, if (bus->number == 0 && port->devfn == devfn) return port; if (bus->number != 0 && - port->bridge.secondary_bus == bus->number) + bus->number >= port->bridge.secondary_bus && + bus->number <= port->bridge.subordinate_bus) return port; } @@ -578,7 +579,18 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (bus->number == 0) return mvebu_sw_pci_bridge_write(port, where, size, val); - if (!port->haslink || PCI_SLOT(devfn) != 0) + if (!port->haslink) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* + * On the secondary bus, we don't want to expose any other + * device than the device physically connected in the PCIe + * slot, visible in slot 0. In slot 1, there's a special + * Marvell device that only makes sense when the Armada is + * used as a PCIe endpoint. + */ + if (bus->number == port->bridge.secondary_bus && + PCI_SLOT(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; /* Access the real PCIe interface */ @@ -609,7 +621,20 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, if (bus->number == 0) return mvebu_sw_pci_bridge_read(port, where, size, val); - if (!port->haslink || PCI_SLOT(devfn) != 0) { + if (!port->haslink) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + /* + * On the secondary bus, we don't want to expose any other + * device than the device physically connected in the PCIe + * slot, visible in slot 0. In slot 1, there's a special + * Marvell device that only makes sense when the Armada is + * used as a PCIe endpoint. + */ + if (bus->number == port->bridge.secondary_bus && + PCI_SLOT(devfn) != 0) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; } |