qdev: move qdev->info to class

Right now, DeviceInfo acts as the class for qdev.  In order to switch to a
proper ObjectClass derivative, we need to ween all of the callers off of
interacting directly with the info pointer.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2011-12-04 11:08:36 -06:00
parent 32fea4025b
commit 30fbb9fc7c
33 changed files with 119 additions and 93 deletions

View file

@ -45,6 +45,17 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
static BusState *qbus_find(const char *path);
/* Register a new device type. */
static void qdev_subclass_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->info = data;
}
DeviceInfo *qdev_get_info(DeviceState *dev)
{
return DEVICE_GET_CLASS(dev)->info;
}
void qdev_register(DeviceInfo *info)
{
TypeInfo type_info = {};
@ -55,6 +66,8 @@ void qdev_register(DeviceInfo *info)
type_info.name = info->name;
type_info.parent = TYPE_DEVICE;
type_info.instance_size = info->size;
type_info.class_init = qdev_subclass_init;
type_info.class_data = info;
type_register_static(&type_info);
@ -102,9 +115,8 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
assert(bus->info == info->bus_info);
dev = DEVICE(object_new(info->name));
dev->info = info;
dev->parent_bus = bus;
qdev_prop_set_defaults(dev, dev->info->props);
qdev_prop_set_defaults(dev, qdev_get_info(dev)->props);
qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
qdev_prop_set_globals(dev);
QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
@ -117,12 +129,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
QTAILQ_INIT(&dev->properties);
dev->state = DEV_STATE_CREATED;
for (prop = dev->info->props; prop && prop->name; prop++) {
for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
qdev_property_add_static(dev, prop, NULL);
}
for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
for (prop = qdev_get_info(dev)->bus_info->props; prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
qdev_property_add_static(dev, prop, NULL);
}
@ -355,19 +367,19 @@ int qdev_init(DeviceState *dev)
int rc;
assert(dev->state == DEV_STATE_CREATED);
rc = dev->info->init(dev, dev->info);
rc = qdev_get_info(dev)->init(dev, qdev_get_info(dev));
if (rc < 0) {
qdev_free(dev);
return rc;
}
if (dev->info->vmsd) {
vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
if (qdev_get_info(dev)->vmsd) {
vmstate_register_with_alias_id(dev, -1, qdev_get_info(dev)->vmsd, dev,
dev->instance_id_alias,
dev->alias_required_for_version);
}
dev->state = DEV_STATE_INITIALIZED;
if (dev->hotplugged && dev->info->reset) {
dev->info->reset(dev);
if (dev->hotplugged && qdev_get_info(dev)->reset) {
qdev_get_info(dev)->reset(dev);
}
return 0;
}
@ -386,17 +398,17 @@ int qdev_unplug(DeviceState *dev)
qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
return -1;
}
assert(dev->info->unplug != NULL);
assert(qdev_get_info(dev)->unplug != NULL);
qdev_hot_removed = true;
return dev->info->unplug(dev);
return qdev_get_info(dev)->unplug(dev);
}
static int qdev_reset_one(DeviceState *dev, void *opaque)
{
if (dev->info->reset) {
dev->info->reset(dev);
if (qdev_get_info(dev)->reset) {
qdev_get_info(dev)->reset(dev);
}
return 0;
@ -447,7 +459,7 @@ int qdev_simple_unplug_cb(DeviceState *dev)
way is somewhat unclean, and best avoided. */
void qdev_init_nofail(DeviceState *dev)
{
DeviceInfo *info = dev->info;
DeviceInfo *info = qdev_get_info(dev);
if (qdev_init(dev) < 0) {
error_report("Initialization of device %s failed", info->name);
@ -508,15 +520,15 @@ void qdev_free(DeviceState *dev)
bus = QLIST_FIRST(&dev->child_bus);
qbus_free(bus);
}
if (dev->info->vmsd)
vmstate_unregister(dev, dev->info->vmsd, dev);
if (dev->info->exit)
dev->info->exit(dev);
if (qdev_get_info(dev)->vmsd)
vmstate_unregister(dev, qdev_get_info(dev)->vmsd, dev);
if (qdev_get_info(dev)->exit)
qdev_get_info(dev)->exit(dev);
if (dev->opts)
qemu_opts_del(dev->opts);
}
QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
for (prop = dev->info->props; prop && prop->name; prop++) {
for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
if (prop->info->free) {
prop->info->free(dev, prop);
}
@ -708,7 +720,7 @@ static void qbus_list_bus(DeviceState *dev)
const char *sep = " ";
error_printf("child busses at \"%s\":",
dev->id ? dev->id : dev->info->name);
dev->id ? dev->id : qdev_get_info(dev)->name);
QLIST_FOREACH(child, &dev->child_bus, sibling) {
error_printf("%s\"%s\"", sep, child->name);
sep = ", ";
@ -723,7 +735,7 @@ static void qbus_list_dev(BusState *bus)
error_printf("devices at \"%s\":", bus->name);
QTAILQ_FOREACH(dev, &bus->children, sibling) {
error_printf("%s\"%s\"", sep, dev->info->name);
error_printf("%s\"%s\"", sep, qdev_get_info(dev)->name);
if (dev->id)
error_printf("/\"%s\"", dev->id);
sep = ", ";
@ -759,12 +771,12 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
}
}
QTAILQ_FOREACH(dev, &bus->children, sibling) {
if (strcmp(dev->info->name, elem) == 0) {
if (strcmp(qdev_get_info(dev)->name, elem) == 0) {
return dev;
}
}
QTAILQ_FOREACH(dev, &bus->children, sibling) {
if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
if (qdev_get_info(dev)->alias && strcmp(qdev_get_info(dev)->alias, elem) == 0) {
return dev;
}
}
@ -966,7 +978,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
{
BusState *child;
qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
qdev_printf("dev: %s, id \"%s\"\n", qdev_get_info(dev)->name,
dev->id ? dev->id : "");
indent += 2;
if (dev->num_gpio_in) {
@ -975,7 +987,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
if (dev->num_gpio_out) {
qdev_printf("gpio-out %d\n", dev->num_gpio_out);
}
qdev_print_props(mon, dev, dev->info->props, "dev", indent);
qdev_print_props(mon, dev, qdev_get_info(dev)->props, "dev", indent);
qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
if (dev->parent_bus->info->print_dev)
dev->parent_bus->info->print_dev(mon, dev, indent);
@ -1056,7 +1068,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
l += snprintf(p + l, size - l, "%s", d);
g_free(d);
} else {
l += snprintf(p + l, size - l, "%s", dev->info->name);
l += snprintf(p + l, size - l, "%s", qdev_get_info(dev)->name);
}
}
l += snprintf(p + l , size - l, "/");
@ -1078,7 +1090,7 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
char *qdev_get_type(DeviceState *dev, Error **errp)
{
return g_strdup(dev->info->name);
return g_strdup(qdev_get_info(dev)->name);
}
void qdev_ref(DeviceState *dev)
@ -1288,7 +1300,7 @@ void qdev_property_add_child(DeviceState *dev, const char *name,
{
gchar *type;
type = g_strdup_printf("child<%s>", child->info->name);
type = g_strdup_printf("child<%s>", qdev_get_info(child)->name);
qdev_property_add(dev, name, type, qdev_get_child_property,
NULL, qdev_release_child_property,
@ -1340,7 +1352,7 @@ static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
if (target) {
gchar *target_type;
target_type = g_strdup_printf("link<%s>", target->info->name);
target_type = g_strdup_printf("link<%s>", qdev_get_info(target)->name);
if (strcmp(target_type, type) == 0) {
*child = target;
qdev_ref(target);