summaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pci-mvebu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/host/pci-mvebu.c')
-rw-r--r--drivers/pci/host/pci-mvebu.c31
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;
}