Blame 0107-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch

Justin M. Forbes d4cdad
From 61efa48e1973eaac16615c85198d9d74e36a3124 Mon Sep 17 00:00:00 2001
Justin M. Forbes d4cdad
From: Amit Shah <amit.shah@redhat.com>
Justin M. Forbes d4cdad
Date: Mon, 21 Mar 2011 20:31:45 +0100
Justin M. Forbes d4cdad
Subject: [PATCH 107/118] char: Add a QemuChrHandlers struct to initialise
Justin M. Forbes d4cdad
 chardev handlers
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
Instead of passing each handler in the qemu_add_handlers() function,
Justin M. Forbes d4cdad
create a struct of handlers that can be passed to the function instead.
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Justin M. Forbes d4cdad
---
Justin M. Forbes d4cdad
 gdbstub.c               |    9 +++++++--
Justin M. Forbes d4cdad
 hw/ccid-card-passthru.c |   11 +++++++----
Justin M. Forbes d4cdad
 hw/debugcon.c           |    2 +-
Justin M. Forbes d4cdad
 hw/escc.c               |    9 +++++++--
Justin M. Forbes d4cdad
 hw/etraxfs_ser.c        |   13 +++++++++----
Justin M. Forbes d4cdad
 hw/grlib_apbuart.c      |   12 +++++++-----
Justin M. Forbes d4cdad
 hw/ivshmem.c            |   28 ++++++++++++++++++++++------
Justin M. Forbes d4cdad
 hw/lm32_juart.c         |    8 +++++++-
Justin M. Forbes d4cdad
 hw/lm32_uart.c          |    8 +++++++-
Justin M. Forbes d4cdad
 hw/mcf_uart.c           |    9 +++++++--
Justin M. Forbes d4cdad
 hw/milkymist-uart.c     |    8 +++++++-
Justin M. Forbes d4cdad
 hw/pl011.c              |    9 +++++++--
Justin M. Forbes d4cdad
 hw/pxa2xx.c             |   13 +++++++++----
Justin M. Forbes d4cdad
 hw/serial.c             |    9 +++++++--
Justin M. Forbes d4cdad
 hw/sh_serial.c          |   12 +++++++++---
Justin M. Forbes d4cdad
 hw/spapr_vty.c          |    8 ++++++--
Justin M. Forbes d4cdad
 hw/strongarm.c          |   12 +++++++-----
Justin M. Forbes d4cdad
 hw/syborg_serial.c      |    9 +++++++--
Justin M. Forbes d4cdad
 hw/usb-serial.c         |    9 +++++++--
Justin M. Forbes d4cdad
 hw/virtio-console.c     |   11 ++++++++---
Justin M. Forbes d4cdad
 hw/xen_console.c        |   16 +++++++++++-----
Justin M. Forbes d4cdad
 hw/xilinx_uartlite.c    |   11 +++++++++--
Justin M. Forbes d4cdad
 monitor.c               |   18 ++++++++++++++----
Justin M. Forbes d4cdad
 net/slirp.c             |    8 ++++++--
Justin M. Forbes d4cdad
 qemu-char.c             |   32 ++++++++++++++++++++++----------
Justin M. Forbes d4cdad
 qemu-char.h             |   13 +++++++++----
Justin M. Forbes d4cdad
 usb-redir.c             |    9 +++++++--
Justin M. Forbes d4cdad
 27 files changed, 233 insertions(+), 83 deletions(-)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/gdbstub.c b/gdbstub.c
Justin M. Forbes d4cdad
index 640cf4e..b984e12 100644
Justin M. Forbes d4cdad
--- a/gdbstub.c
Justin M. Forbes d4cdad
+++ b/gdbstub.c
Justin M. Forbes d4cdad
@@ -2860,6 +2860,12 @@ static void gdb_sigterm_handler(int signal)
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
 #endif
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers gdb_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = gdb_chr_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = gdb_chr_receive,
Justin M. Forbes d4cdad
+    .fd_event = gdb_chr_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 int gdbserver_start(const char *device)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     GDBState *s;
Justin M. Forbes d4cdad
@@ -2889,8 +2895,7 @@ int gdbserver_start(const char *device)
Justin M. Forbes d4cdad
         if (!chr)
Justin M. Forbes d4cdad
             return -1;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
Justin M. Forbes d4cdad
-                              gdb_chr_event, NULL);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &gdb_handlers, NULL);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s = gdbserver_state;
Justin M. Forbes d4cdad
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
Justin M. Forbes d4cdad
index 9f51c6c..c5bff01 100644
Justin M. Forbes d4cdad
--- a/hw/ccid-card-passthru.c
Justin M. Forbes d4cdad
+++ b/hw/ccid-card-passthru.c
Justin M. Forbes d4cdad
@@ -274,6 +274,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
Justin M. Forbes d4cdad
     return card->atr;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers passthru_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = ccid_card_vscard_can_read,
