mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
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:
parent
32fea4025b
commit
30fbb9fc7c
33 changed files with 119 additions and 93 deletions
70
hw/qdev.c
70
hw/qdev.c
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue