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

qdev: add -device command line option.



The -device switch is the users frontend to the qdev_device_add function
added by the previous patch.

Also adds a linked list where command line options can be saved.
Use it for the new -device and for the -usbdevice and -bt switches.

Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 8ffb1bcf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -381,6 +381,8 @@ Network adapter that supports CDC ethernet and RNDIS protocols.
@end table
ETEXI

DEF("device", HAS_ARG, QEMU_OPTION_device,
    "-device driver[,options]  add device\n")
DEF("name", HAS_ARG, QEMU_OPTION_name,
    "-name string1[,process=string2]    set the name of the guest\n"
    "            string1 sets the window title and string2 the process name (on Linux)\n")
+64 −33
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ int main(int argc, char **argv)
#include "hw/watchdog.h"
#include "hw/smbios.h"
#include "hw/xen.h"
#include "hw/qdev.h"
#include "bt-host.h"
#include "net.h"
#include "monitor.h"
@@ -175,12 +176,6 @@ int main(int argc, char **argv)

#define DEFAULT_RAM_SIZE 128

/* Max number of USB devices that can be specified on the commandline.  */
#define MAX_USB_CMDLINE 8

/* Max number of bluetooth switches on the commandline.  */
#define MAX_BT_CMDLINE 10

static const char *data_dir;
const char *bios_name = NULL;
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
@@ -2633,6 +2628,11 @@ static int usb_device_del(const char *devname)
    return usb_device_del_addr(bus_num, addr);
}

static int usb_parse(const char *cmdline)
{
    return usb_device_add(cmdline, 0);
}

void do_usb_add(Monitor *mon, const char *devname)
{
    usb_device_add(devname, 1);
@@ -4827,6 +4827,52 @@ char *qemu_find_file(int type, const char *name)
    return buf;
}

struct device_config {
    enum {
        DEV_GENERIC,   /* -device      */
        DEV_USB,       /* -usbdevice   */
        DEV_BT,        /* -bt          */
    } type;
    const char *cmdline;
    TAILQ_ENTRY(device_config) next;
};
TAILQ_HEAD(, device_config) device_configs = TAILQ_HEAD_INITIALIZER(device_configs);

static void add_device_config(int type, const char *cmdline)
{
    struct device_config *conf;

    conf = qemu_mallocz(sizeof(*conf));
    conf->type = type;
    conf->cmdline = cmdline;
    TAILQ_INSERT_TAIL(&device_configs, conf, next);
}

static int foreach_device_config(int type, int (*func)(const char *cmdline))
{
    struct device_config *conf;
    int rc;

    TAILQ_FOREACH(conf, &device_configs, next) {
        if (conf->type != type)
            continue;
        rc = func(conf->cmdline);
        if (0 != rc)
            return rc;
    }
    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;
@@ -4841,8 +4887,6 @@ int main(int argc, char **argv, char **envp)
    int cyls, heads, secs, translation;
    const char *net_clients[MAX_NET_CLIENTS];
    int nb_net_clients;
    const char *bt_opts[MAX_BT_CMDLINE];
    int nb_bt_opts;
    int hda_index;
    int optind;
    const char *r, *optarg;
@@ -4857,8 +4901,6 @@ int main(int argc, char **argv, char **envp)
    const char *loadvm = NULL;
    QEMUMachine *machine;
    const char *cpu_model;
    const char *usb_devices[MAX_USB_CMDLINE];
    int usb_devices_index;
#ifndef _WIN32
    int fds[2];
#endif
@@ -4938,10 +4980,7 @@ int main(int argc, char **argv, char **envp)
        node_cpumask[i] = 0;
    }

    usb_devices_index = 0;

    nb_net_clients = 0;
    nb_bt_opts = 0;
    nb_drives = 0;
    nb_drives_opt = 0;
    nb_numa_nodes = 0;
@@ -5209,11 +5248,7 @@ int main(int argc, char **argv, char **envp)
                break;
#endif
            case QEMU_OPTION_bt:
                if (nb_bt_opts >= MAX_BT_CMDLINE) {
                    fprintf(stderr, "qemu: too many bluetooth options\n");
                    exit(1);
                }
                bt_opts[nb_bt_opts++] = optarg;
                add_device_config(DEV_BT, optarg);
                break;
#ifdef HAS_AUDIO
            case QEMU_OPTION_audio_help:
@@ -5455,12 +5490,10 @@ int main(int argc, char **argv, char **envp)
                break;
            case QEMU_OPTION_usbdevice:
                usb_enabled = 1;
                if (usb_devices_index >= MAX_USB_CMDLINE) {
                    fprintf(stderr, "Too many USB devices\n");
                    exit(1);
                }
                usb_devices[usb_devices_index] = optarg;
                usb_devices_index++;
                add_device_config(DEV_USB, optarg);
                break;
            case QEMU_OPTION_device:
                add_device_config(DEV_GENERIC, optarg);
                break;
            case QEMU_OPTION_smp:
                smp_cpus = atoi(optarg);
@@ -5779,8 +5812,7 @@ int main(int argc, char **argv, char **envp)
    net_client_check();

    /* init the bluetooth world */
    for (i = 0; i < nb_bt_opts; i++)
        if (bt_parse(bt_opts[i]))
    if (foreach_device_config(DEV_BT, bt_parse))
        exit(1);

    /* init the memory */
@@ -5972,14 +6004,13 @@ int main(int argc, char **argv, char **envp)

    /* init USB devices */
    if (usb_enabled) {
        for(i = 0; i < usb_devices_index; i++) {
            if (usb_device_add(usb_devices[i], 0) < 0) {
                fprintf(stderr, "Warning: could not add USB device %s\n",
                        usb_devices[i]);
            }
        }
        foreach_device_config(DEV_USB, usb_parse);
    }

    /* init generic devices */
    if (foreach_device_config(DEV_GENERIC, generic_parse))
        exit(1);

    if (!display_state)
        dumb_display_init();
    /* just use the first displaystate for the moment */