qdev: refactor device creation to allow bus_info to be set only in class

As we use class_init to set class members, DeviceInfo no longer holds this
information.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2011-12-09 12:08:01 -06:00
parent d253e09619
commit 18b6dade8c
1 changed files with 19 additions and 23 deletions

View File

@ -119,21 +119,29 @@ const char *qdev_fw_name(DeviceState *dev)
return object_get_typename(OBJECT(dev));
}
void qdev_register_subclass(DeviceInfo *info, const char *parent)
static void qdev_do_register_subclass(DeviceInfo *info, const char *parent,
const char *name)
{
TypeInfo type_info = {};
assert(info->size >= sizeof(DeviceState));
assert(!info->next);
type_info.name = info->name;
type_info.name = name;
type_info.parent = parent;
type_info.instance_size = info->size;
type_info.class_init = qdev_subclass_init;
type_info.class_data = info;
type_register_static(&type_info);
}
void qdev_register_subclass(DeviceInfo *info, const char *parent)
{
qdev_do_register_subclass(info, parent, info->name);
if (info->alias) {
qdev_do_register_subclass(info, parent, info->alias);
}
info->next = device_info_list;
device_info_list = info;
}
@ -173,12 +181,12 @@ bool qdev_exists(const char *name)
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp);
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
static DeviceState *qdev_create_from_info(BusState *bus, const char *typename)
{
DeviceState *dev;
Property *prop;
dev = DEVICE(object_new(info->name));
dev = DEVICE(object_new(typename));
dev->parent_bus = bus;
qdev_prop_set_defaults(dev, qdev_get_props(dev));
qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
@ -230,18 +238,11 @@ DeviceState *qdev_create(BusState *bus, const char *name)
DeviceState *qdev_try_create(BusState *bus, const char *name)
{
DeviceInfo *info;
if (!bus) {
bus = sysbus_get_default();
}
info = qdev_find_info(bus->info, name);
if (!info) {
return NULL;
}
return qdev_create_from_info(bus, info);
return qdev_create_from_info(bus, name);
}
static void qdev_print_devinfo(DeviceInfo *info)
@ -352,8 +353,8 @@ static DeviceState *qdev_get_peripheral_anon(void)
DeviceState *qdev_device_add(QemuOpts *opts)
{
DeviceClass *k;
const char *driver, *path, *id;
DeviceInfo *info;
DeviceState *qdev;
BusState *bus;
@ -364,12 +365,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
}
/* find driver */
info = qdev_find_info(NULL, driver);
if (!info || info->no_user) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
error_printf_unless_qmp("Try with argument '?' for a list.\n");
return NULL;
}
k = DEVICE_CLASS(object_class_by_name(driver));
/* find bus */
path = qemu_opt_get(opts, "bus");
@ -378,16 +374,16 @@ DeviceState *qdev_device_add(QemuOpts *opts)
if (!bus) {
return NULL;
}
if (bus->info != info->bus_info) {
if (bus->info != k->bus_info) {
qerror_report(QERR_BAD_BUS_FOR_DEVICE,
driver, bus->info->name);
return NULL;
}
} else {
bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
bus = qbus_find_recursive(main_system_bus, NULL, k->bus_info);
if (!bus) {
qerror_report(QERR_NO_BUS_FOR_DEVICE,
info->name, info->bus_info->name);
driver, k->bus_info->name);
return NULL;
}
}
@ -397,7 +393,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
}
/* create device, set properties */
qdev = qdev_create_from_info(bus, info);
qdev = qdev_create_from_info(bus, driver);
id = qemu_opts_id(opts);
if (id) {
qdev->id = id;