Justin M. Forbes d4cdad
+    .fd_read = ccid_card_vscard_read,
Justin M. Forbes d4cdad
+    .fd_event = ccid_card_vscard_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int passthru_initfn(CCIDCardState *base)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     PassthruState *card = DO_UPCAST(PassthruState, base, base);
Justin M. Forbes d4cdad
@@ -282,10 +288,7 @@ static int passthru_initfn(CCIDCardState *base)
Justin M. Forbes d4cdad
     card->vscard_in_hdr = 0;
Justin M. Forbes d4cdad
     if (card->cs) {
Justin M. Forbes d4cdad
         DPRINTF(card, D_INFO, "initing chardev\n");
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(card->cs,
Justin M. Forbes d4cdad
-            ccid_card_vscard_can_read,
Justin M. Forbes d4cdad
-            ccid_card_vscard_read,
Justin M. Forbes d4cdad
-            ccid_card_vscard_event, card);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(card->cs, &passthru_handlers, card);
Justin M. Forbes d4cdad
         ccid_card_vscard_send_init(card);
Justin M. Forbes d4cdad
     } else {
Justin M. Forbes d4cdad
         error_report("missing chardev");
Justin M. Forbes d4cdad
diff --git a/hw/debugcon.c b/hw/debugcon.c
Justin M. Forbes d4cdad
index c9ee6d9..1d3c3ca 100644
Justin M. Forbes d4cdad
--- a/hw/debugcon.c
Justin M. Forbes d4cdad
+++ b/hw/debugcon.c
Justin M. Forbes d4cdad
@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s)
Justin M. Forbes d4cdad
         exit(1);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(s->chr, NULL, s);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
 static int debugcon_isa_initfn(ISADevice *dev)
Justin M. Forbes d4cdad
diff --git a/hw/escc.c b/hw/escc.c
Justin M. Forbes d4cdad
index 13c7e66..997377e 100644
Justin M. Forbes d4cdad
--- a/hw/escc.c
Justin M. Forbes d4cdad
+++ b/hw/escc.c
Justin M. Forbes d4cdad
@@ -867,6 +867,12 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
Justin M. Forbes d4cdad
     sysbus_mmio_map(s, 0, base);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers serial_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = serial_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = serial_receive1,
Justin M. Forbes d4cdad
+    .fd_event = serial_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int escc_init1(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     SerialState *s = FROM_SYSBUS(SerialState, dev);
Justin M. Forbes d4cdad
@@ -879,8 +885,7 @@ static int escc_init1(SysBusDevice *dev)
Justin M. Forbes d4cdad
         s->chn[i].chn = 1 - i;
Justin M. Forbes d4cdad
         s->chn[i].clock = s->frequency / 2;
Justin M. Forbes d4cdad
         if (s->chn[i].chr) {
Justin M. Forbes d4cdad
-            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
Justin M. Forbes d4cdad
-                                  serial_receive1, serial_event, &s->chn[i]);
Justin M. Forbes d4cdad
+            qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]);
Justin M. Forbes d4cdad
         }
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
     s->chn[0].otherchn = &s->chn[1];
Justin M. Forbes d4cdad
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
Justin M. Forbes d4cdad
index 298b985..29d486e 100644
Justin M. Forbes d4cdad
--- a/hw/etraxfs_ser.c
Justin M. Forbes d4cdad
+++ b/hw/etraxfs_ser.c
Justin M. Forbes d4cdad
@@ -208,6 +208,12 @@ static void etraxfs_ser_reset(DeviceState *d)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers serial_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = serial_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = serial_receive,
Justin M. Forbes d4cdad
+    .fd_event = serial_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int etraxfs_ser_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
Justin M. Forbes d4cdad
@@ -217,10 +223,9 @@ static int etraxfs_ser_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
     sysbus_init_mmio_region(dev, &s->mmio);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->chr = qdev_init_chardev(&dev->qdev);
