From patchwork Tue Mar 5 17:51:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Shah X-Patchwork-Id: 225129 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CE6A72C035E for ; Wed, 6 Mar 2013 04:58:17 +1100 (EST) Received: from localhost ([::1]:58168 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCw80-0003yQ-4S for incoming@patchwork.ozlabs.org; Tue, 05 Mar 2013 12:58:16 -0500 Received: from eggs.gnu.org ([208.118.235.92]:44888) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCw5L-0007wO-Sz for qemu-devel@nongnu.org; Tue, 05 Mar 2013 12:55:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UCw5B-0000EO-MA for qemu-devel@nongnu.org; Tue, 05 Mar 2013 12:55:31 -0500 Received: from mx1.redhat.com ([209.132.183.28]:9785) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCw5B-0000EJ-F3 for qemu-devel@nongnu.org; Tue, 05 Mar 2013 12:55:21 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r25HtJgu022690 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 5 Mar 2013 12:55:20 -0500 Received: from localhost (ovpn-113-84.phx2.redhat.com [10.3.113.84]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r25Ht78P013636; Tue, 5 Mar 2013 12:55:18 -0500 From: Amit Shah To: qemu list Date: Tue, 5 Mar 2013 23:21:28 +0530 Message-Id: <0ff4f5f2b8b7afdb85a0c241403ad73f472f0b81.1362505276.git.amit.shah@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Amit Shah , Anthony Liguori , Anthony Liguori Subject: [Qemu-devel] [PATCH 13/20] qemu-char: make char drivers dynamically registerable X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Anthony Liguori Signed-off-by: Anthony Liguori Signed-off-by: Amit Shah --- include/char/char.h | 2 + qemu-char.c | 110 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/include/char/char.h b/include/char/char.h index e8b781c..2e24270 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -244,6 +244,8 @@ CharDriverState *qemu_chr_find(const char *name); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); +void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *)); + /* add an eventfd to the qemu devices that are polled */ CharDriverState *qemu_chr_open_eventfd(int eventfd); diff --git a/qemu-char.c b/qemu-char.c index 2c7c929..9bcdf73 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3177,53 +3177,31 @@ static CharDriverState *qemu_chr_open_pp(QemuOpts *opts) #endif -static const struct { +typedef struct CharDriver { const char *name; CharDriverState *(*open)(QemuOpts *opts); -} backend_table[] = { - { .name = "null", .open = qemu_chr_open_null }, - { .name = "socket", .open = qemu_chr_open_socket }, - { .name = "udp", .open = qemu_chr_open_udp }, - { .name = "msmouse", .open = qemu_chr_open_msmouse }, - { .name = "vc", .open = vc_init }, - { .name = "memory", .open = qemu_chr_open_ringbuf }, -#ifdef _WIN32 - { .name = "file", .open = qemu_chr_open_win_file_out }, - { .name = "pipe", .open = qemu_chr_open_win_pipe }, - { .name = "console", .open = qemu_chr_open_win_con }, - { .name = "serial", .open = qemu_chr_open_win }, - { .name = "stdio", .open = qemu_chr_open_win_stdio }, -#else - { .name = "file", .open = qemu_chr_open_file_out }, - { .name = "pipe", .open = qemu_chr_open_pipe }, - { .name = "stdio", .open = qemu_chr_open_stdio }, -#endif -#ifdef CONFIG_BRLAPI - { .name = "braille", .open = chr_baum_init }, -#endif -#ifdef HAVE_CHARDEV_TTY - { .name = "tty", .open = qemu_chr_open_tty }, - { .name = "serial", .open = qemu_chr_open_tty }, - { .name = "pty", .open = qemu_chr_open_pty }, -#endif -#ifdef HAVE_CHARDEV_PARPORT - { .name = "parallel", .open = qemu_chr_open_pp }, - { .name = "parport", .open = qemu_chr_open_pp }, -#endif -#ifdef CONFIG_SPICE - { .name = "spicevmc", .open = qemu_chr_open_spice }, -#if SPICE_SERVER_VERSION >= 0x000c02 - { .name = "spiceport", .open = qemu_chr_open_spice_port }, -#endif -#endif -}; +} CharDriver; + +static GSList *backends; + +void register_char_driver(const char *name, CharDriverState *(*open)(QemuOpts *)) +{ + CharDriver *s; + + s = g_malloc0(sizeof(*s)); + s->name = g_strdup(name); + s->open = open; + + backends = g_slist_append(backends, s); +} CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, void (*init)(struct CharDriverState *s), Error **errp) { + CharDriver *cd; CharDriverState *chr; - int i; + GSList *i; if (qemu_opts_id(opts) == NULL) { error_setg(errp, "chardev: no id specified"); @@ -3235,17 +3213,20 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, qemu_opts_id(opts)); goto err; } - for (i = 0; i < ARRAY_SIZE(backend_table); i++) { - if (strcmp(backend_table[i].name, qemu_opt_get(opts, "backend")) == 0) + for (i = backends; i; i = i->next) { + cd = i->data; + + if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) { break; + } } - if (i == ARRAY_SIZE(backend_table)) { + if (i == NULL) { error_setg(errp, "chardev: backend \"%s\" not found", qemu_opt_get(opts, "backend")); - goto err; + return NULL; } - chr = backend_table[i].open(opts); + chr = cd->open(opts); if (!chr) { error_setg(errp, "chardev: opening backend \"%s\" failed", qemu_opt_get(opts, "backend")); @@ -3677,3 +3658,44 @@ void qmp_chardev_remove(const char *id, Error **errp) } qemu_chr_delete(chr); } + +static void register_types(void) +{ + register_char_driver("null", qemu_chr_open_null); + register_char_driver("socket", qemu_chr_open_socket); + register_char_driver("udp", qemu_chr_open_udp); + register_char_driver("msmouse", qemu_chr_open_msmouse); + register_char_driver("vc", vc_init); + register_char_driver("memory", qemu_chr_open_ringbuf); +#ifdef _WIN32 + register_char_driver("file", qemu_chr_open_win_file_out); + register_char_driver("pipe", qemu_chr_open_win_pipe); + register_char_driver("console", qemu_chr_open_win_con); + register_char_driver("serial", qemu_chr_open_win); + register_char_driver("stdio", qemu_chr_open_win_stdio); +#else + register_char_driver("file", qemu_chr_open_file_out); + register_char_driver("pipe", qemu_chr_open_pipe); + register_char_driver("stdio", qemu_chr_open_stdio); +#endif +#ifdef CONFIG_BRLAPI + register_char_driver("braille", chr_baum_init); +#endif +#ifdef HAVE_CHARDEV_TTY + register_char_driver("tty", qemu_chr_open_tty); + register_char_driver("serial", qemu_chr_open_tty); + register_char_driver("pty", qemu_chr_open_pty); +#endif +#ifdef HAVE_CHARDEV_PARPORT + register_char_driver("parallel", qemu_chr_open_pp); + register_char_driver("parport", qemu_chr_open_pp); +#endif +#ifdef CONFIG_SPICE + register_char_driver("spicevmc", qemu_chr_open_spice); +#if SPICE_SERVER_VERSION >= 0x000c02 + register_char_driver("spiceport", qemu_chr_open_spice_port); +#endif +#endif +} + +type_init(register_types);