qdev: remove info from class
Now DeviceInfo is no longer used after object construction. All of the relevant members have been moved to DeviceClass. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
4be9f0d11c
commit
6e008585eb
4
hw/pci.c
4
hw/pci.c
|
@ -1467,7 +1467,9 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||||
}
|
}
|
||||||
|
|
||||||
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
|
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
|
||||||
pci_dev = do_pci_register_device(pci_dev, bus, base->name, pci_dev->devfn);
|
pci_dev = do_pci_register_device(pci_dev, bus,
|
||||||
|
object_get_typename(OBJECT(qdev)),
|
||||||
|
pci_dev->devfn);
|
||||||
if (pci_dev == NULL)
|
if (pci_dev == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (qdev->hotplugged && pc->no_hotplug) {
|
if (qdev->hotplugged && pc->no_hotplug) {
|
||||||
|
|
94
hw/qdev.c
94
hw/qdev.c
|
@ -48,46 +48,54 @@ static BusState *qbus_find(const char *path);
|
||||||
static void qdev_subclass_init(ObjectClass *klass, void *data)
|
static void qdev_subclass_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
DeviceInfo *info = data;
|
||||||
|
|
||||||
dc->info = data;
|
dc->fw_name = info->fw_name;
|
||||||
dc->reset = dc->info->reset;
|
dc->alias = info->alias;
|
||||||
|
dc->desc = info->desc;
|
||||||
|
dc->props = info->props;
|
||||||
|
dc->no_user = info->no_user;
|
||||||
|
|
||||||
/* Poison to try to detect future uses */
|
dc->reset = info->reset;
|
||||||
dc->info->reset = NULL;
|
|
||||||
|
|
||||||
if (dc->info->class_init) {
|
dc->vmsd = info->vmsd;
|
||||||
dc->info->class_init(klass, data);
|
|
||||||
|
dc->init = info->init;
|
||||||
|
dc->unplug = info->unplug;
|
||||||
|
dc->exit = info->exit;
|
||||||
|
dc->bus_info = info->bus_info;
|
||||||
|
|
||||||
|
if (info->class_init) {
|
||||||
|
info->class_init(klass, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DeviceInfo *qdev_get_info(DeviceState *dev)
|
|
||||||
{
|
|
||||||
return DEVICE_GET_CLASS(dev)->info;
|
|
||||||
}
|
|
||||||
|
|
||||||
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
|
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
|
||||||
{
|
{
|
||||||
return qdev_get_info(dev)->vmsd;
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
return dc->vmsd;
|
||||||
}
|
}
|
||||||
|
|
||||||
BusInfo *qdev_get_bus_info(DeviceState *dev)
|
BusInfo *qdev_get_bus_info(DeviceState *dev)
|
||||||
{
|
{
|
||||||
return qdev_get_info(dev)->bus_info;
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
return dc->bus_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
Property *qdev_get_props(DeviceState *dev)
|
Property *qdev_get_props(DeviceState *dev)
|
||||||
{
|
{
|
||||||
return qdev_get_info(dev)->props;
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
return dc->props;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *qdev_fw_name(DeviceState *dev)
|
const char *qdev_fw_name(DeviceState *dev)
|
||||||
{
|
{
|
||||||
DeviceInfo *info = qdev_get_info(dev);
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
if (info->fw_name) {
|
if (dc->fw_name) {
|
||||||
return info->fw_name;
|
return dc->fw_name;
|
||||||
} else if (info->alias) {
|
} else if (dc->alias) {
|
||||||
return info->alias;
|
return dc->alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
return object_get_typename(OBJECT(dev));
|
return object_get_typename(OBJECT(dev));
|
||||||
|
@ -159,7 +167,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
|
||||||
assert(bus->info == info->bus_info);
|
assert(bus->info == info->bus_info);
|
||||||
dev = DEVICE(object_new(info->name));
|
dev = DEVICE(object_new(info->name));
|
||||||
dev->parent_bus = bus;
|
dev->parent_bus = bus;
|
||||||
qdev_prop_set_defaults(dev, qdev_get_info(dev)->props);
|
qdev_prop_set_defaults(dev, qdev_get_props(dev));
|
||||||
qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
|
qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
|
||||||
qdev_prop_set_globals(dev);
|
qdev_prop_set_globals(dev);
|
||||||
QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
|
QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
|
||||||
|
@ -172,12 +180,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
|
||||||
QTAILQ_INIT(&dev->properties);
|
QTAILQ_INIT(&dev->properties);
|
||||||
dev->state = DEV_STATE_CREATED;
|
dev->state = DEV_STATE_CREATED;
|
||||||
|
|
||||||
for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
|
for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
|
||||||
qdev_property_add_legacy(dev, prop, NULL);
|
qdev_property_add_legacy(dev, prop, NULL);
|
||||||
qdev_property_add_static(dev, prop, NULL);
|
qdev_property_add_static(dev, prop, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (prop = qdev_get_info(dev)->bus_info->props; prop && prop->name; prop++) {
|
for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
|
||||||
qdev_property_add_legacy(dev, prop, NULL);
|
qdev_property_add_legacy(dev, prop, NULL);
|
||||||
qdev_property_add_static(dev, prop, NULL);
|
qdev_property_add_static(dev, prop, NULL);
|
||||||
}
|
}
|
||||||
|
@ -407,16 +415,19 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||||
Return 0 on success. */
|
Return 0 on success. */
|
||||||
int qdev_init(DeviceState *dev)
|
int qdev_init(DeviceState *dev)
|
||||||
{
|
{
|
||||||
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert(dev->state == DEV_STATE_CREATED);
|
assert(dev->state == DEV_STATE_CREATED);
|
||||||
rc = qdev_get_info(dev)->init(dev, qdev_get_info(dev));
|
|
||||||
|
/* FIXME hopefully this doesn't break anything */
|
||||||
|
rc = dc->init(dev, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
qdev_free(dev);
|
qdev_free(dev);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if (qdev_get_info(dev)->vmsd) {
|
if (qdev_get_vmsd(dev)) {
|
||||||
vmstate_register_with_alias_id(dev, -1, qdev_get_info(dev)->vmsd, dev,
|
vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
|
||||||
dev->instance_id_alias,
|
dev->instance_id_alias,
|
||||||
dev->alias_required_for_version);
|
dev->alias_required_for_version);
|
||||||
}
|
}
|
||||||
|
@ -437,15 +448,17 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
|
||||||
|
|
||||||
int qdev_unplug(DeviceState *dev)
|
int qdev_unplug(DeviceState *dev)
|
||||||
{
|
{
|
||||||
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
if (!dev->parent_bus->allow_hotplug) {
|
if (!dev->parent_bus->allow_hotplug) {
|
||||||
qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
|
qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
assert(qdev_get_info(dev)->unplug != NULL);
|
assert(dc->unplug != NULL);
|
||||||
|
|
||||||
qdev_hot_removed = true;
|
qdev_hot_removed = true;
|
||||||
|
|
||||||
return qdev_get_info(dev)->unplug(dev);
|
return dc->unplug(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qdev_reset_one(DeviceState *dev, void *opaque)
|
static int qdev_reset_one(DeviceState *dev, void *opaque)
|
||||||
|
@ -500,10 +513,9 @@ int qdev_simple_unplug_cb(DeviceState *dev)
|
||||||
way is somewhat unclean, and best avoided. */
|
way is somewhat unclean, and best avoided. */
|
||||||
void qdev_init_nofail(DeviceState *dev)
|
void qdev_init_nofail(DeviceState *dev)
|
||||||
{
|
{
|
||||||
DeviceInfo *info = qdev_get_info(dev);
|
|
||||||
|
|
||||||
if (qdev_init(dev) < 0) {
|
if (qdev_init(dev) < 0) {
|
||||||
error_report("Initialization of device %s failed", info->name);
|
error_report("Initialization of device %s failed",
|
||||||
|
object_get_typename(OBJECT(dev)));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,6 +565,7 @@ void qdev_free(DeviceState *dev)
|
||||||
{
|
{
|
||||||
BusState *bus;
|
BusState *bus;
|
||||||
Property *prop;
|
Property *prop;
|
||||||
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
qdev_property_del_all(dev);
|
qdev_property_del_all(dev);
|
||||||
|
|
||||||
|
@ -561,15 +574,18 @@ void qdev_free(DeviceState *dev)
|
||||||
bus = QLIST_FIRST(&dev->child_bus);
|
bus = QLIST_FIRST(&dev->child_bus);
|
||||||
qbus_free(bus);
|
qbus_free(bus);
|
||||||
}
|
}
|
||||||
if (qdev_get_info(dev)->vmsd)
|
if (qdev_get_vmsd(dev)) {
|
||||||
vmstate_unregister(dev, qdev_get_info(dev)->vmsd, dev);
|
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
|
||||||
if (qdev_get_info(dev)->exit)
|
}
|
||||||
qdev_get_info(dev)->exit(dev);
|
if (dc->exit) {
|
||||||
if (dev->opts)
|
dc->exit(dev);
|
||||||
|
}
|
||||||
|
if (dev->opts) {
|
||||||
qemu_opts_del(dev->opts);
|
qemu_opts_del(dev->opts);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
|
QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
|
||||||
for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
|
for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
|
||||||
if (prop->info->free) {
|
if (prop->info->free) {
|
||||||
prop->info->free(dev, prop);
|
prop->info->free(dev, prop);
|
||||||
}
|
}
|
||||||
|
@ -817,7 +833,9 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QTAILQ_FOREACH(dev, &bus->children, sibling) {
|
QTAILQ_FOREACH(dev, &bus->children, sibling) {
|
||||||
if (qdev_get_info(dev)->alias && strcmp(qdev_get_info(dev)->alias, elem) == 0) {
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
|
if (dc->alias && strcmp(dc->alias, elem) == 0) {
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1046,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
|
||||||
if (dev->num_gpio_out) {
|
if (dev->num_gpio_out) {
|
||||||
qdev_printf("gpio-out %d\n", dev->num_gpio_out);
|
qdev_printf("gpio-out %d\n", dev->num_gpio_out);
|
||||||
}
|
}
|
||||||
qdev_print_props(mon, dev, qdev_get_info(dev)->props, "dev", indent);
|
qdev_print_props(mon, dev, qdev_get_props(dev), "dev", indent);
|
||||||
qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
|
qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
|
||||||
if (dev->parent_bus->info->print_dev)
|
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);
|
||||||
|
|
26
hw/qdev.h
26
hw/qdev.h
|
@ -72,10 +72,30 @@ typedef struct DeviceProperty
|
||||||
#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
|
#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
|
||||||
#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
|
#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
|
||||||
|
|
||||||
|
typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
|
||||||
|
typedef int (*qdev_event)(DeviceState *dev);
|
||||||
|
typedef void (*qdev_resetfn)(DeviceState *dev);
|
||||||
|
|
||||||
typedef struct DeviceClass {
|
typedef struct DeviceClass {
|
||||||
ObjectClass parent_class;
|
ObjectClass parent_class;
|
||||||
DeviceInfo *info;
|
|
||||||
|
const char *fw_name;
|
||||||
|
const char *alias;
|
||||||
|
const char *desc;
|
||||||
|
Property *props;
|
||||||
|
int no_user;
|
||||||
|
|
||||||
|
/* callbacks */
|
||||||
void (*reset)(DeviceState *dev);
|
void (*reset)(DeviceState *dev);
|
||||||
|
|
||||||
|
/* device state */
|
||||||
|
const VMStateDescription *vmsd;
|
||||||
|
|
||||||
|
/* Private to qdev / bus. */
|
||||||
|
qdev_initfn init;
|
||||||
|
qdev_event unplug;
|
||||||
|
qdev_event exit;
|
||||||
|
BusInfo *bus_info;
|
||||||
} DeviceClass;
|
} DeviceClass;
|
||||||
|
|
||||||
/* This structure should not be accessed directly. We declare it here
|
/* This structure should not be accessed directly. We declare it here
|
||||||
|
@ -213,10 +233,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
|
||||||
|
|
||||||
/*** Device API. ***/
|
/*** Device API. ***/
|
||||||
|
|
||||||
typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
|
|
||||||
typedef int (*qdev_event)(DeviceState *dev);
|
|
||||||
typedef void (*qdev_resetfn)(DeviceState *dev);
|
|
||||||
|
|
||||||
struct DeviceInfo {
|
struct DeviceInfo {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *fw_name;
|
const char *fw_name;
|
||||||
|
|
Loading…
Reference in a new issue