Commit eb0acfdd authored by Michael S. Tsirkin's avatar Michael S. Tsirkin
Browse files

pci: add pci_for_each_bus_depth_first



Useful for ACPI hotplug.

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 4d25299c
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -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);
+14 −0
Original line number Diff line number Diff line
@@ -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);