qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/6] qdev: -device switch patches.
@ 2009-07-15 11:59 Gerd Hoffmann
  2009-07-15 11:59 ` [Qemu-devel] [PATCH 1/6] qdev/prop: add pci devfn property Gerd Hoffmann
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-07-15 11:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [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

end of thread, other threads:[~2009-07-22 15:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [Qemu-devel] [PATCH 3/6] qdev: create default bus names Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 4/6] qdev: bus walker + qdev_device_add() Gerd Hoffmann
2009-07-15 11:59 ` [Qemu-devel] [PATCH 5/6] qdev: add -device command line option 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).