Don't rely on bus_info. I took a little liberty in the last commit as it would cause info qtree/info qdm to not show any useful information. But since this is not considered a supported interface, breaking it across a single commit seems okay.
This commit makes info qtree/qdm work again. Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> --- hw/qdev-monitor.c | 120 ++++++++++++++++++++++++++++---------------------- hw/qdev-properties.c | 30 +++--------- hw/qdev.c | 26 +++-------- hw/qdev.h | 1 - 4 files changed, 83 insertions(+), 94 deletions(-) diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index dc4e4e1..f5ee166 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -118,17 +118,44 @@ static const char *find_typename_by_alias(const char *alias) return NULL; } +static void display_property(Object *obj, const char *name, + const char *typename, bool read_only, + void *opaque) +{ + char *legacy_typename; + + if (!strstart(typename, "legacy<", NULL)) { + return; + } + + legacy_typename = g_strdup(&typename[7]); + legacy_typename[strlen(legacy_typename) - 1] = 0; + + /* + * TODO Properties without a parser are just for dirty hacks. + * qdev_prop_ptr is the only such PropertyInfo. It's marked + * for removal. This conditional should be removed along with + * it. + */ + if (!read_only) { + error_printf("%s.%s=%s\n", object_get_typename(obj), + &name[7], legacy_typename); + } + + g_free(legacy_typename); +} + int qdev_device_help(QemuOpts *opts) { const char *driver; - Property *prop; ObjectClass *klass; - DeviceClass *info; + Object *obj; driver = qemu_opt_get(opts, "driver"); if (driver && !strcmp(driver, "?")) { bool show_no_user = false; - object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user); + object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, + false, &show_no_user); return 1; } @@ -149,30 +176,11 @@ int qdev_device_help(QemuOpts *opts) if (!klass) { return 0; } - info = DEVICE_CLASS(klass); - - for (prop = info->props; prop && prop->name; prop++) { - /* - * TODO Properties without a parser are just for dirty hacks. - * qdev_prop_ptr is the only such PropertyInfo. It's marked - * for removal. This conditional should be removed along with - * it. - */ - if (!prop->info->parse) { - continue; /* no way to set it, don't show */ - } - error_printf("%s.%s=%s\n", driver, prop->name, - prop->info->legacy_name ?: prop->info->name); - } - if (info->bus_info) { - for (prop = info->bus_info->props; prop && prop->name; prop++) { - if (!prop->info->parse) { - continue; /* no way to set it, don't show */ - } - error_printf("%s.%s=%s\n", driver, prop->name, - prop->info->legacy_name ?: prop->info->name); - } - } + + obj = object_new(driver); + object_property_foreach(obj, display_property, NULL); + object_delete(obj); + return 1; } @@ -481,50 +489,56 @@ DeviceState *qdev_device_add(QemuOpts *opts) #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) static void qbus_print(Monitor *mon, BusState *bus, int indent); -static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, - const char *prefix, int indent) +typedef struct QTreePrinter { - if (!props) - return; - for (; props->name; props++) { - Error *err = NULL; - char *value; - char *legacy_name = g_strdup_printf("legacy-%s", props->name); - if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { - value = object_property_get_str(OBJECT(dev), legacy_name, &err); - } else { - value = object_property_get_str(OBJECT(dev), props->name, &err); - } - g_free(legacy_name); + Visitor visitor; + Monitor *mon; + int indent; + const char *prefix; +} QTreePrinter; + +static void qtree_printer_visit_str(Visitor *v, char **obj, + const char *name, Error **errp) +{ + QTreePrinter *p = (QTreePrinter *)v; - if (err) { - error_free(err); - continue; - } - qdev_printf("%s-prop: %s = %s\n", prefix, props->name, - value && *value ? value : "<null>"); - g_free(value); + monitor_printf(p->mon, "%*sdev-prop: %s = %s\n", + p->indent, "", &name[7], *obj); +} + +static void qdev_print_prop(Object *obj, const char *name, + const char *typename, bool read_only, + void *opaque) +{ + QTreePrinter *printer = opaque; + + if (strstart(typename, "legacy<", NULL)) { + object_property_get(obj, &printer->visitor, name, NULL); } } static void qdev_print(Monitor *mon, DeviceState *dev, int indent) { + QTreePrinter printer = { + .visitor.type_str = qtree_printer_visit_str, + .mon = mon, + .indent = indent + 2, + }; BusState *child; + qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)), dev->id ? dev->id : ""); - indent += 2; if (dev->num_gpio_in) { qdev_printf("gpio-in %d\n", dev->num_gpio_in); } if (dev->num_gpio_out) { qdev_printf("gpio-out %d\n", dev->num_gpio_out); } - qdev_print_props(mon, dev, qdev_get_props(dev), "dev", indent); - qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent); + object_property_foreach(OBJECT(dev), qdev_print_prop, &printer); if (dev->parent_bus->info->print_dev) - dev->parent_bus->info->print_dev(mon, dev, indent); + dev->parent_bus->info->print_dev(mon, dev, indent + 2); QLIST_FOREACH(child, &dev->child_bus, sibling) { - qbus_print(mon, child, indent); + qbus_print(mon, child, indent + 2); } } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 894fa79..0c6dade 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -925,31 +925,17 @@ PropertyInfo qdev_prop_blocksize = { /* --- public helpers --- */ -static Property *qdev_prop_walk(Property *props, const char *name) -{ - if (!props) - return NULL; - while (props->name) { - if (strcmp(props->name, name) == 0) - return props; - props++; - } - return NULL; -} - static Property *qdev_prop_find(DeviceState *dev, const char *name) { - Property *prop; - - /* device properties */ - prop = qdev_prop_walk(qdev_get_props(dev), name); - if (prop) - return prop; + Object *obj = OBJECT(dev); + ObjectProperty *prop; - /* bus properties */ - prop = qdev_prop_walk(dev->parent_bus->info->props, name); - if (prop) - return prop; + QTAILQ_FOREACH(prop, &obj->properties, node) { + if (strstart(prop->type, "legacy<", NULL) && + strcmp(&prop->name[7], name) == 0) { + return prop->opaque; + } + } return NULL; } diff --git a/hw/qdev.c b/hw/qdev.c index e835650..05ed0c9 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -45,18 +45,6 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev) return dc->vmsd; } -BusInfo *qdev_get_bus_info(DeviceState *dev) -{ - DeviceClass *dc = DEVICE_GET_CLASS(dev); - return dc->bus_info; -} - -Property *qdev_get_props(DeviceState *dev) -{ - DeviceClass *dc = DEVICE_GET_CLASS(dev); - return dc->props; -} - const char *qdev_fw_name(DeviceState *dev) { DeviceClass *dc = DEVICE_GET_CLASS(dev); @@ -95,7 +83,6 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus) dev->parent_bus = bus; QTAILQ_INSERT_HEAD(&bus->children, dev, sibling); - qdev_add_properties(dev, dev->parent_bus->info->props); } /* Create a new device. This only initializes the device state structure @@ -609,7 +596,7 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop, object_property_add(OBJECT(dev), name, type, prop->info->print ? qdev_get_legacy_property : prop->info->get, prop->info->parse ? qdev_set_legacy_property : prop->info->set, - NULL, + prop->info->release, prop, errp); g_free(type); @@ -643,7 +630,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, static void device_initfn(Object *obj) { DeviceState *dev = DEVICE(obj); - Property *prop; + DeviceClass *dc = DEVICE_GET_CLASS(dev); if (qdev_hotplug) { dev->hotplugged = 1; @@ -653,7 +640,8 @@ static void device_initfn(Object *obj) dev->instance_id_alias = -1; dev->state = DEV_STATE_CREATED; - qdev_add_properties(dev, qdev_get_props(dev)); + qdev_add_properties(dev, dc->props); + object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL); } @@ -661,8 +649,8 @@ static void device_initfn(Object *obj) static void device_finalize(Object *obj) { DeviceState *dev = DEVICE(obj); - BusState *bus; DeviceClass *dc = DEVICE_GET_CLASS(dev); + BusState *bus; if (dev->state == DEV_STATE_INITIALIZED) { while (dev->num_child_bus) { @@ -679,7 +667,9 @@ static void device_finalize(Object *obj) qemu_opts_del(dev->opts); } } - QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); + if (dev->parent_bus) { + QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); + } } void device_reset(DeviceState *dev) diff --git a/hw/qdev.h b/hw/qdev.h index fc3b50f..6d2261f 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -96,7 +96,6 @@ struct BusInfo { bus_get_dev_path get_dev_path; bus_get_fw_dev_path get_fw_dev_path; qbus_resetfn *reset; - Property *props; }; struct BusState { -- 1.7.5.4