>From 4f9a4ea2b909b38e326d87434a6b32454c9c1166 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 30 Jun 2009 17:19:19 +0200 Subject: [PATCH] qdev: add -device command line option. Add a linked list where command line options can be saved. Use it for the new -device and for the -usbdevice and -bt switches. --- hw/qdev.c | 4 ++- qemu-options.hx | 2 + vl.c | 97 ++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 6bc2530..82bcd04 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -124,8 +124,10 @@ DeviceState *qdev_device_add(const char *cmdline) if (params) { while (params[0]) { - if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) + if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) { + fprintf(stderr, "parse error at \"%s\"\n", params); break; + } params += n; if (strcmp(tag, "addr") == 0) continue; diff --git a/qemu-options.hx b/qemu-options.hx index a94f9d3..67d7bd0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -364,6 +364,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 string set the name of the guest\n") STEXI diff --git a/vl.c b/vl.c index 7b7489c..1b1852a 100644 --- a/vl.c +++ b/vl.c @@ -142,6 +142,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" @@ -181,12 +182,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 - /* XXX: use a two level table to limit memory usage */ #define MAX_IOPORTS 65536 @@ -2787,6 +2782,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); @@ -4970,6 +4970,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; @@ -4984,8 +5030,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; @@ -5000,8 +5044,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 @@ -5081,10 +5123,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; @@ -5331,11 +5370,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: @@ -5577,12 +5612,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); @@ -5893,9 +5926,8 @@ 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])) - exit(1); + if (foreach_device_config(DEV_BT, bt_parse)) + exit(1); /* init the memory */ if (ram_size == 0) @@ -6083,14 +6115,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 */ -- 1.6.2.5