aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-11-04 17:33:34 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-11-04 17:33:34 +0000
commitd5b4dc3b50175f0c34f3cf4b053e123fb37f5aed (patch)
tree96c9c69b8e7080f0417c95ff78a8fb209a4f863a
parent2bb41e5d307a819789f3bab719419ac7b77e6f80 (diff)
parent31bed5509dfcbdfc293154ce81086a4dbd7a80b6 (diff)
Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-peter' into staging
QOM infrastructure fixes and device conversions * Fixes for -device foo,help # gpg: Signature made Tue 04 Nov 2014 17:27:41 GMT using RSA key ID 3E7E013F # gpg: Good signature from "Andreas Färber <afaerber@suse.de>" # gpg: aka "Andreas Färber <afaerber@suse.com>" * remotes/afaerber/tags/qom-devices-for-peter: qdev: Use qdev_get_device_class() for -device <type>,help qdev: Move error printing to the end of qdev_device_help() qdev: Create qdev_get_device_class() function Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--qdev-monitor.c88
1 files changed, 51 insertions, 37 deletions
diff --git a/qdev-monitor.c b/qdev-monitor.c
index fac7d179fe..ebfa701a9d 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -180,6 +180,44 @@ static const char *find_typename_by_alias(const char *alias)
return NULL;
}
+static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
+{
+ ObjectClass *oc;
+ DeviceClass *dc;
+
+ oc = object_class_by_name(*driver);
+ if (!oc) {
+ const char *typename = find_typename_by_alias(*driver);
+
+ if (typename) {
+ *driver = typename;
+ oc = object_class_by_name(*driver);
+ }
+ }
+
+ if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
+ error_setg(errp, "'%s' is not a valid device model name", *driver);
+ return NULL;
+ }
+
+ if (object_class_is_abstract(oc)) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
+ "non-abstract device type");
+ return NULL;
+ }
+
+ dc = DEVICE_CLASS(oc);
+ if (dc->cannot_instantiate_with_device_add_yet ||
+ (qdev_hotplug && !dc->hotpluggable)) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
+ "pluggable device type");
+ return NULL;
+ }
+
+ return dc;
+}
+
+
int qdev_device_help(QemuOpts *opts)
{
Error *local_err = NULL;
@@ -197,19 +235,14 @@ int qdev_device_help(QemuOpts *opts)
return 0;
}
- if (!object_class_by_name(driver)) {
- const char *typename = find_typename_by_alias(driver);
-
- if (typename) {
- driver = typename;
- }
+ qdev_get_device_class(&driver, &local_err);
+ if (local_err) {
+ goto error;
}
prop_list = qmp_device_list_properties(driver, &local_err);
if (local_err) {
- error_printf("%s\n", error_get_pretty(local_err));
- error_free(local_err);
- return 1;
+ goto error;
}
for (prop = prop_list; prop; prop = prop->next) {
@@ -225,6 +258,11 @@ int qdev_device_help(QemuOpts *opts)
qapi_free_DevicePropertyInfoList(prop_list);
return 1;
+
+error:
+ error_printf("%s\n", error_get_pretty(local_err));
+ error_free(local_err);
+ return 1;
}
static Object *qdev_get_peripheral(void)
@@ -455,7 +493,6 @@ static BusState *qbus_find(const char *path)
DeviceState *qdev_device_add(QemuOpts *opts)
{
- ObjectClass *oc;
DeviceClass *dc;
const char *driver, *path, *id;
DeviceState *dev;
@@ -469,33 +506,10 @@ DeviceState *qdev_device_add(QemuOpts *opts)
}
/* find driver */
- oc = object_class_by_name(driver);
- if (!oc) {
- const char *typename = find_typename_by_alias(driver);
-
- if (typename) {
- driver = typename;
- oc = object_class_by_name(driver);
- }
- }
-
- 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;
- }
-
- 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 ||
- (qdev_hotplug && !dc->hotpluggable)) {
- qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
- "pluggable device type");
+ dc = qdev_get_device_class(&driver, &err);
+ if (err) {
+ qerror_report_err(err);
+ error_free(err);
return NULL;
}