The full tree search was a bit unreasonable. Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> --- hw/qdev.c | 60 +++++++++++++++++++++++++++--------------------------------- hw/qdev.h | 4 ++++ 2 files changed, 31 insertions(+), 33 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c index b944108..7da7196 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -1210,6 +1210,9 @@ void qdev_property_add_child(DeviceState *dev, const char *name, qdev_property_add(dev, name, type, qdev_get_child_property, NULL, NULL, child, errp); + g_assert(child->parent == NULL); + child->parent = dev; + g_free(type); } @@ -1282,48 +1285,39 @@ void qdev_property_add_link(DeviceState *dev, const char *name, g_free(full_type); } -static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev) +gchar *qdev_get_canonical_path(DeviceState *dev) { - GSList *i; + DeviceState *root = qdev_get_root(); + char *newpath = NULL, *path = NULL; - if (parent == dev) { - return g_strdup(""); - } - - for (i = parent->properties; i; i = i->next) { - DeviceProperty *prop = i->data; - gchar *subpath; - - if (!strstart(prop->type, "child<", NULL)) { - continue; - } + while (dev != root) { + GSList *i; - /* Check to see if the device is one of parent's children */ - if (prop->opaque == dev) { - return g_strdup(prop->name); - } + g_assert(dev->parent != NULL); - /* Check to see if the device is a child of our child */ - subpath = qdev_get_path_in(prop->opaque, dev); - if (subpath) { - gchar *path; + for (i = dev->parent->properties; i; i = i->next) { + DeviceProperty *prop = i->data; - path = g_strdup_printf("%s/%s", prop->name, subpath); - g_free(subpath); + if (!strstart(prop->type, "child<", NULL)) { + continue; + } - return path; + if (prop->opaque == dev) { + if (path) { + newpath = g_strdup_printf("%s/%s", prop->name, path); + g_free(path); + path = newpath; + } else { + path = g_strdup(prop->name); + } + break; + } } - } - return NULL; -} + g_assert(i != NULL); -gchar *qdev_get_canonical_path(DeviceState *dev) -{ - gchar *path, *newpath; - - path = qdev_get_path_in(qdev_get_root(), dev); - g_assert(path != NULL); + dev = dev->parent; + } newpath = g_strdup_printf("/%s", path); g_free(path); diff --git a/hw/qdev.h b/hw/qdev.h index e8c9e76..8eb7ce1 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -83,6 +83,10 @@ struct DeviceState { int instance_id_alias; int alias_required_for_version; GSList *properties; + + /* Do not, under any circumstance, use this parent link below anywhere + * outside of qdev.c. You have been warned. */ + DeviceState *parent; }; typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); -- 1.7.4.1