[Skiboot] [PATCH v7 08/17] core/pci: Allow iteration on specified devices

Gavin Shan gwshan at linux.vnet.ibm.com
Thu Jun 4 16:19:00 AEST 2015


The patch reworks pci_walk_dev() to allow iteration on all the
subordinate child devices beneath the specified one, 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 0258826..ff36af6 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -764,9 +764,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)
@@ -1465,11 +1465,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);
 }
 
@@ -1489,7 +1493,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,
@@ -1508,7 +1512,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 89592c4..887d9dc 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 47212a6..355b04a 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -1957,7 +1957,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 6b3a228..2093937 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