summaryrefslogtreecommitdiff
path: root/qdev-monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'qdev-monitor.c')
-rw-r--r--qdev-monitor.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/qdev-monitor.c b/qdev-monitor.c
index a02c925cb3..dc37a43dd9 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -453,11 +453,12 @@ static BusState *qbus_find(const char *path)
DeviceState *qdev_device_add(QemuOpts *opts)
{
- ObjectClass *obj;
- DeviceClass *k;
+ ObjectClass *oc;
+ DeviceClass *dc;
const char *driver, *path, *id;
- DeviceState *qdev;
+ DeviceState *dev;
BusState *bus = NULL;
+ Error *err = NULL;
driver = qemu_opt_get(opts, "driver");
if (!driver) {
@@ -466,22 +467,28 @@ DeviceState *qdev_device_add(QemuOpts *opts)
}
/* find driver */
- obj = object_class_by_name(driver);
- if (!obj) {
+ oc = object_class_by_name(driver);
+ if (!oc) {
const char *typename = find_typename_by_alias(driver);
if (typename) {
driver = typename;
- obj = object_class_by_name(driver);
+ oc = object_class_by_name(driver);
}
}
- if (!obj) {
+ if (!oc) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
return NULL;
}
- k = DEVICE_CLASS(obj);
+ if (object_class_is_abstract(oc)) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
+ "non-abstract device type");
+ return NULL;
+ }
+
+ dc = DEVICE_CLASS(oc);
/* find bus */
path = qemu_opt_get(opts, "bus");
@@ -490,16 +497,16 @@ DeviceState *qdev_device_add(QemuOpts *opts)
if (!bus) {
return NULL;
}
- if (!object_dynamic_cast(OBJECT(bus), k->bus_type)) {
+ if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
qerror_report(QERR_BAD_BUS_FOR_DEVICE,
driver, object_get_typename(OBJECT(bus)));
return NULL;
}
- } else if (k->bus_type != NULL) {
- bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
+ } else if (dc->bus_type != NULL) {
+ bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
if (!bus) {
qerror_report(QERR_NO_BUS_FOR_DEVICE,
- k->bus_type, driver);
+ dc->bus_type, driver);
return NULL;
}
}
@@ -509,36 +516,42 @@ DeviceState *qdev_device_add(QemuOpts *opts)
}
/* create device, set properties */
- qdev = DEVICE(object_new(driver));
+ dev = DEVICE(object_new(driver));
if (bus) {
- qdev_set_parent_bus(qdev, bus);
+ qdev_set_parent_bus(dev, bus);
}
id = qemu_opts_id(opts);
if (id) {
- qdev->id = id;
+ dev->id = id;
}
- if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
- qdev_free(qdev);
+ if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
+ object_unparent(OBJECT(dev));
+ object_unref(OBJECT(dev));
return NULL;
}
- if (qdev->id) {
- object_property_add_child(qdev_get_peripheral(), qdev->id,
- OBJECT(qdev), NULL);
+ if (dev->id) {
+ object_property_add_child(qdev_get_peripheral(), dev->id,
+ OBJECT(dev), NULL);
} else {
static int anon_count;
gchar *name = g_strdup_printf("device[%d]", anon_count++);
object_property_add_child(qdev_get_peripheral_anon(), name,
- OBJECT(qdev), NULL);
+ OBJECT(dev), NULL);
g_free(name);
- }
- if (qdev_init(qdev) < 0) {
+ }
+ object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ if (err != NULL) {
+ qerror_report_err(err);
+ error_free(err);
+ object_unparent(OBJECT(dev));
+ object_unref(OBJECT(dev));
qerror_report(QERR_DEVICE_INIT_FAILED, driver);
return NULL;
}
- qdev->opts = opts;
- return qdev;
+ dev->opts = opts;
+ return dev;
}