Justin M. Forbes d4cdad
-    if (s->chr)
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr,
Justin M. Forbes d4cdad
-                      serial_can_receive, serial_receive,
Justin M. Forbes d4cdad
-                      serial_event, s);
Justin M. Forbes d4cdad
+    if (s->chr) {
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, &serial_handlers, s);
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
Justin M. Forbes d4cdad
index c90b810..ac6c33b 100644
Justin M. Forbes d4cdad
--- a/hw/grlib_apbuart.c
Justin M. Forbes d4cdad
+++ b/hw/grlib_apbuart.c
Justin M. Forbes d4cdad
@@ -144,16 +144,18 @@ static CPUWriteMemoryFunc * const grlib_apbuart_write[] = {
Justin M. Forbes d4cdad
     NULL, NULL, grlib_apbuart_writel,
Justin M. Forbes d4cdad
 };
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers grlib_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = grlib_apbuart_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = grlib_apbuart_receive,
Justin M. Forbes d4cdad
+    .fd_event = grlib_apbuart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int grlib_apbuart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     UART *uart      = FROM_SYSBUS(typeof(*uart), dev);
Justin M. Forbes d4cdad
     int   uart_regs = 0;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(uart->chr,
Justin M. Forbes d4cdad
-                          grlib_apbuart_can_receive,
Justin M. Forbes d4cdad
-                          grlib_apbuart_receive,
Justin M. Forbes d4cdad
-                          grlib_apbuart_event,
Justin M. Forbes d4cdad
-                          uart);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     sysbus_init_irq(dev, &uart->irq);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
Justin M. Forbes d4cdad
index 7b4dbf6..ee78576 100644
Justin M. Forbes d4cdad
--- a/hw/ivshmem.c
Justin M. Forbes d4cdad
+++ b/hw/ivshmem.c
Justin M. Forbes d4cdad
@@ -276,6 +276,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) {
Justin M. Forbes d4cdad
     msix_notify(pdev, entry->vector);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers ivshmem_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = ivshmem_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = ivshmem_receive,
Justin M. Forbes d4cdad
+    .fd_event = ivshmem_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+static const QemuChrHandlers ivshmem_msi_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = ivshmem_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = fake_irqfd,
Justin M. Forbes d4cdad
+    .fd_event = ivshmem_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static CharDriverState* create_eventfd_chr_device(void * opaque, int eventfd,
Justin M. Forbes d4cdad
                                                                     int vector)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
@@ -295,11 +307,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, int eventfd,
Justin M. Forbes d4cdad
         s->eventfd_table[vector].pdev = &s->dev;
Justin M. Forbes d4cdad
         s->eventfd_table[vector].vector = vector;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd,
Justin M. Forbes d4cdad
-                      ivshmem_event, &s->eventfd_table[vector]);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &ivshmem_msi_handlers,
Justin M. Forbes d4cdad
+                              &s->eventfd_table[vector]);
Justin M. Forbes d4cdad
     } else {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive,
Justin M. Forbes d4cdad
-                      ivshmem_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &ivshmem_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return chr;
Justin M. Forbes d4cdad
@@ -614,6 +625,12 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers ivshmem_server_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = ivshmem_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = ivshmem_read,
Justin M. Forbes d4cdad
+    .fd_event = ivshmem_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int pci_ivshmem_init(PCIDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
Justin M. Forbes d4cdad
@@ -703,8 +720,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
         s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read,
Justin M. Forbes d4cdad
-                     ivshmem_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s);
Justin M. Forbes d4cdad
     } else {
Justin M. Forbes d4cdad
         /* just map the file immediately, we're not using a server */
Justin M. Forbes d4cdad
         int fd;
Justin M. Forbes d4cdad
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
Justin M. Forbes d4cdad
index 5454aa4..1b9fa07 100644
Justin M. Forbes d4cdad
--- a/hw/lm32_juart.c
Justin M. Forbes d4cdad
+++ b/hw/lm32_juart.c
Justin M. Forbes d4cdad
@@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d)
Justin M. Forbes d4cdad
     s->jrx = 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers juart_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = juart_can_rx,
