Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-p…
Browse files Browse the repository at this point in the history
…eter' 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 <[email protected]>"
# gpg:                 aka "Andreas Färber <[email protected]>"

* 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 <[email protected]>
  • Loading branch information
pm215 committed Nov 4, 2014
2 parents 2bb41e5 + 31bed55 commit d5b4dc3
Showing 1 changed file with 51 additions and 37 deletions.
88 changes: 51 additions & 37 deletions qdev-monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down

0 comments on commit d5b4dc3

Please sign in to comment.