[Skiboot] [PATCH v5 05/15] core/pci: Allow iteration on specified devices

Gavin Shan gwshan at linux.vnet.ibm.com
Mon Apr 27 16:26:23 AEST 2015


The patch reworks pci_walk_dev() to allow iteration on child devices
beneath the specified device, so that the function can be reused in
PCI slot management code in subsequent patches. The patch doesn't
change the existing logic except adding one more parameter to
pci_walk_dev() to indicate the top-level PCI device. When that's
NULL, all subordinate PCI devices under the specified PHB will be
iterated.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pci.c     | 14 +++++++++-----
 hw/p7ioc-phb.c |  2 +-
 hw/phb3.c      |  2 +-
 include/pci.h  |  3 ++-
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/core/pci.c b/core/pci.c
index be61e84..0f9f4a0 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -762,9 +762,9 @@ static void pci_scan_phb(void *data)
 	pci_scan(phb, 0, 0xff, &phb->devices, NULL, has_link);
 
 	/* Configre MPS (Max Payload Size) for PCIe domain */
-	pci_walk_dev(phb, pci_get_mps, &mps);
+	pci_walk_dev(phb, NULL, pci_get_mps, &mps);
 	phb->mps = mps;
-	pci_walk_dev(phb, pci_configure_mps, NULL);
+	pci_walk_dev(phb, NULL, pci_configure_mps, NULL);
 }
 
 int64_t pci_register_phb(struct phb *phb)
@@ -1485,11 +1485,15 @@ static struct pci_device *__pci_walk_dev(struct phb *phb,
 }
 
 struct pci_device *pci_walk_dev(struct phb *phb,
+				struct pci_device *pd,
 				int (*cb)(struct phb *,
 					  struct pci_device *,
 					  void *),
 				void *userdata)
 {
+	if (pd)
+		return __pci_walk_dev(phb, &pd->children, cb, userdata);
+
 	return __pci_walk_dev(phb, &phb->devices, cb, userdata);
 }
 
@@ -1509,7 +1513,7 @@ static int __pci_find_dev(struct phb *phb,
 
 struct pci_device *pci_find_dev(struct phb *phb, uint16_t bdfn)
 {
-	return pci_walk_dev(phb, __pci_find_dev, &bdfn);
+	return pci_walk_dev(phb, NULL, __pci_find_dev, &bdfn);
 }
 
 static int __pci_restore_bridge_buses(struct phb *phb,
@@ -1528,7 +1532,7 @@ static int __pci_restore_bridge_buses(struct phb *phb,
 	return 0;
 }
 
-void pci_restore_bridge_buses(struct phb *phb)
+void pci_restore_bridge_buses(struct phb *phb, struct pci_device *pd)
 {
-	pci_walk_dev(phb, __pci_restore_bridge_buses, NULL);
+	pci_walk_dev(phb, pd, __pci_restore_bridge_buses, NULL);
 }
diff --git a/hw/p7ioc-phb.c b/hw/p7ioc-phb.c
index d84fd15..340d24d 100644
--- a/hw/p7ioc-phb.c
+++ b/hw/p7ioc-phb.c
@@ -345,7 +345,7 @@ static int64_t p7ioc_sm_freset(struct p7ioc_phb *p)
 			 */
 			if (p->flags & P7IOC_RESTORE_BUS_NUM) {
 				p->flags &= ~P7IOC_RESTORE_BUS_NUM;
-				pci_restore_bridge_buses(&p->phb);
+				pci_restore_bridge_buses(&p->phb, NULL);
 			}
 
 			return OPAL_SUCCESS;
diff --git a/hw/phb3.c b/hw/phb3.c
index 031c9de..e2fa9ac 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -1924,7 +1924,7 @@ static void phb3_setup_for_link_up(struct phb3 *p)
 	 */
 	if (p->flags & PHB3_RESTORE_BUS_NUM) {
 		p->flags &= ~PHB3_RESTORE_BUS_NUM;
-		pci_restore_bridge_buses(&p->phb);
+		pci_restore_bridge_buses(&p->phb, NULL);
 	}
 }
 
diff --git a/include/pci.h b/include/pci.h
index 9573961..57ba547 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -488,12 +488,13 @@ extern int64_t pci_find_ecap(struct phb *phb, uint16_t bdfn, uint16_t cap,
 			     uint8_t *version);
 extern void pci_device_init(struct phb *phb, struct pci_device *pd);
 extern struct pci_device *pci_walk_dev(struct phb *phb,
+				       struct pci_device *pd,
 				       int (*cb)(struct phb *,
 						 struct pci_device *,
 						 void *),
 				       void *userdata);
 extern struct pci_device *pci_find_dev(struct phb *phb, uint16_t bdfn);
-extern void pci_restore_bridge_buses(struct phb *phb);
+extern void pci_restore_bridge_buses(struct phb *phb, struct pci_device *pd);
 
 /* Manage PHBs */
 extern int64_t pci_register_phb(struct phb *phb);
-- 
2.1.0



More information about the Skiboot mailing list