pci: add pci_for_each_bus_depth_first

Useful for ACPI hotplug.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Michael S. Tsirkin 2013-10-14 18:01:07 +03:00
parent 4d25299cb2
commit eb0acfdde6
2 changed files with 42 additions and 0 deletions

View File

@ -1704,6 +1704,34 @@ static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
return NULL;
}
void pci_for_each_bus_depth_first(PCIBus *bus,
void *(*begin)(PCIBus *bus, void *parent_state),
void (*end)(PCIBus *bus, void *state),
void *parent_state)
{
PCIBus *sec;
void *state;
if (!bus) {
return;
}
if (begin) {
state = begin(bus, parent_state);
} else {
state = parent_state;
}
QLIST_FOREACH(sec, &bus->child, sibling) {
pci_for_each_bus_depth_first(sec, begin, end, state);
}
if (end) {
end(bus, state);
}
}
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
{
bus = pci_find_bus_nr(bus, bus_num);

View File

@ -387,6 +387,20 @@ int pci_bus_num(PCIBus *s);
void pci_for_each_device(PCIBus *bus, int bus_num,
void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque),
void *opaque);
void pci_for_each_bus_depth_first(PCIBus *bus,
void *(*begin)(PCIBus *bus, void *parent_state),
void (*end)(PCIBus *bus, void *state),
void *parent_state);
/* Use this wrapper when specific scan order is not required. */
static inline
void pci_for_each_bus(PCIBus *bus,
void (*fn)(PCIBus *bus, void *opaque),
void *opaque)
{
pci_for_each_bus_depth_first(bus, NULL, fn, opaque);
}
PCIBus *pci_find_primary_bus(void);
PCIBus *pci_device_root_bus(const PCIDevice *d);
const char *pci_root_bus_path(PCIDevice *dev);