[Skiboot] [PATCH 12/16] core/pci: Reserve PCI buses for RC's slot

Gavin Shan gwshan at linux.vnet.ibm.com
Fri Sep 16 15:05:19 AEST 2016


When RC's downstream link is down, we need reserve spare PCI buses
if it has an associated PCI hotplug slot. Otherwise, the adapter
behind it can't be probed successfully in PCI hot add scenario.

This reserves all available buses (to 255) for RC's hotplug slot
when its downstream is down so that PCI adapter can be hot added
to the slot afterwards.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pci.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/core/pci.c b/core/pci.c
index 14780a5..c72a3cf 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -558,9 +558,10 @@ uint8_t pci_scan_bus(struct phb *phb, uint8_t bus, uint8_t max_bus,
 		     struct list_head *list, struct pci_device *parent,
 		     bool scan_downstream)
 {
-	struct pci_device *pd = NULL;
+	struct pci_device *pd = NULL, *rc = NULL;
 	uint8_t dev, fn, next_bus, max_sub, save_max;
 	uint32_t scan_map;
+	bool use_max;
 
 	/* Decide what to scan  */
 	scan_map = parent ? parent->scan_map : phb->scan_map;
@@ -576,6 +577,10 @@ uint8_t pci_scan_bus(struct phb *phb, uint8_t bus, uint8_t max_bus,
 		if (!pd)
 			continue;
 
+		/* Record RC when its downstream link is down */
+		if (!scan_downstream && dev == 0 && !rc)
+			rc = pd;
+
 		/* XXX Handle ARI */
 		if (!pd->is_multifunction)
 			continue;
@@ -586,6 +591,20 @@ uint8_t pci_scan_bus(struct phb *phb, uint8_t bus, uint8_t max_bus,
 		}
 	}
 
+	/* Reserve all possible buses if RC's downstream link is down
+	 * if PCI hotplug is supported.
+	 */
+	if (rc && rc->slot && rc->slot->pluggable) {
+		next_bus = phb->ops->choose_bus(phb, rc, bus + 1,
+						&max_bus, &use_max);
+		rc->secondary_bus = next_bus;
+		rc->subordinate_bus = max_bus;
+		pci_cfg_write8(phb, rc->bdfn, PCI_CFG_SECONDARY_BUS,
+			       rc->secondary_bus);
+		pci_cfg_write8(phb, rc->bdfn, PCI_CFG_SUBORDINATE_BUS,
+			       rc->subordinate_bus);
+	}
+
 	/*
 	 * We only scan downstream if instructed to do so by the
 	 * caller. Typically we avoid the scan when we know the
@@ -605,7 +624,7 @@ uint8_t pci_scan_bus(struct phb *phb, uint8_t bus, uint8_t max_bus,
 
 	/* Scan down bridges */
 	list_for_each(list, pd, link) {
-		bool use_max, do_scan;
+		bool do_scan;
 
 		if (!pd->is_bridge)
 			continue;
-- 
2.1.0



More information about the Skiboot mailing list