]> git.proxmox.com Git - mirror_qemu.git/commitdiff
qemu-char: Call fe_claim / fe_release when not using qdev chr properties
authorHans de Goede <hdegoede@redhat.com>
Wed, 27 Mar 2013 19:29:40 +0000 (20:29 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Fri, 5 Apr 2013 00:21:25 +0000 (19:21 -0500)
chardev-frontends need to explictly check, increase and decrement the
avail_connections "property" of the chardev when they are not using a
qdev-chardev-property for the chardev.

This fixes things like:
qemu-kvm -chardev stdio,id=foo -device isa-serial,chardev=foo \
  -mon chardev=foo

Working, where they should fail. Most of the changes here are due to
old hardware emulation code which is using serial_hds directly rather then
a qdev-chardev-property.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Message-id: 1364412581-3672-3-git-send-email-hdegoede@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
12 files changed:
backends/rng-egd.c
gdbstub.c
hw/arm/pxa2xx.c
hw/bt-hci-csr.c
hw/ipoctal232.c
hw/ivshmem.c
hw/mcf_uart.c
hw/sh_serial.c
hw/xen_console.c
net/slirp.c
qemu-char.c
vl.c

index 5e012e9e30402e36fe061f2dcad95d372cc24e54..cc6f5ee28ebeaea6f29902a487144b8c3eabeff6 100644 (file)
@@ -149,6 +149,11 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
         return;
     }
 
+    if (qemu_chr_fe_claim(s->chr) != 0) {
+        error_set(errp, QERR_DEVICE_IN_USE, s->chr_name);
+        return;
+    }
+
     /* FIXME we should resubmit pending requests when the CDS reconnects. */
     qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
                           NULL, s);
@@ -191,6 +196,7 @@ static void rng_egd_finalize(Object *obj)
 
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+        qemu_chr_fe_release(s->chr);
     }
 
     g_free(s->chr_name);
index a666cb5bb025cf4afa9ff034c8156210bfcc5a37..a0288a77fb219af89cb8eac1594ce17d8dcb0d6b 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3025,6 +3025,7 @@ int gdbserver_start(const char *device)
         if (!chr)
             return -1;
 
+        qemu_chr_fe_claim_no_fail(chr);
         qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
                               gdb_chr_event, NULL);
     }
index 7467cca4f7c5c64b5f775fb49ee9b6d8a8ad3b19..b7ca511d45c04d3a5312ef0602ce5ee9f48adc04 100644 (file)
@@ -1981,9 +1981,11 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
     memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000);
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
-    if (chr)
+    if (chr) {
+        qemu_chr_fe_claim_no_fail(chr);
         qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
                         pxa2xx_fir_rx, pxa2xx_fir_event, s);
+    }
 
     register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
                     pxa2xx_fir_load, s);
index e4ada3c731174983afaed69056e564e9bae3bbf2..55c819b08562880956533d7be8f85060751aaba5 100644 (file)
@@ -439,6 +439,7 @@ CharDriverState *uart_hci_init(qemu_irq wakeup)
     s->chr.opaque = s;
     s->chr.chr_write = csrhci_write;
     s->chr.chr_ioctl = csrhci_ioctl;
+    s->chr.avail_connections = 1;
 
     s->hci = qemu_next_hci();
     s->hci->opaque = s;
index 1da6a9917505275d65058b9faef1da44e3985de3..345efaecc9ee13e42356b0ea2ab662181edeaae9 100644 (file)
@@ -556,6 +556,7 @@ static int ipoctal_init(IPackDevice *ip)
 
             if (ch->dev) {
                 index++;
+                qemu_chr_fe_claim_no_fail(ch->dev);
                 qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
                                       hostdev_receive, hostdev_event, ch);
                 DPRINTF("Redirecting channel %u to %s (%s)\n",
index 68a2cf2e69c943312963d153eaaf1389fdb44314..af2789e9ac820e654e868a1595aa0ede8f93b026 100644 (file)
@@ -292,6 +292,7 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *
         fprintf(stderr, "creating eventfd for eventfd %d failed\n", eventfd);
         exit(-1);
     }