Justin M. Forbes d4cdad
+    .fd_read = juart_rx,
Justin M. Forbes d4cdad
+    .fd_event = juart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int lm32_juart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->chr = qdev_init_chardev(&dev->qdev);
Justin M. Forbes d4cdad
     if (s->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, juart_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
Justin M. Forbes d4cdad
index 3678545..ccaf88c 100644
Justin M. Forbes d4cdad
--- a/hw/lm32_uart.c
Justin M. Forbes d4cdad
+++ b/hw/lm32_uart.c
Justin M. Forbes d4cdad
@@ -242,6 +242,12 @@ static void uart_reset(DeviceState *d)
Justin M. Forbes d4cdad
     s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers uart_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = uart_can_rx,
Justin M. Forbes d4cdad
+    .fd_read = uart_rx,
Justin M. Forbes d4cdad
+    .fd_event = uart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int lm32_uart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     LM32UartState *s = FROM_SYSBUS(typeof(*s), dev);
Justin M. Forbes d4cdad
@@ -255,7 +261,7 @@ static int lm32_uart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->chr = qdev_init_chardev(&dev->qdev);
Justin M. Forbes d4cdad
     if (s->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, uart_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
Justin M. Forbes d4cdad
index e6b2ab0..2870683 100644
Justin M. Forbes d4cdad
--- a/hw/mcf_uart.c
Justin M. Forbes d4cdad
+++ b/hw/mcf_uart.c
Justin M. Forbes d4cdad
@@ -268,6 +268,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
Justin M. Forbes d4cdad
     mcf_uart_push_byte(s, buf[0]);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers mcf_uart_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = mcf_uart_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = mcf_uart_receive,
Justin M. Forbes d4cdad
+    .fd_event = mcf_uart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     mcf_uart_state *s;
Justin M. Forbes d4cdad
@@ -276,8 +282,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
Justin M. Forbes d4cdad
     s->chr = chr;
Justin M. Forbes d4cdad
     s->irq = irq;
Justin M. Forbes d4cdad
     if (chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
Justin M. Forbes d4cdad
-                              mcf_uart_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &mcf_uart_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
     mcf_uart_reset(s);
Justin M. Forbes d4cdad
     return s;
Justin M. Forbes d4cdad
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
Justin M. Forbes d4cdad
index 5404ca9..fd10e12 100644
Justin M. Forbes d4cdad
--- a/hw/milkymist-uart.c
Justin M. Forbes d4cdad
+++ b/hw/milkymist-uart.c
Justin M. Forbes d4cdad
@@ -189,6 +189,12 @@ static void milkymist_uart_reset(DeviceState *d)
Justin M. Forbes d4cdad
     s->regs[R_STAT] = STAT_THRE;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers uart_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = uart_can_rx,
Justin M. Forbes d4cdad
+    .fd_read = uart_rx,
Justin M. Forbes d4cdad
+    .fd_event = uart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int milkymist_uart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
Justin M. Forbes d4cdad
@@ -201,7 +207,7 @@ static int milkymist_uart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->chr = qdev_init_chardev(&dev->qdev);
Justin M. Forbes d4cdad
     if (s->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, uart_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
diff --git a/hw/pl011.c b/hw/pl011.c
Justin M. Forbes d4cdad
index 707a161..7482246 100644
Justin M. Forbes d4cdad
--- a/hw/pl011.c
Justin M. Forbes d4cdad
+++ b/hw/pl011.c
Justin M. Forbes d4cdad
@@ -260,6 +260,12 @@ static const VMStateDescription vmstate_pl011 = {
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
 };
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers pl011_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = pl011_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = pl011_receive,
Justin M. Forbes d4cdad
+    .fd_event = pl011_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int pl011_init(SysBusDevice *dev, const unsigned char *id)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     int iomemtype;
Justin M. Forbes d4cdad
@@ -278,8 +284,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
Justin M. Forbes d4cdad
     s->cr = 0x300;
Justin M. Forbes d4cdad
     s->flags = 0x90;
Justin M. Forbes d4cdad
     if (s->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
Justin M. Forbes d4cdad
-                              pl011_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, &pl011_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
     vmstate_register(&dev->qdev, -1, &vmstate_pl011, s);
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
Justin M. Forbes d4cdad
index e9a507e..24925b6 100644
Justin M. Forbes d4cdad
--- a/hw/pxa2xx.c
Justin M. Forbes d4cdad
+++ b/hw/pxa2xx.c
Justin M. Forbes d4cdad
@@ -1984,6 +1984,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id)
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers pxa2xx_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = pxa2xx_fir_is_empty,
Justin M. Forbes d4cdad
+    .fd_read = pxa2xx_fir_rx,
Justin M. Forbes d4cdad
+    .fd_event = pxa2xx_fir_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
Justin M. Forbes d4cdad
                 target_phys_addr_t base,
Justin M. Forbes d4cdad
                 qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma,
Justin M. Forbes d4cdad
@@ -2002,10 +2008,9 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
Justin M. Forbes d4cdad
     memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000);
Justin M. Forbes d4cdad
     memory_region_add_subregion(sysmem, base, &s->iomem);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    if (chr)
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
Justin M. Forbes d4cdad
-                        pxa2xx_fir_rx, pxa2xx_fir_event, s);
Justin M. Forbes d4cdad
-
Justin M. Forbes d4cdad
+    if (chr) {
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &pxa2xx_handlers, s);
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
     register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
Justin M. Forbes d4cdad
                     pxa2xx_fir_load, s);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/hw/serial.c b/hw/serial.c
Justin M. Forbes d4cdad
index d35c7a9..6499d4a 100644
Justin M. Forbes d4cdad
--- a/hw/serial.c
Justin M. Forbes d4cdad
+++ b/hw/serial.c
Justin M. Forbes d4cdad
@@ -728,6 +728,12 @@ static void serial_reset(void *opaque)
Justin M. Forbes d4cdad
     qemu_irq_lower(s->irq);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers serial_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = serial_can_receive1,
Justin M. Forbes d4cdad
+    .fd_read = serial_receive1,
Justin M. Forbes d4cdad
+    .fd_event = serial_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static void serial_init_core(SerialState *s)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     if (!s->chr) {
Justin M. Forbes d4cdad
@@ -742,8 +748,7 @@ static void serial_init_core(SerialState *s)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     qemu_register_reset(serial_reset, s);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
Justin M. Forbes d4cdad
-                          serial_event, s);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(s->chr, &serial_handlers, s);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
 /* Change the main reference oscillator frequency. */
Justin M. Forbes d4cdad
diff --git a/hw/sh_serial.c b/hw/sh_serial.c
Justin M. Forbes d4cdad
index a20c59e..470ce7a 100644
Justin M. Forbes d4cdad
--- a/hw/sh_serial.c
Justin M. Forbes d4cdad
+++ b/hw/sh_serial.c
Justin M. Forbes d4cdad
@@ -350,6 +350,12 @@ static CPUWriteMemoryFunc * const sh_serial_writefn[] = {
Justin M. Forbes d4cdad
     &sh_serial_write,
Justin M. Forbes d4cdad
 };
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers sh_serial_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = sh_serial_can_receive1,
Justin M. Forbes d4cdad
+    .fd_read = sh_serial_receive1,
Justin M. Forbes d4cdad
+    .fd_event = sh_serial_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 void sh_serial_init (target_phys_addr_t base, int feat,
Justin M. Forbes d4cdad
 		     uint32_t freq, CharDriverState *chr,
Justin M. Forbes d4cdad
 		     qemu_irq eri_source,
Justin M. Forbes d4cdad
@@ -389,9 +395,9 @@ void sh_serial_init (target_phys_addr_t base, int feat,
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->chr = chr;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    if (chr)
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
Justin M. Forbes d4cdad
-			      sh_serial_event, s);
Justin M. Forbes d4cdad
+    if (chr) {
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &sh_serial_handlers, s);
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->eri = eri_source;
Justin M. Forbes d4cdad
     s->rxi = rxi_source;
Justin M. Forbes d4cdad
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
Justin M. Forbes d4cdad
index f23cc36..0d9cd59 100644
Justin M. Forbes d4cdad
--- a/hw/spapr_vty.c
Justin M. Forbes d4cdad
+++ b/hw/spapr_vty.c
Justin M. Forbes d4cdad
@@ -54,6 +54,11 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
Justin M. Forbes d4cdad
     qemu_chr_fe_write(dev->chardev, buf, len);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers vty_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = vty_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = vty_receive,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int spapr_vty_init(VIOsPAPRDevice *sdev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
Justin M. Forbes d4cdad
@@ -63,8 +68,7 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
Justin M. Forbes d4cdad
         exit(1);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(dev->chardev, vty_can_receive,
Justin M. Forbes d4cdad
-                          vty_receive, NULL, dev);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(dev->chardev, vty_handlers, dev);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
diff --git a/hw/strongarm.c b/hw/strongarm.c
Justin M. Forbes d4cdad
index a3d9080..8a8a219 100644
Justin M. Forbes d4cdad
--- a/hw/strongarm.c
Justin M. Forbes d4cdad
+++ b/hw/strongarm.c
Justin M. Forbes d4cdad
@@ -1160,6 +1160,12 @@ static const MemoryRegionOps strongarm_uart_ops = {
Justin M. Forbes d4cdad
     .endianness = DEVICE_NATIVE_ENDIAN,
Justin M. Forbes d4cdad
 };
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers strongarm_uart_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = strongarm_uart_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = strongarm_uart_receive,
Justin M. Forbes d4cdad
+    .fd_event = strongarm_uart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int strongarm_uart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
Justin M. Forbes d4cdad
@@ -1172,11 +1178,7 @@ static int strongarm_uart_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
     s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     if (s->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr,
Justin M. Forbes d4cdad
-                        strongarm_uart_can_receive,
Justin M. Forbes d4cdad
-                        strongarm_uart_receive,
Justin M. Forbes d4cdad
-                        strongarm_uart_event,
Justin M. Forbes d4cdad
-                        s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
Justin M. Forbes d4cdad
index c83f82c..fff76da 100644
Justin M. Forbes d4cdad
--- a/hw/syborg_serial.c
Justin M. Forbes d4cdad
+++ b/hw/syborg_serial.c
Justin M. Forbes d4cdad
@@ -292,6 +292,12 @@ static const VMStateDescription vmstate_syborg_serial = {
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
 };
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers syborg_serial_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = syborg_serial_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = syborg_serial_receive,
Justin M. Forbes d4cdad
+    .fd_event = syborg_serial_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int syborg_serial_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     SyborgSerialState *s = FROM_SYSBUS(SyborgSerialState, dev);
Justin M. Forbes d4cdad
@@ -304,8 +310,7 @@ static int syborg_serial_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
     sysbus_init_mmio(dev, 0x1000, iomemtype);
Justin M. Forbes d4cdad
     s->chr = qdev_init_chardev(&dev->qdev);
Justin M. Forbes d4cdad
     if (s->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr, syborg_serial_can_receive,
Justin M. Forbes d4cdad
-                              syborg_serial_receive, syborg_serial_event, s);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, &syborg_serial_handlers, s);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
     if (s->fifo_size <= 0) {
Justin M. Forbes d4cdad
         fprintf(stderr, "syborg_serial: fifo too small\n");
Justin M. Forbes d4cdad
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
Justin M. Forbes d4cdad
index 7dbf6df..bcf6622 100644
Justin M. Forbes d4cdad
--- a/hw/usb-serial.c
Justin M. Forbes d4cdad
+++ b/hw/usb-serial.c
Justin M. Forbes d4cdad
@@ -482,6 +482,12 @@ static void usb_serial_event(void *opaque, int event)
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers usb_serial_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = usb_serial_can_read,
Justin M. Forbes d4cdad
+    .fd_read = usb_serial_read,
Justin M. Forbes d4cdad
+    .fd_event = usb_serial_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int usb_serial_initfn(USBDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);
Justin M. Forbes d4cdad
@@ -493,8 +499,7 @@ static int usb_serial_initfn(USBDevice *dev)
Justin M. Forbes d4cdad
         return -1;
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
Justin M. Forbes d4cdad
-                          usb_serial_event, s);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s);
Justin M. Forbes d4cdad
     usb_serial_handle_reset(dev);
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
Justin M. Forbes d4cdad
index d3351c8..6d6f3ef 100644
Justin M. Forbes d4cdad
--- a/hw/virtio-console.c
Justin M. Forbes d4cdad
+++ b/hw/virtio-console.c
Justin M. Forbes d4cdad
@@ -95,6 +95,12 @@ static void chr_event(void *opaque, int event)
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers chr_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = chr_can_read,
Justin M. Forbes d4cdad
+    .fd_read = chr_read,
Justin M. Forbes d4cdad
+    .fd_event = chr_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int virtconsole_initfn(VirtIOSerialPort *port)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
Justin M. Forbes d4cdad
@@ -107,8 +113,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     if (vcon->chr) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
Justin M. Forbes d4cdad
-                              vcon);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon);
Justin M. Forbes d4cdad
         info->have_data = flush_buf;
