From 2f262e06f01a38cb8a218b7c5ad71233883a6b55 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 2 Apr 2012 17:33:51 +0200 Subject: qdev: Push "type" property up to Object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that Object is a type, add an instance_init function and push the "type" property from qdev to there. Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 6a8f6bda2b..a9a9f891da 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -515,11 +515,6 @@ char* qdev_get_fw_dev_path(DeviceState *dev) return strdup(path); } -static char *qdev_get_type(Object *obj, Error **errp) -{ - return g_strdup(object_get_typename(obj)); -} - /** * Legacy property handling */ @@ -638,7 +633,6 @@ static void device_initfn(Object *obj) qdev_property_add_static(dev, prop, NULL); } - object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL); qdev_prop_set_defaults(dev, qdev_get_props(dev)); } -- cgit v1.2.3 From bce544740a87cac1636f01c8a28502fec1694b3d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 28 Mar 2012 18:12:47 +0200 Subject: qdev: Move bus properties to abstract superclasses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In qdev, each bus in practice identified an abstract superclass, but this was mostly hidden. In QOM, instead, these abstract classes are explicit so we can move bus properties there. All bus property walks are removed, and all device property walks are changed to look along the class hierarchy instead. We would have duplicates if class A defines some properties and its subclass B does not define any, because class_b->props will be left equal to class_a->props. The solution here is to reintroduce the class_base_init TypeInfo callback, that was present in one of the early QOM versions but removed (on my request...) before committing. This breaks global bus properties, an obscure feature when used with the command-line which is actually useful and used when used by backwards-compatible machine types. So this patch also adjusts the global bus properties in hw/pc_piix.c to refer to the abstract class. Globals and other properties must be modified in the same patch to avoid complications related to initialization ordering. Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index a9a9f891da..f239902291 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); @@ -78,20 +66,12 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, void qdev_set_parent_bus(DeviceState *dev, BusState *bus) { - Property *prop; - if (qdev_hotplug) { assert(bus->allow_hotplug); } dev->parent_bus = bus; QTAILQ_INSERT_HEAD(&bus->children, dev, sibling); - - for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) { - qdev_property_add_legacy(dev, prop, NULL); - qdev_property_add_static(dev, prop, NULL); - } - qdev_prop_set_defaults(dev, dev->parent_bus->info->props); } /* Create a new device. This only initializes the device state structure @@ -618,6 +598,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, static void device_initfn(Object *obj) { DeviceState *dev = DEVICE(obj); + ObjectClass *class; Property *prop; if (qdev_hotplug) { @@ -628,12 +609,15 @@ static void device_initfn(Object *obj) dev->instance_id_alias = -1; dev->state = DEV_STATE_CREATED; - for (prop = qdev_get_props(dev); prop && prop->name; prop++) { - qdev_property_add_legacy(dev, prop, NULL); - qdev_property_add_static(dev, prop, NULL); - } - - qdev_prop_set_defaults(dev, qdev_get_props(dev)); + class = object_get_class(OBJECT(dev)); + do { + for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) { + qdev_property_add_legacy(dev, prop, NULL); + qdev_property_add_static(dev, prop, NULL); + } + qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props); + class = object_class_get_parent(class); + } while (class != object_class_by_name(TYPE_DEVICE)); } /* Unlink device from bus and free the structure. */ @@ -661,6 +645,16 @@ static void device_finalize(Object *obj) QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); } +static void device_class_base_init(ObjectClass *class, void *data) +{ + DeviceClass *klass = DEVICE_CLASS(class); + + /* We explicitly look up properties in the superclasses, + * so do not propagate them to the subclasses. + */ + klass->props = NULL; +} + void device_reset(DeviceState *dev) { DeviceClass *klass = DEVICE_GET_CLASS(dev); @@ -687,6 +681,7 @@ static TypeInfo device_type_info = { .instance_size = sizeof(DeviceState), .instance_init = device_initfn, .instance_finalize = device_finalize, + .class_base_init = device_class_base_init, .abstract = true, .class_size = sizeof(DeviceClass), }; -- cgit v1.2.3 From 4b3582b06b6105ac182a051e4f3647da2c99fd66 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 3 Apr 2012 10:05:07 +0200 Subject: qdev: Clean up global properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that global properties do not depend on buses anymore, set them directly in the device instance_init function. Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index f239902291..483f2e619d 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -111,7 +111,6 @@ DeviceState *qdev_try_create(BusState *bus, const char *type) } qdev_set_parent_bus(dev, bus); - qdev_prop_set_globals(dev); return dev; } @@ -618,6 +617,7 @@ static void device_initfn(Object *obj) qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props); class = object_class_get_parent(class); } while (class != object_class_by_name(TYPE_DEVICE)); + qdev_prop_set_globals(dev); } /* Unlink device from bus and free the structure. */ -- cgit v1.2.3 From fdae245f56f97387bb33b2db03aa015f206c24b2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 2 Apr 2012 22:40:26 +0200 Subject: qdev: Remove qdev_prop_set_defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, qdev_property_add_static can set the default. Signed-off-by: Paolo Bonzini Reviewed-by: Anthony Liguori Signed-off-by: Andreas Färber --- hw/qdev.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 483f2e619d..7f18590594 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -579,6 +579,9 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop, void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp) { + Error *local_err = NULL; + Object *obj = OBJECT(dev); + /* * TODO qdev_prop_ptr does not have getters or setters. It must * go now that it can be replaced with links. The test should be @@ -588,10 +591,28 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, return; } - object_property_add(OBJECT(dev), prop->name, prop->info->name, + object_property_add(obj, prop->name, prop->info->name, prop->info->get, prop->info->set, prop->info->release, - prop, errp); + prop, &local_err); + + if (local_err) { + error_propagate(errp, local_err); + return; + } + if (prop->qtype == QTYPE_NONE) { + return; + } + + if (prop->qtype == QTYPE_QBOOL) { + object_property_set_bool(obj, prop->defval, prop->name, &local_err); + } else if (prop->info->enum_table) { + object_property_set_str(obj, prop->info->enum_table[prop->defval], + prop->name, &local_err); + } else if (prop->qtype == QTYPE_QINT) { + object_property_set_int(obj, prop->defval, prop->name, &local_err); + } + assert_no_error(local_err); } static void device_initfn(Object *obj) @@ -614,7 +635,6 @@ static void device_initfn(Object *obj) qdev_property_add_legacy(dev, prop, NULL); qdev_property_add_static(dev, prop, NULL); } - qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props); class = object_class_get_parent(class); } while (class != object_class_by_name(TYPE_DEVICE)); qdev_prop_set_globals(dev); -- cgit v1.2.3 From 09e5ab6360ce78fc0acbfe29ac100f8148397ca6 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 3 Feb 2012 12:28:43 -0600 Subject: qdev: Use wrapper for qdev_get_path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it easier to remove it from BusInfo. Signed-off-by: Anthony Liguori Signed-off-by: Paolo Bonzini [AF: Drop now unnecessary NULL initialization in scsibus_get_dev_path()] Signed-off-by: Andreas Färber --- hw/qdev.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 7f18590594..7b2802dee0 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -494,6 +494,22 @@ char* qdev_get_fw_dev_path(DeviceState *dev) return strdup(path); } +char *qdev_get_dev_path(DeviceState *dev) +{ + BusInfo *businfo; + + if (!dev || !dev->parent_bus) { + return NULL; + } + + businfo = dev->parent_bus->info; + if (businfo->get_dev_path) { + return businfo->get_dev_path(dev); + } + + return NULL; +} + /** * Legacy property handling */ -- cgit v1.2.3 From 8185d21639ab749979445734ec671122aa96e805 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 2 May 2012 12:06:55 +0200 Subject: qdev: Move SysBus initialization to sysbus.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TYPE_SYSTEM_BUS will be local to hw/sysbus.c, so move existing references to main_system_bus and system_bus_info there. Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 7b2802dee0..7816a3776a 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -34,10 +34,6 @@ int qdev_hotplug = 0; static bool qdev_hot_added = false; static bool qdev_hot_removed = false; -/* This is a nasty hack to allow passing a NULL bus to qdev_create. */ -static BusState *main_system_bus; -static void main_system_bus_create(void); - /* Register a new device type. */ const VMStateDescription *qdev_get_vmsd(DeviceState *dev) { @@ -188,14 +184,6 @@ static int qdev_reset_one(DeviceState *dev, void *opaque) return 0; } -BusState *sysbus_get_default(void) -{ - if (!main_system_bus) { - main_system_bus_create(); - } - return main_system_bus; -} - static int qbus_reset_one(BusState *bus, void *opaque) { if (bus->info->reset) { @@ -415,7 +403,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info, if (parent) { QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling); parent->num_child_bus++; - } else if (bus != main_system_bus) { + } else if (bus != sysbus_get_default()) { /* TODO: once all bus devices are qdevified, only reset handler for main_system_bus should be registered here. */ qemu_register_reset(qbus_reset_all_fn, bus); @@ -432,16 +420,6 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name) return bus; } -static void main_system_bus_create(void) -{ - /* assign main_system_bus before qbus_create_inplace() - * in order to make "if (bus != main_system_bus)" work */ - main_system_bus = g_malloc0(system_bus_info.size); - main_system_bus->qdev_allocated = 1; - qbus_create_inplace(main_system_bus, &system_bus_info, NULL, - "main-system-bus"); -} - void qbus_free(BusState *bus) { DeviceState *dev; @@ -453,7 +431,7 @@ void qbus_free(BusState *bus) QLIST_REMOVE(bus, sibling); bus->parent->num_child_bus--; } else { - assert(bus != main_system_bus); /* main_system_bus is never freed */ + assert(bus != sysbus_get_default()); /* main_system_bus is never freed */ qemu_unregister_reset(qbus_reset_all_fn, bus); } g_free((void*)bus->name); -- cgit v1.2.3 From 0d936928ef87ca1bb7b41b5b89c400c699a7691c Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Wed, 2 May 2012 09:00:20 +0200 Subject: qdev: Convert busses to QEMU Object Model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is far less interesting than it sounds. We simply add an Object to each BusState and then register the types appropriately. Most of the interesting refactoring will follow in the next patches. Since we're changing fundamental type names (BusInfo -> BusClass), it all needs to convert at once. Fortunately, not a lot of code is affected. Signed-off-by: Anthony Liguori Signed-off-by: Paolo Bonzini [AF: Made all new bus TypeInfos static const.] [AF: Made qbus_free() call object_delete(), required {qom,glib}_allocated] Signed-off-by: Andreas Färber --- hw/qdev.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 20 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 7816a3776a..63012b5252 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -81,7 +81,7 @@ DeviceState *qdev_create(BusState *bus, const char *name) if (!dev) { if (bus) { hw_error("Unknown device '%s' for bus '%s'\n", name, - bus->info->name); + object_get_typename(OBJECT(bus))); } else { hw_error("Unknown device '%s' for default sysbus\n", name); } @@ -186,8 +186,9 @@ static int qdev_reset_one(DeviceState *dev, void *opaque) static int qbus_reset_one(BusState *bus, void *opaque) { - if (bus->info->reset) { - return bus->info->reset(bus); + BusClass *bc = BUS_GET_CLASS(bus); + if (bc->reset) { + return bc->reset(bus); } return 0; } @@ -370,13 +371,13 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id) return NULL; } -void qbus_create_inplace(BusState *bus, BusInfo *info, - DeviceState *parent, const char *name) +/* FIXME move this logic into instance_init */ +static void do_qbus_create_inplace(BusState *bus, const char *typename, + DeviceState *parent, const char *name) { char *buf; int i,len; - bus->info = info; bus->parent = parent; if (name) { @@ -390,9 +391,9 @@ void qbus_create_inplace(BusState *bus, BusInfo *info, bus->name = buf; } else { /* no id -> use lowercase bus type for bus name */ - len = strlen(info->name) + 16; + len = strlen(typename) + 16; buf = g_malloc(len); - len = snprintf(buf, len, "%s.%d", info->name, + len = snprintf(buf, len, "%s.%d", typename, parent ? parent->num_child_bus : 0); for (i = 0; i < len; i++) buf[i] = qemu_tolower(buf[i]); @@ -410,13 +411,20 @@ void qbus_create_inplace(BusState *bus, BusInfo *info, } } -BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name) +void qbus_create_inplace(BusState *bus, const char *typename, + DeviceState *parent, const char *name) +{ + object_initialize(bus, typename); + do_qbus_create_inplace(bus, typename, parent, name); +} + +BusState *qbus_create(const char *typename, DeviceState *parent, const char *name) { BusState *bus; - bus = g_malloc0(info->size); - bus->qdev_allocated = 1; - qbus_create_inplace(bus, info, parent, name); + bus = BUS(object_new(typename)); + bus->qom_allocated = true; + do_qbus_create_inplace(bus, typename, parent, name); return bus; } @@ -435,9 +443,25 @@ void qbus_free(BusState *bus) qemu_unregister_reset(qbus_reset_all_fn, bus); } g_free((void*)bus->name); - if (bus->qdev_allocated) { - g_free(bus); + if (bus->qom_allocated) { + object_delete(OBJECT(bus)); + } else { + object_finalize(OBJECT(bus)); + if (bus->glib_allocated) { + g_free(bus); + } + } +} + +static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) +{ + BusClass *bc = BUS_GET_CLASS(bus); + + if (bc->get_fw_dev_path) { + return bc->get_fw_dev_path(dev); } + + return NULL; } static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) @@ -447,8 +471,8 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) if (dev && dev->parent_bus) { char *d; l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size); - if (dev->parent_bus->info->get_fw_dev_path) { - d = dev->parent_bus->info->get_fw_dev_path(dev); + d = bus_get_fw_dev_path(dev->parent_bus, dev); + if (d) { l += snprintf(p + l, size - l, "%s", d); g_free(d); } else { @@ -474,15 +498,15 @@ char* qdev_get_fw_dev_path(DeviceState *dev) char *qdev_get_dev_path(DeviceState *dev) { - BusInfo *businfo; + BusClass *bc; if (!dev || !dev->parent_bus) { return NULL; } - businfo = dev->parent_bus->info; - if (businfo->get_dev_path) { - return businfo->get_dev_path(dev); + bc = BUS_GET_CLASS(dev->parent_bus); + if (bc->get_dev_path) { + return bc->get_dev_path(dev); } return NULL; @@ -700,8 +724,17 @@ static TypeInfo device_type_info = { .class_size = sizeof(DeviceClass), }; +static const TypeInfo bus_info = { + .name = TYPE_BUS, + .parent = TYPE_OBJECT, + .instance_size = sizeof(BusState), + .abstract = true, + .class_size = sizeof(BusClass), +}; + static void qdev_register_types(void) { + type_register_static(&bus_info); type_register_static(&device_type_info); } -- cgit v1.2.3 From f968fc6892daf02865cce8af277cc755be690eda Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Wed, 2 May 2012 10:39:01 +0200 Subject: qdev: Connect busses with their parent devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes SysBus part of the root hierarchy and all busses children of their respective parent DeviceState. Signed-off-by: Anthony Liguori Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 63012b5252..dc46e7bd10 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -404,6 +404,7 @@ static void do_qbus_create_inplace(BusState *bus, const char *typename, if (parent) { QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling); parent->num_child_bus++; + object_property_add_child(OBJECT(parent), bus->name, OBJECT(bus), NULL); } else if (bus != sysbus_get_default()) { /* TODO: once all bus devices are qdevified, only reset handler for main_system_bus should be registered here. */ @@ -656,6 +657,9 @@ static void device_initfn(Object *obj) class = object_class_get_parent(class); } while (class != object_class_by_name(TYPE_DEVICE)); qdev_prop_set_globals(dev); + + object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS, + (Object **)&dev->parent_bus, NULL); } /* Unlink device from bus and free the structure. */ -- cgit v1.2.3 From 0866aca1de15a12547f52ff8563cf7c163e1898e Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 23 Dec 2011 15:34:39 -0600 Subject: qbus: Make child devices links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make qbus children show up as link<> properties. There is no stable addressing for qbus children so we use an unstable naming convention. This is okay in QOM though because the composition name is expected to be what's stable. Signed-off-by: Anthony Liguori Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index dc46e7bd10..fc79b24103 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -60,14 +60,48 @@ bool qdev_exists(const char *name) static void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp); -void qdev_set_parent_bus(DeviceState *dev, BusState *bus) +static void bus_remove_child(BusState *bus, DeviceState *child) { + BusChild *kid; + + QTAILQ_FOREACH(kid, &bus->children, sibling) { + if (kid->child == child) { + char name[32]; + + snprintf(name, sizeof(name), "child[%d]", kid->index); + QTAILQ_REMOVE(&bus->children, kid, sibling); + object_property_del(OBJECT(bus), name, NULL); + g_free(kid); + return; + } + } +} + +static void bus_add_child(BusState *bus, DeviceState *child) +{ + char name[32]; + BusChild *kid = g_malloc0(sizeof(*kid)); + if (qdev_hotplug) { assert(bus->allow_hotplug); } + kid->index = bus->max_index++; + kid->child = child; + + QTAILQ_INSERT_HEAD(&bus->children, kid, sibling); + + snprintf(name, sizeof(name), "child[%d]", kid->index); + object_property_add_link(OBJECT(bus), name, + object_get_typename(OBJECT(child)), + (Object **)&kid->child, + NULL); +} + +void qdev_set_parent_bus(DeviceState *dev, BusState *bus) +{ dev->parent_bus = bus; - QTAILQ_INSERT_HEAD(&bus->children, dev, sibling); + bus_add_child(bus, dev); } /* Create a new device. This only initializes the device state structure @@ -310,7 +344,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, qbus_walkerfn *busfn, void *opaque) { - DeviceState *dev; + BusChild *kid; int err; if (busfn) { @@ -320,8 +354,8 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, } } - QTAILQ_FOREACH(dev, &bus->children, sibling) { - err = qdev_walk_children(dev, devfn, busfn, opaque); + QTAILQ_FOREACH(kid, &bus->children, sibling) { + err = qdev_walk_children(kid->child, devfn, busfn, opaque); if (err < 0) { return err; } @@ -355,12 +389,17 @@ int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, DeviceState *qdev_find_recursive(BusState *bus, const char *id) { - DeviceState *dev, *ret; + BusChild *kid; + DeviceState *ret; BusState *child; - QTAILQ_FOREACH(dev, &bus->children, sibling) { - if (dev->id && strcmp(dev->id, id) == 0) + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; + + if (dev->id && strcmp(dev->id, id) == 0) { return dev; + } + QLIST_FOREACH(child, &dev->child_bus, sibling) { ret = qdev_find_recursive(child, id); if (ret) { @@ -431,9 +470,10 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam void qbus_free(BusState *bus) { - DeviceState *dev; + BusChild *kid; - while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) { + while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) { + DeviceState *dev = kid->child; qdev_free(dev); } if (bus->parent) { @@ -684,7 +724,9 @@ static void device_finalize(Object *obj) qemu_opts_del(dev->opts); } } - QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); + if (dev->parent_bus) { + bus_remove_child(dev->parent_bus, dev); + } } static void device_class_base_init(ObjectClass *class, void *data) -- cgit v1.2.3 From ac7d1ba6d15ff10343d2ff5ea331fa6a41174f3f Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 3 Feb 2012 13:32:19 -0600 Subject: qbus: Initialize in standard way MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move code to an initfn and finalizer. Replace do_qbus_create_inplace() with qbus_realize(). Signed-off-by: Anthony Liguori Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 80 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 32 deletions(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index fc79b24103..38ca58175f 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -410,40 +410,35 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id) return NULL; } -/* FIXME move this logic into instance_init */ -static void do_qbus_create_inplace(BusState *bus, const char *typename, - DeviceState *parent, const char *name) +static void qbus_realize(BusState *bus) { + const char *typename = object_get_typename(OBJECT(bus)); char *buf; int i,len; - bus->parent = parent; - - if (name) { + if (bus->name) { /* use supplied name */ - bus->name = g_strdup(name); - } else if (parent && parent->id) { + } else if (bus->parent && bus->parent->id) { /* parent device has id -> use it for bus name */ - len = strlen(parent->id) + 16; + len = strlen(bus->parent->id) + 16; buf = g_malloc(len); - snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus); + snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus); bus->name = buf; } else { /* no id -> use lowercase bus type for bus name */ len = strlen(typename) + 16; buf = g_malloc(len); len = snprintf(buf, len, "%s.%d", typename, - parent ? parent->num_child_bus : 0); + bus->parent ? bus->parent->num_child_bus : 0); for (i = 0; i < len; i++) buf[i] = qemu_tolower(buf[i]); bus->name = buf; } - QTAILQ_INIT(&bus->children); - if (parent) { - QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling); - parent->num_child_bus++; - object_property_add_child(OBJECT(parent), bus->name, OBJECT(bus), NULL); + if (bus->parent) { + QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling); + bus->parent->num_child_bus++; + object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL); } else if (bus != sysbus_get_default()) { /* TODO: once all bus devices are qdevified, only reset handler for main_system_bus should be registered here. */ @@ -455,7 +450,10 @@ void qbus_create_inplace(BusState *bus, const char *typename, DeviceState *parent, const char *name) { object_initialize(bus, typename); - do_qbus_create_inplace(bus, typename, parent, name); + + bus->parent = parent; + bus->name = name ? g_strdup(name) : NULL; + qbus_realize(bus); } BusState *qbus_create(const char *typename, DeviceState *parent, const char *name) @@ -464,26 +462,16 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam bus = BUS(object_new(typename)); bus->qom_allocated = true; - do_qbus_create_inplace(bus, typename, parent, name); + + bus->parent = parent; + bus->name = name ? g_strdup(name) : NULL; + qbus_realize(bus); + return bus; } void qbus_free(BusState *bus) { - BusChild *kid; - - while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) { - DeviceState *dev = kid->child; - qdev_free(dev); - } - if (bus->parent) { - QLIST_REMOVE(bus, sibling); - bus->parent->num_child_bus--; - } else { - assert(bus != sysbus_get_default()); /* main_system_bus is never freed */ - qemu_unregister_reset(qbus_reset_all_fn, bus); - } - g_free((void*)bus->name); if (bus->qom_allocated) { object_delete(OBJECT(bus)); } else { @@ -770,12 +758,40 @@ static TypeInfo device_type_info = { .class_size = sizeof(DeviceClass), }; +static void qbus_initfn(Object *obj) +{ + BusState *bus = BUS(obj); + + QTAILQ_INIT(&bus->children); +} + +static void qbus_finalize(Object *obj) +{ + BusState *bus = BUS(obj); + BusChild *kid; + + while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) { + DeviceState *dev = kid->child; + qdev_free(dev); + } + if (bus->parent) { + QLIST_REMOVE(bus, sibling); + bus->parent->num_child_bus--; + } else { + assert(bus != sysbus_get_default()); /* main_system_bus is never freed */ + qemu_unregister_reset(qbus_reset_all_fn, bus); + } + g_free((char *)bus->name); +} + static const TypeInfo bus_info = { .name = TYPE_BUS, .parent = TYPE_OBJECT, .instance_size = sizeof(BusState), .abstract = true, .class_size = sizeof(BusClass), + .instance_init = qbus_initfn, + .instance_finalize = qbus_finalize, }; static void qdev_register_types(void) -- cgit v1.2.3 From 8cb6789a31e8c5823b36d84416433c145a1e6442 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 30 Mar 2012 14:54:31 +0200 Subject: qdev: Remove qdev_prop_exists() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Can be replaced everywhere with object_property_find(). Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/qdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 38ca58175f..654cbcaccf 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -323,7 +323,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) if (nd->netdev) qdev_prop_set_netdev(dev, "netdev", nd->netdev); if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED && - qdev_prop_exists(dev, "vectors")) { + object_property_find(OBJECT(dev), "vectors")) { qdev_prop_set_uint32(dev, "vectors", nd->nvectors); } nd->instantiated = 1; -- cgit v1.2.3 From 89bfe000433a601d30729086e88519ff36b85103 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 12 Apr 2012 18:00:18 +0200 Subject: qom: Push error reporting to object_property_find() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids duplicated error_set(). Signed-off-by: Paolo Bonzini [AF: Also drop error_set() in object_property_del().] Signed-off-by: Andreas Färber --- hw/qdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/qdev.c') diff --git a/hw/qdev.c b/hw/qdev.c index 654cbcaccf..b20b34d11f 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -323,7 +323,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) if (nd->netdev) qdev_prop_set_netdev(dev, "netdev", nd->netdev); if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED && - object_property_find(OBJECT(dev), "vectors")) { + object_property_find(OBJECT(dev), "vectors", NULL)) { qdev_prop_set_uint32(dev, "vectors", nd->nvectors); } nd->instantiated = 1; -- cgit v1.2.3