Commit f31d07d1 authored by Gerd Hoffmann's avatar Gerd Hoffmann Committed by Anthony Liguori
Browse files

QemuOpts: switch over -device.



Make -device switch use the QemuOpts framework.
Everything should continue to work like it did before.

New: "-set device.$id.$property=$value" works.

Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
Message-Id: 
parent d058fe03
Loading
Loading
Loading
Loading
+38 −40
Original line number Diff line number Diff line
@@ -120,18 +120,33 @@ static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
    return pos;
}

DeviceState *qdev_device_add(const char *cmdline)
static int set_property(const char *name, const char *value, void *opaque)
{
    DeviceState *dev = opaque;

    if (strcmp(name, "driver") == 0)
        return 0;
    if (strcmp(name, "bus") == 0)
        return 0;

    if (-1 == qdev_prop_parse(dev, name, value)) {
        fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
                name, value, dev->info->name);
        return -1;
    }
    return 0;
}

DeviceState *qdev_device_add(QemuOpts *opts)
{
    const char *driver, *path, *id;
    DeviceInfo *info;
    DeviceState *qdev;
    BusState *bus;
    char driver[32], path[128] = "";
    char tag[32], value[256];
    const char *params = NULL;
    int n = 0;

    if (1 != sscanf(cmdline, "%32[^,],%n", driver, &n)) {
        fprintf(stderr, "device parse error: \"%s\"\n", cmdline);
    driver = qemu_opt_get(opts, "driver");
    if (!driver) {
        fprintf(stderr, "-device: no driver specified\n");
        return NULL;
    }
    if (strcmp(driver, "?") == 0) {
@@ -142,10 +157,8 @@ DeviceState *qdev_device_add(const char *cmdline)
        }
        return NULL;
    }
    if (n) {
        params = cmdline + n;
        get_param_value(path, sizeof(path), "bus",  params);
    }

    /* find driver */
    info = qdev_find_info(NULL, driver);
    if (!info) {
        fprintf(stderr, "Device \"%s\" not found.  Try -device '?' for a list.\n",
@@ -158,40 +171,26 @@ DeviceState *qdev_device_add(const char *cmdline)
        return NULL;
    }

    if (strlen(path)) {
    /* find bus */
    path = qemu_opt_get(opts, "bus");
    if (path != NULL) {
        bus = qbus_find(path);
        if (!bus)
            return NULL;
        qdev = qdev_create(bus, driver);
    } else {
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
    }
    if (!bus)
        return NULL;
        qdev = qdev_create(bus, driver);
    }

    if (params) {
        while (params[0]) {
            if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) {
                fprintf(stderr, "parse error at \"%s\"\n", params);
                break;
            }
            params += n;
            if (params[0] == ',')
                params++;
            if (strcmp(tag, "bus") == 0)
                continue;
            if (strcmp(tag, "id") == 0) {
                qdev->id = qemu_strdup(value);
                continue;
            }
            if (-1 == qdev_prop_parse(qdev, tag, value)) {
                fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
                        tag, value, driver);
            }
    /* create device, set properties */
    qdev = qdev_create(bus, driver);
    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;
    }

    qdev_init(qdev);
    return qdev;
}
@@ -208,7 +207,6 @@ void qdev_init(DeviceState *dev)
void qdev_free(DeviceState *dev)
{
    LIST_REMOVE(dev, sibling);
    qemu_free(dev->id);
    qemu_free(dev);
}

+3 −2
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#include "hw.h"
#include "sys-queue.h"
#include "qemu-option.h"

typedef struct Property Property;

@@ -19,7 +20,7 @@ typedef struct BusInfo BusInfo;
/* This structure should not be accessed directly.  We declare it here
   so that it can be embedded in individual device state structures.  */
struct DeviceState {
    char *id;
    const char *id;
    DeviceInfo *info;
    BusState *parent_bus;
    int num_gpio_out;
@@ -82,7 +83,7 @@ struct CompatProperty {
/*** Board API.  This should go away once we have a machine config file.  ***/

DeviceState *qdev_create(BusState *bus, const char *name);
DeviceState *qdev_device_add(const char *cmdline);
DeviceState *qdev_device_add(QemuOpts *opts);
void qdev_init(DeviceState *dev);
void qdev_free(DeviceState *dev);

+14 −0
Original line number Diff line number Diff line
@@ -71,8 +71,22 @@ QemuOptsList qemu_drive_opts = {
    },
};

QemuOptsList qemu_device_opts = {
    .name = "device",
    .head = TAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
    .desc = {
        /*
         * no elements => accept any
         * sanity checking will happen later
         * when setting device properties
         */
        { /* end if list */ }
    },
};

static QemuOptsList *lists[] = {
    &qemu_drive_opts,
    &qemu_device_opts,
    NULL,
};

+1 −0
Original line number Diff line number Diff line
extern QemuOptsList qemu_drive_opts;
extern QemuOptsList qemu_device_opts;

int qemu_set_option(const char *str);
+17 −14
Original line number Diff line number Diff line
@@ -4716,9 +4716,18 @@ char *qemu_find_file(int type, const char *name)
    return buf;
}

static int device_init_func(QemuOpts *opts, void *opaque)
{
    DeviceState *dev;

    dev = qdev_device_add(opts);
    if (!dev)
        return -1;
    return 0;
}

struct device_config {
    enum {
        DEV_GENERIC,   /* -device      */
        DEV_USB,       /* -usbdevice   */
        DEV_BT,        /* -bt          */
    } type;
@@ -4752,16 +4761,6 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline))
    return 0;
}

static int generic_parse(const char *cmdline)
{
    DeviceState *dev;

    dev = qdev_device_add(cmdline);
    if (!dev)
        return -1;
    return 0;
}

int main(int argc, char **argv, char **envp)
{
    const char *gdbstub_dev = NULL;
@@ -4776,7 +4775,7 @@ int main(int argc, char **argv, char **envp)
    int cyls, heads, secs, translation;
    const char *net_clients[MAX_NET_CLIENTS];
    int nb_net_clients;
    QemuOpts *hda_opts = NULL;
    QemuOpts *hda_opts = NULL, *opts;
    int optind;
    const char *r, *optarg;
    CharDriverState *monitor_hd = NULL;
@@ -5386,7 +5385,11 @@ int main(int argc, char **argv, char **envp)
                add_device_config(DEV_USB, optarg);
                break;
            case QEMU_OPTION_device:
                add_device_config(DEV_GENERIC, optarg);
                opts = qemu_opts_parse(&qemu_device_opts, optarg, "driver");
                if (!opts) {
                    fprintf(stderr, "parse error: %s\n", optarg);
                    exit(1);
                }
                break;
            case QEMU_OPTION_smp:
            {
@@ -5922,7 +5925,7 @@ int main(int argc, char **argv, char **envp)
    }

    /* init generic devices */
    if (foreach_device_config(DEV_GENERIC, generic_parse))
    if (qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) != 0)
        exit(1);

    if (!display_state)