Commit 43c95d78 authored by Eduardo Habkost's avatar Eduardo Habkost Committed by Andreas Färber
Browse files

qdev: Create qdev_get_device_class() function



Extract the DeviceClass lookup from qdev_device_add() to a separate
function.

Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
parent 1bc8dae3
Loading
Loading
Loading
Loading
+42 −28
Original line number Diff line number Diff line
@@ -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;
@@ -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;
    }