diff options
Diffstat (limited to 'qdev-monitor.c')
-rw-r--r-- | qdev-monitor.c | 63 |
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; } |