From: Jan Kiszka <jan.kis...@siemens.com> Add qdev_iterate_recursive to walk the complete qtree invoking a callback for each device. Use this service to implement qdev_find_id_recursive.
Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- hw/qdev.c | 29 +++++++++++++++++++++++++---- hw/qdev.h | 3 +++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 2d1d171..466d8d5 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -475,16 +475,22 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, return NULL; } -static DeviceState *qdev_find_id_recursive(BusState *bus, const char *id) +void *qdev_iterate_recursive(BusState *bus, qdev_iteratefn callback, + void *opaque) { DeviceState *dev, *ret; BusState *child; + if (!bus) { + bus = main_system_bus; + } QTAILQ_FOREACH(dev, &bus->children, sibling) { - if (dev->id && strcmp(dev->id, id) == 0) - return dev; + ret = callback(dev, opaque); + if (ret) { + return ret; + } QTAILQ_FOREACH(child, &dev->child_bus, sibling) { - ret = qdev_find_id_recursive(child, id); + ret = qdev_iterate_recursive(child, callback, opaque); if (ret) { return ret; } @@ -493,6 +499,21 @@ static DeviceState *qdev_find_id_recursive(BusState *bus, const char *id) return NULL; } +static void *find_id_callback(DeviceState *dev, void *opaque) +{ + const char *id = opaque; + + if (dev->id && strcmp(dev->id, id) == 0) { + return dev; + } + return NULL; +} + +static DeviceState *qdev_find_id_recursive(BusState *bus, const char *id) +{ + return qdev_iterate_recursive(bus, find_id_callback, (void *)id); +} + static int qdev_instance_no(DeviceState *dev) { struct DeviceState *sibling; diff --git a/hw/qdev.h b/hw/qdev.h index 170a63a..111c876 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -134,6 +134,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info); typedef int (*qdev_event)(DeviceState *dev); typedef void (*qdev_resetfn)(DeviceState *dev); +typedef void *(*qdev_iteratefn)(DeviceState *dev, void *opaque); struct DeviceInfo { const char *name; @@ -168,6 +169,8 @@ void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); CharDriverState *qdev_init_chardev(DeviceState *dev); BusState *qdev_get_parent_bus(DeviceState *dev); +void *qdev_iterate_recursive(BusState *bus, qdev_iteratefn callback, + void *opaque); /*** BUS API. ***/ -- 1.6.0.2