From patchwork Tue Jun 15 22:38:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v4,08/23] qdev: Introduce qdev_iterate_recursive Date: Tue, 15 Jun 2010 12:38:32 -0000 From: Jan Kiszka X-Patchwork-Id: 55808 Message-Id: <8f4efb5aab7b6cd6bca60816059dd38e77c6a1ff.1276641524.git.jan.kiszka@web.de> To: qemu-devel@nongnu.org, Anthony Liguori Cc: Juan Quintela , Jan Kiszka , Markus Armbruster , Luiz Capitulino , Blue Swirl , Avi Kivity From: Jan Kiszka 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 --- 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. ***/