From 81699d8a90deac361e9e14fd853f8341f40b2fad Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 19 Nov 2010 18:55:58 +0900 Subject: qbus: add functions to walk both devices and busses There are some cases where you want to walk the busses, in particular, when searching for a bus either by name or DeviceInfo. Paolo suggested that we model the return values on how GCC's walkers work which allows an actor to skip child transversal, or terminate walking with a positive value that's returned as the qbus_walk_children's result. Signed-off-by: Isaku Yamahata Signed-off-by: Anthony Liguori Signed-off-by: Michael S. Tsirkin --- hw/qdev.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 35858cb81b..11d845ac06 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -449,6 +449,52 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) return NULL; } +int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque) +{ + DeviceState *dev; + int err; + + if (busfn) { + err = busfn(bus, opaque); + if (err) { + return err; + } + } + + QLIST_FOREACH(dev, &bus->children, sibling) { + err = qdev_walk_children(dev, devfn, busfn, opaque); + if (err < 0) { + return err; + } + } + + return 0; +} + +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque) +{ + BusState *bus; + int err; + + if (devfn) { + err = devfn(dev, opaque); + if (err) { + return err; + } + } + + QLIST_FOREACH(bus, &dev->child_bus, sibling) { + err = qbus_walk_children(bus, devfn, busfn, opaque); + if (err < 0) { + return err; + } + } + + return 0; +} + static BusState *qbus_find_recursive(BusState *bus, const char *name, const BusInfo *info) { -- cgit 1.4.1