Justin M. Forbes d4cdad
         info->guest_open = guest_open;
Justin M. Forbes d4cdad
         info->guest_close = guest_close;
Justin M. Forbes d4cdad
@@ -126,7 +131,7 @@ static int virtconsole_exitfn(VirtIOSerialPort *port)
Justin M. Forbes d4cdad
 	 * Instead of closing the chardev, free it so it can be used
Justin M. Forbes d4cdad
 	 * for other purposes.
Justin M. Forbes d4cdad
 	 */
Justin M. Forbes d4cdad
-	qemu_chr_add_handlers(vcon->chr, NULL, NULL, NULL, NULL);
Justin M. Forbes d4cdad
+	qemu_chr_add_handlers(vcon->chr, NULL, NULL);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
diff --git a/hw/xen_console.c b/hw/xen_console.c
Justin M. Forbes d4cdad
index edcb31c..2ba74f0 100644
Justin M. Forbes d4cdad
--- a/hw/xen_console.c
Justin M. Forbes d4cdad
+++ b/hw/xen_console.c
Justin M. Forbes d4cdad
@@ -212,6 +212,11 @@ out:
Justin M. Forbes d4cdad
     return ret;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers xencons_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = xencons_can_receive,
Justin M. Forbes d4cdad
+    .fd_read = xencons_receive,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int con_initialise(struct XenDevice *xendev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
Justin M. Forbes d4cdad
@@ -232,9 +237,9 @@ static int con_initialise(struct XenDevice *xendev)
Justin M. Forbes d4cdad
 	return -1;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     xen_be_bind_evtchn(&con->xendev);
Justin M. Forbes d4cdad
-    if (con->chr)
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
Justin M. Forbes d4cdad
-                              NULL, con);
Justin M. Forbes d4cdad
+    if (con->chr) {
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(con->chr, &xencons_handlers, con);
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
Justin M. Forbes d4cdad
 		  con->ring_ref,
Justin M. Forbes d4cdad
@@ -248,8 +253,9 @@ static void con_disconnect(struct XenDevice *xendev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    if (con->chr)
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
Justin M. Forbes d4cdad
+    if (con->chr) {
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(con->chr, NULL, NULL);
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
     xen_be_unbind_evtchn(&con->xendev);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     if (con->sring) {
Justin M. Forbes d4cdad
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
Justin M. Forbes d4cdad
index ceb7b4d..69f7191 100644
Justin M. Forbes d4cdad
--- a/hw/xilinx_uartlite.c
Justin M. Forbes d4cdad
+++ b/hw/xilinx_uartlite.c
Justin M. Forbes d4cdad
@@ -195,6 +195,12 @@ static void uart_event(void *opaque, int event)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers uart_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = uart_can_rx,
Justin M. Forbes d4cdad
+    .fd_read = uart_rx,
Justin M. Forbes d4cdad
+    .fd_event = uart_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int xilinx_uartlite_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
Justin M. Forbes d4cdad
@@ -206,8 +212,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev)
Justin M. Forbes d4cdad
     sysbus_init_mmio_region(dev, &s->mmio);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     s->chr = qdev_init_chardev(&dev->qdev);
Justin M. Forbes d4cdad
-    if (s->chr)
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
Justin M. Forbes d4cdad
+    if (s->chr) {
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(s->chr, &uart_handlers, s);
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
diff --git a/monitor.c b/monitor.c
Justin M. Forbes d4cdad
index f956eb7..a82fda3 100644
Justin M. Forbes d4cdad
--- a/monitor.c
Justin M. Forbes d4cdad
+++ b/monitor.c
Justin M. Forbes d4cdad
@@ -4882,6 +4882,18 @@ static void sortcmdlist(void)
Justin M. Forbes d4cdad
  * End:
Justin M. Forbes d4cdad
  */
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers monitor_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = monitor_can_read,
Justin M. Forbes d4cdad
+    .fd_read = monitor_read,
Justin M. Forbes d4cdad
+    .fd_event = monitor_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+static const QemuChrHandlers monitor_control_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = monitor_can_read,
Justin M. Forbes d4cdad
+    .fd_read = monitor_control_read,
Justin M. Forbes d4cdad
+    .fd_event = monitor_control_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 void monitor_init(CharDriverState *chr, int flags)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     static int is_first_init = 1;
Justin M. Forbes d4cdad
@@ -4904,12 +4916,10 @@ void monitor_init(CharDriverState *chr, int flags)
Justin M. Forbes d4cdad
     if (monitor_ctrl_mode(mon)) {
Justin M. Forbes d4cdad
         mon->mc = g_malloc0(sizeof(MonitorControl));
Justin M. Forbes d4cdad
         /* Control mode requires special handlers */
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
Justin M. Forbes d4cdad
-                              monitor_control_event, mon);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &monitor_control_handlers, mon);
Justin M. Forbes d4cdad
         qemu_chr_fe_set_echo(chr, true);
Justin M. Forbes d4cdad
     } else {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
Justin M. Forbes d4cdad
-                              monitor_event, mon);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(chr, &monitor_handlers, mon);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     QLIST_INSERT_HEAD(&mon_list, mon, entry);
Justin M. Forbes d4cdad
diff --git a/net/slirp.c b/net/slirp.c
Justin M. Forbes d4cdad
index 6646ecb..05405ff 100644
Justin M. Forbes d4cdad
--- a/net/slirp.c
Justin M. Forbes d4cdad
+++ b/net/slirp.c
Justin M. Forbes d4cdad
@@ -576,6 +576,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
Justin M. Forbes d4cdad
     slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers guestfwd_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = guestfwd_can_read,
Justin M. Forbes d4cdad
+    .fd_read = guestfwd_read,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static int slirp_guestfwd(SlirpState *s, const char *config_str,
Justin M. Forbes d4cdad
                           int legacy_format)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
@@ -632,8 +637,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
Justin M. Forbes d4cdad
     fwd->port = port;
Justin M. Forbes d4cdad
     fwd->slirp = s->slirp;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
Justin M. Forbes d4cdad
-                          NULL, fwd);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd);
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
  fail_syntax:
