summaryrefslogtreecommitdiff
path: root/qdev-monitor.c
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-06-26 20:28:10 +0900
committerChanho Park <chanho61.park@samsung.com>2014-07-07 16:25:44 +0900
commita15119db2ff5c2fdfdeb913b297bf8aa3399132e (patch)
tree7d6f779408bb772b11c029ab88000fc01856b599 /qdev-monitor.c
parent340f06c9eaee097e626c251bf7a013350649c091 (diff)
downloadqemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.tar.gz
qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.tar.bz2
qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.zip
Imported Upstream version 2.0.0upstream/2.0.0
Change-Id: I081766c4314e7893f54fec80b920b1638d15021f
Diffstat (limited to 'qdev-monitor.c')
-rw-r--r--qdev-monitor.c180
1 files changed, 107 insertions, 73 deletions
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 410cdcbe9..9268c8759 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -75,14 +75,8 @@ static bool qdev_class_has_alias(DeviceClass *dc)
return (qdev_class_get_alias(dc) != NULL);
}
-static void qdev_print_class_devinfo(DeviceClass *dc)
+static void qdev_print_devinfo(DeviceClass *dc)
{
- DeviceCategory category;
-
- if (!dc) {
- return;
- }
-
error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
if (dc->bus_type) {
error_printf(", bus %s", dc->bus_type);
@@ -90,33 +84,68 @@ static void qdev_print_class_devinfo(DeviceClass *dc)
if (qdev_class_has_alias(dc)) {
error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
}
- error_printf(", categories");
- for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
- if (test_bit(category, dc->categories)) {
- error_printf(" \"%s\"", qdev_category_get_name(category));
- }
- }
if (dc->desc) {
error_printf(", desc \"%s\"", dc->desc);
}
- if (dc->no_user) {
+ if (dc->cannot_instantiate_with_device_add_yet) {
error_printf(", no-user");
}
error_printf("\n");
}
-static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
+static gint devinfo_cmp(gconstpointer a, gconstpointer b)
{
- DeviceClass *dc;
+ return strcasecmp(object_class_get_name((ObjectClass *)a),
+ object_class_get_name((ObjectClass *)b));
+}
- dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
+static void qdev_print_devinfos(bool show_no_user)
+{
+ static const char *cat_name[DEVICE_CATEGORY_MAX + 1] = {
+ [DEVICE_CATEGORY_BRIDGE] = "Controller/Bridge/Hub",
+ [DEVICE_CATEGORY_USB] = "USB",
+ [DEVICE_CATEGORY_STORAGE] = "Storage",
+ [DEVICE_CATEGORY_NETWORK] = "Network",
+ [DEVICE_CATEGORY_INPUT] = "Input",
+ [DEVICE_CATEGORY_DISPLAY] = "Display",
+ [DEVICE_CATEGORY_SOUND] = "Sound",
+ [DEVICE_CATEGORY_MISC] = "Misc",
+ [DEVICE_CATEGORY_MAX] = "Uncategorized",
+ };
+ GSList *list, *elt;
+ int i;
+ bool cat_printed;
+
+ list = g_slist_sort(object_class_get_list(TYPE_DEVICE, false),
+ devinfo_cmp);
+
+ for (i = 0; i <= DEVICE_CATEGORY_MAX; i++) {
+ cat_printed = false;
+ for (elt = list; elt; elt = elt->next) {
+ DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
+ TYPE_DEVICE);
+ if ((i < DEVICE_CATEGORY_MAX
+ ? !test_bit(i, dc->categories)
+ : !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX))
+ || (!show_no_user
+ && dc->cannot_instantiate_with_device_add_yet)) {
+ continue;
+ }
+ if (!cat_printed) {
+ error_printf("%s%s devices:\n", i ? "\n" : "",
+ cat_name[i]);
+ cat_printed = true;
+ }
+ qdev_print_devinfo(dc);
+ }
+ }
- qdev_print_class_devinfo(dc);
+ g_slist_free(list);
}
static int set_property(const char *name, const char *value, void *opaque)
{
- DeviceState *dev = opaque;
+ Object *obj = opaque;
Error *err = NULL;
if (strcmp(name, "driver") == 0)
@@ -124,7 +153,7 @@ static int set_property(const char *name, const char *value, void *opaque)
if (strcmp(name, "bus") == 0)
return 0;
- qdev_prop_parse(dev, name, value, &err);
+ object_property_parse(obj, value, name, &err);
if (err != NULL) {
qerror_report_err(err);
error_free(err);
@@ -151,21 +180,6 @@ static const char *find_typename_by_alias(const char *alias)
return NULL;
}
-static void qdev_print_category_devices(DeviceCategory category)
-{
- DeviceClass *dc;
- GSList *list, *curr;
-
- list = object_class_get_list(TYPE_DEVICE, false);
- for (curr = list; curr; curr = g_slist_next(curr)) {
- dc = (DeviceClass *)object_class_dynamic_cast(curr->data, TYPE_DEVICE);
- if (!dc->no_user && test_bit(category, dc->categories)) {
- qdev_print_class_devinfo(dc);
- }
- }
- g_slist_free(list);
-}
-
int qdev_device_help(QemuOpts *opts)
{
const char *driver;
@@ -174,11 +188,7 @@ int qdev_device_help(QemuOpts *opts)
driver = qemu_opt_get(opts, "driver");
if (driver && is_help_option(driver)) {
- DeviceCategory category;
- for (category = 0; category < DEVICE_CATEGORY_MAX; ++category) {
- qdev_print_category_devices(category);
- }
-
+ qdev_print_devinfos(false);
return 1;
}
@@ -444,11 +454,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) {
@@ -457,22 +468,34 @@ 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) {
- qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
+ if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
+ qerror_report(ERROR_CLASS_GENERIC_ERROR,
+ "'%s' is not a valid device model name", driver);
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);
+ if (dc->cannot_instantiate_with_device_add_yet) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
+ "pluggable device type");
+ return NULL;
+ }
/* find bus */
path = qemu_opt_get(opts, "bus");
@@ -481,16 +504,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;
}
}
@@ -499,37 +522,48 @@ DeviceState *qdev_device_add(QemuOpts *opts)
return NULL;
}
- /* create device, set properties */
- qdev = DEVICE(object_new(driver));
+ /* create device */
+ 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;
- }
- if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
- qdev_free(qdev);
- return NULL;
+ dev->id = id;
}
- 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) {
+ }
+
+ /* set properties */
+ if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
+ object_unparent(OBJECT(dev));
+ object_unref(OBJECT(dev));
+ return NULL;
+ }
+
+ dev->opts = opts;
+ object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ if (err != NULL) {
+ qerror_report_err(err);
+ error_free(err);
+ dev->opts = NULL;
+ object_unparent(OBJECT(dev));
+ object_unref(OBJECT(dev));
qerror_report(QERR_DEVICE_INIT_FAILED, driver);
return NULL;
}
- qdev->opts = opts;
- return qdev;
+ return dev;
}
@@ -548,7 +582,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
value = object_property_get_str(OBJECT(dev), legacy_name, &err);
} else {
- value = object_property_print(OBJECT(dev), props->name, &err);
+ value = object_property_print(OBJECT(dev), props->name, true, &err);
}
g_free(legacy_name);
@@ -617,7 +651,7 @@ void do_info_qtree(Monitor *mon, const QDict *qdict)
void do_info_qdm(Monitor *mon, const QDict *qdict)
{
- object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
+ qdev_print_devinfos(true);
}
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
@@ -627,7 +661,7 @@ int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
DeviceState *dev;
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
- if (error_is_set(&local_err)) {
+ if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
@@ -708,7 +742,7 @@ int qemu_global_option(const char *str)
return -1;
}
- opts = qemu_opts_create_nofail(&qemu_global_opts);
+ opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
qemu_opt_set(opts, "driver", driver);
qemu_opt_set(opts, "property", property);
qemu_opt_set(opts, "value", str+offset+1);