From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MWT78-0008S3-Uj for qemu-devel@nongnu.org; Thu, 30 Jul 2009 06:43:59 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MWT75-0008Nz-2Q for qemu-devel@nongnu.org; Thu, 30 Jul 2009 06:43:58 -0400 Received: from [199.232.76.173] (port=54163 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MWT74-0008Nk-Lf for qemu-devel@nongnu.org; Thu, 30 Jul 2009 06:43:54 -0400 Received: from mx2.redhat.com ([66.187.237.31]:38598) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MWT73-0005Xc-L9 for qemu-devel@nongnu.org; Thu, 30 Jul 2009 06:43:54 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n6UAhqIG009552 for ; Thu, 30 Jul 2009 06:43:52 -0400 From: Gerd Hoffmann Date: Thu, 30 Jul 2009 12:43:41 +0200 Message-Id: <1248950621-22249-6-git-send-email-kraxel@redhat.com> In-Reply-To: <1248950621-22249-1-git-send-email-kraxel@redhat.com> References: <1248950621-22249-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 5/5] QemuOpts: switch over -device. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann --- hw/qdev.c | 79 ++++++++++++++++++++++++++++++------------------------------- hw/qdev.h | 5 ++- vl.c | 40 ++++++++++++++++++++----------- 3 files changed, 68 insertions(+), 56 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 479eb72..1c63c8a 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -105,18 +105,34 @@ DeviceState *qdev_create(BusState *bus, const char *name) return dev; } -DeviceState *qdev_device_add(const char *cmdline) +static int set_property(const char *name, const char *value, void *opaque) { + DeviceState *dev = opaque; + + if (strcmp(name, "driver") == 0) + return 0; + if (strcmp(name, "bus") == 0) + return 0; + + if (-1 == qdev_prop_parse(dev, name, value)) { + fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n", + name, value, dev->info->name); + return -1; + } + return 0; +} + +DeviceState *qdev_device_add(QemuOpts *opts) +{ + const char *driver, *path, *id; 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); + qemu_opts_print(opts, NULL); + driver = qemu_opt_get(opts, "driver"); + if (!driver) { + fprintf(stderr, "-device: no driver specified\n"); return NULL; } if (strcmp(driver, "?") == 0) { @@ -125,10 +141,8 @@ DeviceState *qdev_device_add(const char *cmdline) } return NULL; } - if (n) { - params = cmdline + n; - get_param_value(path, sizeof(path), "bus", params); - } + + /* find driver */ info = qdev_find_info(NULL, driver); if (!info) { fprintf(stderr, "Device \"%s\" not found. Try -device '?' for a list.\n", @@ -141,40 +155,26 @@ DeviceState *qdev_device_add(const char *cmdline) return NULL; } - if (strlen(path)) { + /* find bus */ + path = qemu_opt_get(opts, "bus"); + if (path != NULL) { 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 (!bus) + return NULL; - 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); - } - } + /* create device, set properties */ + qdev = qdev_create(bus, driver); + id = qemu_opts_id(opts); + if (id) { + qdev->id = id; + } + if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { + qdev_free(qdev); + return NULL; } - qdev_init(qdev); return qdev; } @@ -191,7 +191,6 @@ void qdev_init(DeviceState *dev) void qdev_free(DeviceState *dev) { LIST_REMOVE(dev, sibling); - qemu_free(dev->id); qemu_free(dev); } diff --git a/hw/qdev.h b/hw/qdev.h index af2ee0f..9f9a940 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -3,6 +3,7 @@ #include "hw.h" #include "sys-queue.h" +#include "qemu-option.h" typedef struct Property Property; @@ -19,7 +20,7 @@ typedef struct BusInfo BusInfo; /* This structure should not be accessed directly. We declare it here so that it can be embedded in individual device state structures. */ struct DeviceState { - char *id; + const char *id; DeviceInfo *info; BusState *parent_bus; int num_gpio_out; @@ -82,7 +83,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); +DeviceState *qdev_device_add(QemuOpts *opts); void qdev_init(DeviceState *dev); void qdev_free(DeviceState *dev); diff --git a/vl.c b/vl.c index e602369..9400956 100644 --- a/vl.c +++ b/vl.c @@ -4802,9 +4802,27 @@ char *qemu_find_file(int type, const char *name) return buf; } +static QemuOptsList device_opt_list = { + .name = "device", + .head = TAILQ_HEAD_INITIALIZER(device_opt_list.head), + .desc = { + /* no elements, accept any */ + { /* end if list */ } + }, +}; + +static int device_init_func(QemuOpts *opts, void *opaque) +{ + DeviceState *dev; + + dev = qdev_device_add(opts); + if (!dev) + return -1; + return 0; +} + struct device_config { enum { - DEV_GENERIC, /* -device */ DEV_USB, /* -usbdevice */ DEV_BT, /* -bt */ } type; @@ -4838,16 +4856,6 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline)) 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; @@ -4862,7 +4870,7 @@ int main(int argc, char **argv, char **envp) int cyls, heads, secs, translation; const char *net_clients[MAX_NET_CLIENTS]; int nb_net_clients; - QemuOpts *hda_opts = NULL; + QemuOpts *hda_opts = NULL, *opts; int optind; const char *r, *optarg; CharDriverState *monitor_hd = NULL; @@ -5472,7 +5480,11 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_USB, optarg); break; case QEMU_OPTION_device: - add_device_config(DEV_GENERIC, optarg); + opts = qemu_opts_parse(&device_opt_list, optarg, "driver"); + if (!opts) { + fprintf(stderr, "parse error: %s\n", optarg); + exit(1); + } break; case QEMU_OPTION_smp: { @@ -6008,7 +6020,7 @@ int main(int argc, char **argv, char **envp) } /* init generic devices */ - if (foreach_device_config(DEV_GENERIC, generic_parse)) + if (qemu_opts_foreach(&device_opt_list, device_init_func, NULL, 1) != 0) exit(1); if (!display_state) -- 1.6.2.5