Justin M. Forbes d4cdad
diff --git a/qemu-char.c b/qemu-char.c
Justin M. Forbes d4cdad
index a5ca611..d2a99a6 100644
Justin M. Forbes d4cdad
--- a/qemu-char.c
Justin M. Forbes d4cdad
+++ b/qemu-char.c
Justin M. Forbes d4cdad
@@ -189,19 +189,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
Justin M. Forbes d4cdad
     va_end(ap);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers null_handlers = {
Justin M. Forbes d4cdad
+    /* All handlers are initialised to NULL */
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 void qemu_chr_add_handlers(CharDriverState *s,
Justin M. Forbes d4cdad
-                           IOCanReadHandler *fd_can_read,
Justin M. Forbes d4cdad
-                           IOReadHandler *fd_read,
Justin M. Forbes d4cdad
-                           IOEventHandler *fd_event,
Justin M. Forbes d4cdad
-                           void *opaque)
Justin M. Forbes d4cdad
+                           const QemuChrHandlers *handlers, void *opaque)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
-    if (!opaque && !fd_can_read && !fd_read && !fd_event) {
Justin M. Forbes d4cdad
+    if (!s) {
Justin M. Forbes d4cdad
+        return;
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
+    if (!opaque && !handlers) {
Justin M. Forbes d4cdad
         /* chr driver being released. */
Justin M. Forbes d4cdad
         ++s->avail_connections;
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
-    s->chr_can_read = fd_can_read;
Justin M. Forbes d4cdad
-    s->chr_read = fd_read;
Justin M. Forbes d4cdad
-    s->chr_event = fd_event;
Justin M. Forbes d4cdad
+    if (!handlers) {
Justin M. Forbes d4cdad
+        handlers = &null_handlers;
Justin M. Forbes d4cdad
+    }
Justin M. Forbes d4cdad
+    s->chr_can_read = handlers->fd_can_read;
Justin M. Forbes d4cdad
+    s->chr_read = handlers->fd_read;
Justin M. Forbes d4cdad
+    s->chr_event = handlers->fd_event;
Justin M. Forbes d4cdad
     s->handler_opaque = opaque;
Justin M. Forbes d4cdad
     if (s->chr_update_read_handler)
Justin M. Forbes d4cdad
         s->chr_update_read_handler(s);
Justin M. Forbes d4cdad
@@ -441,6 +448,12 @@ static void mux_chr_event(void *opaque, int event)
Justin M. Forbes d4cdad
         mux_chr_send_event(d, i, event);
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers mux_chr_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = mux_chr_can_read,
Justin M. Forbes d4cdad
+    .fd_read = mux_chr_read,
Justin M. Forbes d4cdad
+    .fd_event = mux_chr_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 static void mux_chr_update_read_handler(CharDriverState *chr)
Justin M. Forbes d4cdad
 {
Justin M. Forbes d4cdad
     MuxDriver *d = chr->opaque;
Justin M. Forbes d4cdad
@@ -455,8 +468,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
Justin M. Forbes d4cdad
     d->chr_event[d->mux_cnt] = chr->chr_event;
Justin M. Forbes d4cdad
     /* Fix up the real driver with mux routines */
Justin M. Forbes d4cdad
     if (d->mux_cnt == 0) {
Justin M. Forbes d4cdad
-        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
Justin M. Forbes d4cdad
-                              mux_chr_event, chr);
Justin M. Forbes d4cdad
+        qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr);
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
     if (d->focus != -1) {
Justin M. Forbes d4cdad
         mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
Justin M. Forbes d4cdad
diff --git a/qemu-char.h b/qemu-char.h
Justin M. Forbes d4cdad
index 8ca1e2d..564e688 100644
Justin M. Forbes d4cdad
--- a/qemu-char.h
Justin M. Forbes d4cdad
+++ b/qemu-char.h
Justin M. Forbes d4cdad
@@ -222,10 +222,15 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
Justin M. Forbes d4cdad
  */
Justin M. Forbes d4cdad
 void qemu_chr_be_event(CharDriverState *s, int event);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
-void qemu_chr_add_handlers(CharDriverState *s,
Justin M. Forbes d4cdad
-                           IOCanReadHandler *fd_can_read,
Justin M. Forbes d4cdad
-                           IOReadHandler *fd_read,
Justin M. Forbes d4cdad
-                           IOEventHandler *fd_event,
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+typedef struct QemuChrHandlers {
Justin M. Forbes d4cdad
+    IOCanReadHandler *fd_can_read;
Justin M. Forbes d4cdad
+    IOReadHandler *fd_read;
Justin M. Forbes d4cdad
+    IOHandler *fd_write_unblocked;
Justin M. Forbes d4cdad
+    IOEventHandler *fd_event;
Justin M. Forbes d4cdad
+} QemuChrHandlers;
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
+void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers,
Justin M. Forbes d4cdad
                            void *opaque);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
 void qemu_chr_generic_open(CharDriverState *s);
Justin M. Forbes d4cdad
diff --git a/usb-redir.c b/usb-redir.c
Justin M. Forbes d4cdad
index 86bccf8..e421cff 100644
Justin M. Forbes d4cdad
--- a/usb-redir.c
Justin M. Forbes d4cdad
+++ b/usb-redir.c
Justin M. Forbes d4cdad
@@ -865,6 +865,12 @@ static void usbredir_chardev_event(void *opaque, int event)
Justin M. Forbes d4cdad
     }
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
+static const QemuChrHandlers usbredir_chr_handlers = {
Justin M. Forbes d4cdad
+    .fd_can_read = usbredir_chardev_can_read,
Justin M. Forbes d4cdad
+    .fd_read = usbredir_chardev_read,
Justin M. Forbes d4cdad
+    .fd_event = usbredir_chardev_event,
Justin M. Forbes d4cdad
+};
Justin M. Forbes d4cdad
+
Justin M. Forbes d4cdad
 /*
Justin M. Forbes d4cdad
  * init + destroy
Justin M. Forbes d4cdad
  */
Justin M. Forbes d4cdad
@@ -892,8 +898,7 @@ static int usbredir_initfn(USBDevice *udev)
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     /* Let the backend know we are ready */
Justin M. Forbes d4cdad
     qemu_chr_fe_open(dev->cs);
Justin M. Forbes d4cdad
-    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
Justin M. Forbes d4cdad
-                          usbredir_chardev_read, usbredir_chardev_event, dev);
Justin M. Forbes d4cdad
+    qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
Justin M. Forbes d4cdad
Justin M. Forbes d4cdad
     return 0;
Justin M. Forbes d4cdad
 }
Justin M. Forbes d4cdad
-- 
Justin M. Forbes d4cdad
1.7.7.5
Justin M. Forbes d4cdad