* [Qemu-devel] [PATCH 1/6] qdev/prop: add pci devfn property
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
@ 2009-07-15 11:59 ` Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 2/6] qdev/pci: use qdev_prop_pci_devfn Gerd Hoffmann
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
So we can parse "$slot.$fn" strings into devfn numbers.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qdev-properties.c | 43 +++++++++++++++++++++++++++++++++++++++++++
hw/qdev.h | 1 +
2 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 06c25af..cd3ee8b 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -145,6 +145,49 @@ PropertyInfo qdev_prop_macaddr = {
.print = print_mac,
};
+/* --- pci address --- */
+
+/*
+ * bus-local address, i.e. "$slot" or "$slot.$fn"
+ */
+static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str)
+{
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ unsigned int slot, fn, n;
+
+ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
+ fn = 0;
+ if (sscanf(str, "%x%n", &slot, &n) != 1) {
+ return -1;
+ }
+ }
+ if (str[n] != '\0')
+ return -1;
+ if (fn > 7)
+ return -1;
+ *ptr = slot << 3 | fn;
+ return 0;
+}
+
+static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (-1 == *ptr) {
+ return snprintf(dest, len, "<unset>");
+ } else {
+ return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
+ }
+}
+
+PropertyInfo qdev_prop_pci_devfn = {
+ .name = "pci-devfn",
+ .type = PROP_TYPE_UINT32,
+ .size = sizeof(uint32_t),
+ .parse = parse_pci_devfn,
+ .print = print_pci_devfn,
+};
+
/* --- public helpers --- */
static Property *qdev_prop_walk(Property *props, const char *name)
diff --git a/hw/qdev.h b/hw/qdev.h
index 11744fa..a9a229e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -148,6 +148,7 @@ extern PropertyInfo qdev_prop_uint32;
extern PropertyInfo qdev_prop_hex32;
extern PropertyInfo qdev_prop_ptr;
extern PropertyInfo qdev_prop_macaddr;
+extern PropertyInfo qdev_prop_pci_devfn;
/* Set properties between creation and init. */
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/6] qdev/pci: use qdev_prop_pci_devfn
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 1/6] qdev/prop: add pci devfn property Gerd Hoffmann
@ 2009-07-15 11:59 ` Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 3/6] qdev: create default bus names Gerd Hoffmann
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Put the new property into use.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pci.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index 5e2996b..03c7840 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -56,8 +56,8 @@ static struct BusInfo pci_bus_info = {
.print_dev = pcibus_dev_print,
.props = (Property[]) {
{
- .name = "devfn",
- .info = &qdev_prop_uint32,
+ .name = "addr",
+ .info = &qdev_prop_pci_devfn,
.offset = offsetof(PCIDevice, devfn),
.defval = (uint32_t[]) { -1 },
},
@@ -779,7 +779,7 @@ PCIDevice *pci_create(const char *name, const char *devaddr)
}
dev = qdev_create(&bus->qbus, name);
- qdev_prop_set_uint32(dev, "devfn", devfn);
+ qdev_prop_set_uint32(dev, "addr", devfn);
return (PCIDevice *)dev;
}
@@ -929,7 +929,7 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
DeviceState *dev;
dev = qdev_create(&bus->qbus, name);
- qdev_prop_set_uint32(dev, "devfn", devfn);
+ qdev_prop_set_uint32(dev, "addr", devfn);
qdev_init(dev);
return (PCIDevice *)dev;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/6] qdev: create default bus names.
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 1/6] qdev/prop: add pci devfn property Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 2/6] qdev/pci: use qdev_prop_pci_devfn Gerd Hoffmann
@ 2009-07-15 11:59 ` Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 4/6] qdev: bus walker + qdev_device_add() Gerd Hoffmann
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Create a default bus name if none is passed to qbus_create().
If the parent device has DeviceState->id set it will be used to create
the bus name,. i.e. -device lsi,id=foo will give you a scsi bus named
"foo.0".
If there is no id BusInfo->name (lowercased) will be used instead, i.e.
-device lsi will give you a scsi bus named "scsi.0".
A scsi adapter with two scsi busses would have "scsi.0" and "scsi.1" or
"$id.0" and "$id.1" busses. The numbers of the child busses are per
device, i.e. when adding two lsi adapters both will have a "*.0" child
bus.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qdev.c | 25 ++++++++++++++++++++++++-
hw/qdev.h | 1 +
2 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index 4c27451..2b772f8 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -234,14 +234,37 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
{
BusState *bus;
+ char *buf;
+ int i,len;
bus = qemu_mallocz(info->size);
bus->info = info;
bus->parent = parent;
- bus->name = qemu_strdup(name);
+
+ if (name) {
+ /* use supplied name */
+ bus->name = qemu_strdup(name);
+ } else if (parent && parent->id) {
+ /* parent device has id -> use it for bus name */
+ len = strlen(parent->id) + 16;
+ buf = qemu_malloc(len);
+ snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
+ bus->name = buf;
+ } else {
+ /* no id -> use lowercase bus type for bus name */
+ len = strlen(info->name) + 16;
+ buf = qemu_malloc(len);
+ len = snprintf(buf, len, "%s.%d", info->name,
+ parent ? parent->num_child_bus : 0);
+ for (i = 0; i < len; i++)
+ buf[i] = tolower(buf[i]);
+ bus->name = buf;
+ }
+
LIST_INIT(&bus->children);
if (parent) {
LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
+ parent->num_child_bus++;
}
return bus;
}
diff --git a/hw/qdev.h b/hw/qdev.h
index a9a229e..67c4dd5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -27,6 +27,7 @@ struct DeviceState {
int num_gpio_in;
qemu_irq *gpio_in;
LIST_HEAD(, BusState) child_bus;
+ int num_child_bus;
NICInfo *nd;
LIST_ENTRY(DeviceState) sibling;
};
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/6] qdev: bus walker + qdev_device_add()
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
` (2 preceding siblings ...)
2009-07-15 11:59 ` [Qemu-devel] [PATCH 3/6] qdev: create default bus names Gerd Hoffmann
@ 2009-07-15 11:59 ` Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 5/6] qdev: add -device command line option Gerd Hoffmann
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patch implements a parser and qdev tree walker for bus paths and
adds qdev_device_add on top of this.
A bus path can be:
(1) full path, i.e. /i440FX-pcihost/pci.0/lsi/scsi.0
(2) bus name, i.e. "scsi.0". Best used together with id= to make
sure this is unique.
(3) relative path starting with a bus name, i.e. "pci.0/lsi/scsi.0"
For the (common) case of a single child bus being attached to a device
it is enougth to specify the device only, i.e. "pci.0/lsi" will be
accepted too.
qdev_device_add() adds devices and accepts bus= parameters to find the
bus the device should be attached to. Without bus= being specified it
takes the first bus it finds where the device can be attached to (i.e.
first pci bus for pci devices, ...).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qdev.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/qdev.h | 1 +
2 files changed, 252 insertions(+), 0 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index 2b772f8..f96395b 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -37,6 +37,10 @@ extern struct BusInfo system_bus_info;
static DeviceInfo *device_info_list;
+static BusState *qbus_find_recursive(BusState *bus, const char *name,
+ const BusInfo *info);
+static BusState *qbus_find(const char *path);
+
/* Register a new device type. */
void qdev_register(DeviceInfo *info)
{
@@ -103,6 +107,80 @@ DeviceState *qdev_create(BusState *bus, const char *name)
return dev;
}
+DeviceState *qdev_device_add(const char *cmdline)
+{
+ 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);
+ return NULL;
+ }
+ if (strcmp(driver, "?") == 0) {
+ for (info = device_info_list; info != NULL; info = info->next) {
+ fprintf(stderr, "name \"%s\", bus %s\n", info->name, info->bus_info->name);
+ }
+ return NULL;
+ }
+ if (n) {
+ params = cmdline + n;
+ get_param_value(path, sizeof(path), "bus", params);
+ }
+ info = qdev_find_info(NULL, driver);
+ if (!info) {
+ fprintf(stderr, "Device \"%s\" not found. Try -device '?' for a list.\n",
+ driver);
+ return NULL;
+ }
+ if (info->no_user) {
+ fprintf(stderr, "device \"%s\" can't be added via command line\n",
+ info->name);
+ return NULL;
+ }
+
+ if (strlen(path)) {
+ 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);
+ }
+ }
+ }
+
+ qdev_init(qdev);
+ return qdev;
+}
+
/* Initialize a device. Device properties should be set before calling
this function. IRQs and MMIO regions should be connected/mapped after
calling this function. */
@@ -231,6 +309,179 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
}
}
+static BusState *qbus_find_recursive(BusState *bus, const char *name,
+ const BusInfo *info)
+{
+ DeviceState *dev;
+ BusState *child, *ret;
+ int match = 1;
+
+ if (name && (strcmp(bus->name, name) != 0)) {
+ match = 0;
+ }
+ if (info && (bus->info != info)) {
+ match = 0;
+ }
+ if (match) {
+ return bus;
+ }
+
+ LIST_FOREACH(dev, &bus->children, sibling) {
+ LIST_FOREACH(child, &dev->child_bus, sibling) {
+ ret = qbus_find_recursive(child, name, info);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+ return NULL;
+}
+
+static void qbus_list_bus(DeviceState *dev, char *dest, int len)
+{
+ BusState *child;
+ const char *sep = " ";
+ int pos = 0;
+
+ pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
+ dev->id ? dev->id : dev->info->name);
+ LIST_FOREACH(child, &dev->child_bus, sibling) {
+ pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
+ sep = ", ";
+ }
+}
+
+static void qbus_list_dev(BusState *bus, char *dest, int len)
+{
+ DeviceState *dev;
+ const char *sep = " ";
+ int pos = 0;
+
+ pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
+ bus->name);
+ LIST_FOREACH(dev, &bus->children, sibling) {
+ pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
+ sep, dev->info->name);
+ if (dev->id)
+ pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
+ sep = ", ";
+ }
+}
+
+static BusState *qbus_find_bus(DeviceState *dev, char *elem)
+{
+ BusState *child;
+
+ LIST_FOREACH(child, &dev->child_bus, sibling) {
+ if (strcmp(child->name, elem) == 0) {
+ return child;
+ }
+ }
+ return NULL;
+}
+
+static DeviceState *qbus_find_dev(BusState *bus, char *elem)
+{
+ DeviceState *dev;
+
+ /*
+ * try to match in order:
+ * (1) instance id, if present
+ * (2) driver name
+ * (3) driver alias, if present
+ */
+ LIST_FOREACH(dev, &bus->children, sibling) {
+ if (dev->id && strcmp(dev->id, elem) == 0) {
+ return dev;
+ }
+ }
+ LIST_FOREACH(dev, &bus->children, sibling) {
+ if (strcmp(dev->info->name, elem) == 0) {
+ return dev;
+ }
+ }
+ LIST_FOREACH(dev, &bus->children, sibling) {
+ if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
+ return dev;
+ }
+ }
+ return NULL;
+}
+
+static BusState *qbus_find(const char *path)
+{
+ DeviceState *dev;
+ BusState *bus;
+ char elem[128], msg[256];
+ int pos, len;
+
+ /* find start element */
+ if (path[0] == '/') {
+ bus = main_system_bus;
+ pos = 0;
+ } else {
+ if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
+ fprintf(stderr, "path parse error (\"%s\")\n", path);
+ return NULL;
+ }
+ bus = qbus_find_recursive(main_system_bus, elem, NULL);
+ if (!bus) {
+ fprintf(stderr, "bus \"%s\" not found\n", elem);
+ return NULL;
+ }
+ pos = len;
+ }
+
+ for (;;) {
+ if (path[pos] == '\0') {
+ /* we are done */
+ return bus;
+ }
+
+ /* find device */
+ if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
+ fprintf(stderr, "path parse error (\"%s\" pos %d)\n", path, pos);
+ return NULL;
+ }
+ pos += len;
+ dev = qbus_find_dev(bus, elem);
+ if (!dev) {
+ qbus_list_dev(bus, msg, sizeof(msg));
+ fprintf(stderr, "device \"%s\" not found\n%s\n", elem, msg);
+ return NULL;
+ }
+ if (path[pos] == '\0') {
+ /* last specified element is a device. If it has exactly
+ * one child bus accept it nevertheless */
+ switch (dev->num_child_bus) {
+ case 0:
+ fprintf(stderr, "device has no child bus (%s)\n", path);
+ return NULL;
+ case 1:
+ return LIST_FIRST(&dev->child_bus);
+ default:
+ qbus_list_bus(dev, msg, sizeof(msg));
+ fprintf(stderr, "device has multiple child busses (%s)\n%s\n",
+ path, msg);
+ return NULL;
+ }
+ }
+
+ /* find bus */
+ if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
+ fprintf(stderr, "path parse error (\"%s\" pos %d)\n", path, pos);
+ return NULL;
+ }
+ pos += len;
+ bus = qbus_find_bus(dev, elem);
+ if (!bus) {
+ qbus_list_bus(dev, msg, sizeof(msg));
+ fprintf(stderr, "child bus \"%s\" not found\n%s\n", elem, msg);
+ return NULL;
+ }
+ }
+}
+
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
{
BusState *bus;
diff --git a/hw/qdev.h b/hw/qdev.h
index 67c4dd5..f2b8b2e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -81,6 +81,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);
void qdev_init(DeviceState *dev);
void qdev_free(DeviceState *dev);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 5/6] qdev: add -device command line option.
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
` (3 preceding siblings ...)
2009-07-15 11:59 ` [Qemu-devel] [PATCH 4/6] qdev: bus walker + qdev_device_add() Gerd Hoffmann
@ 2009-07-15 11:59 ` Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 6/6] switch balloon initialization to -device Gerd Hoffmann
2009-07-22 15:02 ` [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Markus Armbruster
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
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>
---
qemu-options.hx | 2 +
vl.c | 97 ++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 66 insertions(+), 33 deletions(-)
diff --git a/qemu-options.hx b/qemu-options.hx
index 3f69965..a8ef373 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -362,6 +362,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")
diff --git a/vl.c b/vl.c
index 555f569..fe9602a 100644
--- a/vl.c
+++ b/vl.c
@@ -143,6 +143,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"
@@ -173,12 +174,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
@@ -2574,6 +2569,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);
@@ -4757,6 +4757,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;
@@ -4771,8 +4817,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;
@@ -4787,8 +4831,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
@@ -4868,10 +4910,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;
@@ -5118,11 +5157,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:
@@ -5364,12 +5399,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);
@@ -5692,9 +5725,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)
@@ -5885,14 +5917,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
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 6/6] switch balloon initialization to -device.
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
` (4 preceding siblings ...)
2009-07-15 11:59 ` [Qemu-devel] [PATCH 5/6] qdev: add -device command line option Gerd Hoffmann
@ 2009-07-15 11:59 ` Gerd Hoffmann
2009-07-22 15:02 ` [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Markus Armbruster
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
With that patch applied "-balloon virtio,args" becomes a shortcut for
"-device virtio-balloon-pci,args".
Side effects:
- ballon device gains support for id=<tag>.
- ballon device is off by default now.
- initialization order changes, which may in different pci slot
assignment depending on the VM configuration.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/pc.c | 6 -----
sysemu.h | 2 -
vl.c | 65 +++++++++++++++++++++++++++++++++++++------------------------
3 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/hw/pc.c b/hw/pc.c
index 5a8a7af..8be1277 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1407,12 +1407,6 @@ static void pc_init1(ram_addr_t ram_size,
}
}
- /* Add virtio balloon device */
- if (pci_enabled && virtio_balloon) {
- pci_dev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr);
- qdev_init(&pci_dev->qdev);
- }
-
/* Add virtio console devices */
if (pci_enabled) {
for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
diff --git a/sysemu.h b/sysemu.h
index 06dc4c6..9a83bfe 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -116,8 +116,6 @@ extern int win2k_install_hack;
extern int rtc_td_hack;
extern int alt_grab;
extern int usb_enabled;
-extern int virtio_balloon;
-extern const char *virtio_balloon_devaddr;
extern int smp_cpus;
extern int cursor_hide;
extern int graphic_rotate;
diff --git a/vl.c b/vl.c
index fe9602a..27e52cf 100644
--- a/vl.c
+++ b/vl.c
@@ -223,8 +223,6 @@ int smp_cpus = 1;
const char *vnc_display;
int acpi_enabled = 1;
int no_hpet = 0;
-int virtio_balloon = 1;
-const char *virtio_balloon_devaddr;
int fd_bootchk = 1;
int no_reboot = 0;
int no_shutdown = 0;
@@ -4550,29 +4548,6 @@ static void select_vgahw (const char *p)
}
}
-#ifdef TARGET_I386
-static int balloon_parse(const char *arg)
-{
- char buf[128];
- const char *p;
-
- if (!strcmp(arg, "none")) {
- virtio_balloon = 0;
- } else if (!strncmp(arg, "virtio", 6)) {
- virtio_balloon = 1;
- if (arg[6] == ',') {
- p = arg + 7;
- if (get_param_value(buf, sizeof(buf), "addr", p)) {
- virtio_balloon_devaddr = strdup(buf);
- }
- }
- } else {
- return -1;
- }
- return 0;
-}
-#endif
-
#ifdef _WIN32
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
{
@@ -4778,6 +4753,24 @@ static void add_device_config(int type, const char *cmdline)
TAILQ_INSERT_TAIL(&device_configs, conf, next);
}
+#ifdef TARGET_I386
+static void add_device_config_params(int type, const char *driver,
+ const char *params)
+{
+ char *buf;
+ size_t len,pos;
+
+ len = strlen(driver) + 1;
+ if (params)
+ len += strlen(params) + 1;
+ buf = qemu_mallocz(len);
+ pos = snprintf(buf, len, "%s", driver);
+ if (params)
+ pos += snprintf(buf+pos, len-pos, ",%s", params);
+ add_device_config(type, buf);
+}
+#endif
+
static int foreach_device_config(int type, int (*func)(const char *cmdline))
{
struct device_config *conf;
@@ -4803,6 +4796,26 @@ static int generic_parse(const char *cmdline)
return 0;
}
+#ifdef TARGET_I386
+static int add_device_balloon(const char *arg)
+{
+ const char *name = NULL, *params = NULL;
+
+ if (!strcmp(arg, "none"))
+ return 0;
+ if (!strncmp(arg, "virtio", 6)) {
+ name = "virtio-balloon-pci";
+ if (arg[6] == ',')
+ params = arg+7;
+ }
+ if (!name)
+ return -1;
+
+ add_device_config_params(DEV_GENERIC, name, params);
+ return 0;
+}
+#endif
+
int main(int argc, char **argv, char **envp)
{
const char *gdbstub_dev = NULL;
@@ -5423,7 +5436,7 @@ int main(int argc, char **argv, char **envp)
no_hpet = 1;
break;
case QEMU_OPTION_balloon:
- if (balloon_parse(optarg) < 0) {
+ if (add_device_balloon(optarg) < 0) {
fprintf(stderr, "Unknown -balloon argument %s\n", optarg);
exit(1);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 0/6] qdev: -device switch patches.
2009-07-15 11:59 [Qemu-devel] [PATCH 0/6] qdev: -device switch patches Gerd Hoffmann
` (5 preceding siblings ...)
2009-07-15 11:59 ` [Qemu-devel] [PATCH 6/6] switch balloon initialization to -device Gerd Hoffmann
@ 2009-07-22 15:02 ` Markus Armbruster
6 siblings, 0 replies; 8+ messages in thread
From: Markus Armbruster @ 2009-07-22 15:02 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann <kraxel@redhat.com> writes:
> Hi,
>
> All new and improved -device switch patches, for discussion and maybe
> merging.
>
> Overview:
> * addr= is just a pci bus property now, replacing devfn (internally it
> is still devfn, but we convert $slot.$fn strings from/to devfn so this
> isn't user visible any more).
> * busses get sensible names by default now.
> * bus= is there, supporting a wide range of ways to specify the bus the
> device should be attached to.
>
> Check the indiviual patch descriptions for details.
>
> cheers,
> Gerd
Patch series looks good to me, and I think it faithfully implements
what came out of the last round of review.
Except patch 6/6 is kind of an add-on. Since it changes a default, can
change PCI slots, and is not essential, we might want to delay it until
after the release.
^ permalink raw reply [flat|nested] 8+ messages in thread