Commit bd3c948db739a6c9c5e42ec838ef1220beea8e4e
Committed by
Anthony Liguori
1 parent
8ffb1bcf
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: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
2 changed files
with
66 additions
and
33 deletions
qemu-options.hx
| ... | ... | @@ -381,6 +381,8 @@ Network adapter that supports CDC ethernet and RNDIS protocols. |
| 381 | 381 | @end table |
| 382 | 382 | ETEXI |
| 383 | 383 | |
| 384 | +DEF("device", HAS_ARG, QEMU_OPTION_device, | |
| 385 | + "-device driver[,options] add device\n") | |
| 384 | 386 | DEF("name", HAS_ARG, QEMU_OPTION_name, |
| 385 | 387 | "-name string1[,process=string2] set the name of the guest\n" |
| 386 | 388 | " string1 sets the window title and string2 the process name (on Linux)\n") | ... | ... |
vl.c
| ... | ... | @@ -145,6 +145,7 @@ int main(int argc, char **argv) |
| 145 | 145 | #include "hw/watchdog.h" |
| 146 | 146 | #include "hw/smbios.h" |
| 147 | 147 | #include "hw/xen.h" |
| 148 | +#include "hw/qdev.h" | |
| 148 | 149 | #include "bt-host.h" |
| 149 | 150 | #include "net.h" |
| 150 | 151 | #include "monitor.h" |
| ... | ... | @@ -175,12 +176,6 @@ int main(int argc, char **argv) |
| 175 | 176 | |
| 176 | 177 | #define DEFAULT_RAM_SIZE 128 |
| 177 | 178 | |
| 178 | -/* Max number of USB devices that can be specified on the commandline. */ | |
| 179 | -#define MAX_USB_CMDLINE 8 | |
| 180 | - | |
| 181 | -/* Max number of bluetooth switches on the commandline. */ | |
| 182 | -#define MAX_BT_CMDLINE 10 | |
| 183 | - | |
| 184 | 179 | static const char *data_dir; |
| 185 | 180 | const char *bios_name = NULL; |
| 186 | 181 | /* 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) |
| 2633 | 2628 | return usb_device_del_addr(bus_num, addr); |
| 2634 | 2629 | } |
| 2635 | 2630 | |
| 2631 | +static int usb_parse(const char *cmdline) | |
| 2632 | +{ | |
| 2633 | + return usb_device_add(cmdline, 0); | |
| 2634 | +} | |
| 2635 | + | |
| 2636 | 2636 | void do_usb_add(Monitor *mon, const char *devname) |
| 2637 | 2637 | { |
| 2638 | 2638 | usb_device_add(devname, 1); |
| ... | ... | @@ -4827,6 +4827,52 @@ char *qemu_find_file(int type, const char *name) |
| 4827 | 4827 | return buf; |
| 4828 | 4828 | } |
| 4829 | 4829 | |
| 4830 | +struct device_config { | |
| 4831 | + enum { | |
| 4832 | + DEV_GENERIC, /* -device */ | |
| 4833 | + DEV_USB, /* -usbdevice */ | |
| 4834 | + DEV_BT, /* -bt */ | |
| 4835 | + } type; | |
| 4836 | + const char *cmdline; | |
| 4837 | + TAILQ_ENTRY(device_config) next; | |
| 4838 | +}; | |
| 4839 | +TAILQ_HEAD(, device_config) device_configs = TAILQ_HEAD_INITIALIZER(device_configs); | |
| 4840 | + | |
| 4841 | +static void add_device_config(int type, const char *cmdline) | |
| 4842 | +{ | |
| 4843 | + struct device_config *conf; | |
| 4844 | + | |
| 4845 | + conf = qemu_mallocz(sizeof(*conf)); | |
| 4846 | + conf->type = type; | |
| 4847 | + conf->cmdline = cmdline; | |
| 4848 | + TAILQ_INSERT_TAIL(&device_configs, conf, next); | |
| 4849 | +} | |
| 4850 | + | |
| 4851 | +static int foreach_device_config(int type, int (*func)(const char *cmdline)) | |
| 4852 | +{ | |
| 4853 | + struct device_config *conf; | |
| 4854 | + int rc; | |
| 4855 | + | |
| 4856 | + TAILQ_FOREACH(conf, &device_configs, next) { | |
| 4857 | + if (conf->type != type) | |
| 4858 | + continue; | |
| 4859 | + rc = func(conf->cmdline); | |
| 4860 | + if (0 != rc) | |
| 4861 | + return rc; | |
| 4862 | + } | |
| 4863 | + return 0; | |
| 4864 | +} | |
| 4865 | + | |
| 4866 | +static int generic_parse(const char *cmdline) | |
| 4867 | +{ | |
| 4868 | + DeviceState *dev; | |
| 4869 | + | |
| 4870 | + dev = qdev_device_add(cmdline); | |
| 4871 | + if (!dev) | |
| 4872 | + return -1; | |
| 4873 | + return 0; | |
| 4874 | +} | |
| 4875 | + | |
| 4830 | 4876 | int main(int argc, char **argv, char **envp) |
| 4831 | 4877 | { |
| 4832 | 4878 | const char *gdbstub_dev = NULL; |
| ... | ... | @@ -4841,8 +4887,6 @@ int main(int argc, char **argv, char **envp) |
| 4841 | 4887 | int cyls, heads, secs, translation; |
| 4842 | 4888 | const char *net_clients[MAX_NET_CLIENTS]; |
| 4843 | 4889 | int nb_net_clients; |
| 4844 | - const char *bt_opts[MAX_BT_CMDLINE]; | |
| 4845 | - int nb_bt_opts; | |
| 4846 | 4890 | int hda_index; |
| 4847 | 4891 | int optind; |
| 4848 | 4892 | const char *r, *optarg; |
| ... | ... | @@ -4857,8 +4901,6 @@ int main(int argc, char **argv, char **envp) |
| 4857 | 4901 | const char *loadvm = NULL; |
| 4858 | 4902 | QEMUMachine *machine; |
| 4859 | 4903 | const char *cpu_model; |
| 4860 | - const char *usb_devices[MAX_USB_CMDLINE]; | |
| 4861 | - int usb_devices_index; | |
| 4862 | 4904 | #ifndef _WIN32 |
| 4863 | 4905 | int fds[2]; |
| 4864 | 4906 | #endif |
| ... | ... | @@ -4938,10 +4980,7 @@ int main(int argc, char **argv, char **envp) |
| 4938 | 4980 | node_cpumask[i] = 0; |
| 4939 | 4981 | } |
| 4940 | 4982 | |
| 4941 | - usb_devices_index = 0; | |
| 4942 | - | |
| 4943 | 4983 | nb_net_clients = 0; |
| 4944 | - nb_bt_opts = 0; | |
| 4945 | 4984 | nb_drives = 0; |
| 4946 | 4985 | nb_drives_opt = 0; |
| 4947 | 4986 | nb_numa_nodes = 0; |
| ... | ... | @@ -5209,11 +5248,7 @@ int main(int argc, char **argv, char **envp) |
| 5209 | 5248 | break; |
| 5210 | 5249 | #endif |
| 5211 | 5250 | case QEMU_OPTION_bt: |
| 5212 | - if (nb_bt_opts >= MAX_BT_CMDLINE) { | |
| 5213 | - fprintf(stderr, "qemu: too many bluetooth options\n"); | |
| 5214 | - exit(1); | |
| 5215 | - } | |
| 5216 | - bt_opts[nb_bt_opts++] = optarg; | |
| 5251 | + add_device_config(DEV_BT, optarg); | |
| 5217 | 5252 | break; |
| 5218 | 5253 | #ifdef HAS_AUDIO |
| 5219 | 5254 | case QEMU_OPTION_audio_help: |
| ... | ... | @@ -5455,12 +5490,10 @@ int main(int argc, char **argv, char **envp) |
| 5455 | 5490 | break; |
| 5456 | 5491 | case QEMU_OPTION_usbdevice: |
| 5457 | 5492 | usb_enabled = 1; |
| 5458 | - if (usb_devices_index >= MAX_USB_CMDLINE) { | |
| 5459 | - fprintf(stderr, "Too many USB devices\n"); | |
| 5460 | - exit(1); | |
| 5461 | - } | |
| 5462 | - usb_devices[usb_devices_index] = optarg; | |
| 5463 | - usb_devices_index++; | |
| 5493 | + add_device_config(DEV_USB, optarg); | |
| 5494 | + break; | |
| 5495 | + case QEMU_OPTION_device: | |
| 5496 | + add_device_config(DEV_GENERIC, optarg); | |
| 5464 | 5497 | break; |
| 5465 | 5498 | case QEMU_OPTION_smp: |
| 5466 | 5499 | smp_cpus = atoi(optarg); |
| ... | ... | @@ -5779,9 +5812,8 @@ int main(int argc, char **argv, char **envp) |
| 5779 | 5812 | net_client_check(); |
| 5780 | 5813 | |
| 5781 | 5814 | /* init the bluetooth world */ |
| 5782 | - for (i = 0; i < nb_bt_opts; i++) | |
| 5783 | - if (bt_parse(bt_opts[i])) | |
| 5784 | - exit(1); | |
| 5815 | + if (foreach_device_config(DEV_BT, bt_parse)) | |
| 5816 | + exit(1); | |
| 5785 | 5817 | |
| 5786 | 5818 | /* init the memory */ |
| 5787 | 5819 | if (ram_size == 0) |
| ... | ... | @@ -5972,14 +6004,13 @@ int main(int argc, char **argv, char **envp) |
| 5972 | 6004 | |
| 5973 | 6005 | /* init USB devices */ |
| 5974 | 6006 | if (usb_enabled) { |
| 5975 | - for(i = 0; i < usb_devices_index; i++) { | |
| 5976 | - if (usb_device_add(usb_devices[i], 0) < 0) { | |
| 5977 | - fprintf(stderr, "Warning: could not add USB device %s\n", | |
| 5978 | - usb_devices[i]); | |
| 5979 | - } | |
| 5980 | - } | |
| 6007 | + foreach_device_config(DEV_USB, usb_parse); | |
| 5981 | 6008 | } |
| 5982 | 6009 | |
| 6010 | + /* init generic devices */ | |
| 6011 | + if (foreach_device_config(DEV_GENERIC, generic_parse)) | |
| 6012 | + exit(1); | |
| 6013 | + | |
| 5983 | 6014 | if (!display_state) |
| 5984 | 6015 | dumb_display_init(); |
| 5985 | 6016 | /* just use the first displaystate for the moment */ | ... | ... |