@@ -761,9 +761,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)
@@ -1483,11 +1483,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);
}
@@ -1507,7 +1511,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,
@@ -1526,7 +1530,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);
}
@@ -344,7 +344,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;
@@ -1938,7 +1938,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);
}
}
@@ -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);
The patch reworks pci_walk_dev() to allow iterate 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. Signed-off-by: Gavin Shan <gwshan@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(-)