diff --git a/hw/pci.c b/hw/pci.c index eb21848b0f4874264d29550d9662212ec59c6756..44bb3b9a91cf7694b917c10b1cb83e3e53354021 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -2027,3 +2027,38 @@ static char *pcibus_get_dev_path(DeviceState *dev) return strdup(path); } +static int pci_qdev_find_recursive(PCIBus *bus, + const char *id, PCIDevice **pdev) +{ + DeviceState *qdev = qdev_find_recursive(&bus->qbus, id); + if (!qdev) { + return -ENODEV; + } + + /* roughly check if given qdev is pci device */ + if (qdev->info->init == &pci_qdev_init && + qdev->parent_bus->info == &pci_bus_info) { + *pdev = DO_UPCAST(PCIDevice, qdev, qdev); + return 0; + } + return -EINVAL; +} + +int pci_qdev_find_device(const char *id, PCIDevice **pdev) +{ + struct PCIHostBus *host; + int rc = -ENODEV; + + QLIST_FOREACH(host, &host_buses, next) { + int tmp = pci_qdev_find_recursive(host->bus, id, pdev); + if (!tmp) { + rc = 0; + break; + } + if (tmp != -ENODEV) { + rc = tmp; + } + } + + return rc; +} diff --git a/hw/pci.h b/hw/pci.h index 6e80b08e0bc0cf97b76ba529fcd1e77eb6d7abfa..052960e3eac00ee4ffc9562d7cb4922dbfacd8fe 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -252,6 +252,7 @@ PCIBus *pci_find_root_bus(int domain); int pci_find_domain(const PCIBus *bus); PCIBus *pci_find_bus(PCIBus *bus, int bus_num); PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function); +int pci_qdev_find_device(const char *id, PCIDevice **pdev); PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr); int pci_parse_devaddr(const char *addr, int *domp, int *busp,