+    qemu_chr_fe_claim_no_fail(chr);
 
     /* if MSI is supported we need multiple interrupts */
     if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
index aacf0f05ed3a500040de2bba960d782408c356aa..e5de801671327cd024039c419feffc1980e767b1 100644 (file)
@@ -280,6 +280,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
     s->chr = chr;
     s->irq = irq;
     if (chr) {
+        qemu_chr_fe_claim_no_fail(chr);
         qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
                               mcf_uart_event, s);
     }
index 40e797c5a234886bb90382df67bf7536efd33a5a..462969557ca06008d743af6b3f83ef5b430d1cbf 100644 (file)
@@ -396,9 +396,11 @@ void sh_serial_init(MemoryRegion *sysmem,
 
     s->chr = chr;
 
-    if (chr)
+    if (chr) {
+        qemu_chr_fe_claim_no_fail(chr);
         qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
                              sh_serial_event, s);
+    }
 
     s->eri = eri_source;
     s->rxi = rxi_source;
index a8db6f8d8f109d47e4a75314861ceedbe9ec6562..c56ef4737fb44322b0d5218f6453356384befeac 100644 (file)
@@ -241,9 +241,17 @@ static int con_initialise(struct XenDevice *xendev)
        return -1;
 
     xen_be_bind_evtchn(&con->xendev);
-    if (con->chr)
-        qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
-                              NULL, con);
+    if (con->chr) {
+        if (qemu_chr_fe_claim(con->chr) == 0) {
+            qemu_chr_add_handlers(con->chr, xencons_can_receive,
+                                  xencons_receive, NULL, con);
+        } else {
+            xen_be_printf(xendev, 0,
+                          "xen_console_init error chardev %s already used\n",
+                          con->chr->label);
+            con->chr = NULL;
+        }
+    }
 
     xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
                  con->ring_ref,
@@ -260,8 +268,10 @@ static void con_disconnect(struct XenDevice *xendev)
     if (!xendev->dev) {
         return;
     }
-    if (con->chr)
+    if (con->chr) {
         qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
+        qemu_chr_fe_release(con->chr);
+    }
     xen_be_unbind_evtchn(&con->xendev);
 
     if (con->sring) {
index 4df550faf6c86080cfc4e9e6585b2fcf00235126..eabfee6d4fdfef7068a8eb9eed3ab96d542e520f 100644 (file)
@@ -660,6 +660,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
         fwd->port = port;
         fwd->slirp = s->slirp;
 
+        qemu_chr_fe_claim_no_fail(fwd->hd);
         qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
                               NULL, fwd);
     }
index 100f9a968ccdc9dbc2af34c95236ae12cffffcd8..e5eb8dd2ef87f31eaefce500c168fc329d2e6216 100644 (file)
@@ -3411,6 +3411,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
         error_free(err);
     }
     if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
+        qemu_chr_fe_claim_no_fail(chr);
         monitor_init(chr, MONITOR_USE_READLINE);
     }
     return chr;
@@ -3523,9 +3524,16 @@ CharDriverState *qemu_chr_find(const char *name)
 CharDriverState *qemu_char_get_next_serial(void)
 {
     static int next_serial;
+    CharDriverState *chr;
 
     /* FIXME: This function needs to go away: use chardev properties!  */
-    return serial_hds[next_serial++];
+
+    while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) {
+        chr = serial_hds[next_serial++];
+        qemu_chr_fe_claim_no_fail(chr);
+        return chr;
+    }
+    return NULL;
 }
 
 QemuOptsList qemu_chardev_opts = {
diff --git a/vl.c b/vl.c
index e2c97062fd0201ac253f31e655ad45fe26abb309..33f30b6ef05d49522676e34fc4b3181342420710 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2396,6 +2396,7 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
         exit(1);
     }
 
+    qemu_chr_fe_claim_no_fail(chr);
     monitor_init(chr, flags);
     return 0;
 }