qemu/0101-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
Cole Robinson 22d63f488d Switch base tarball from qemu-kvm to qemu
qemu 1.3 release
Option to use linux VFIO driver to assign PCI devices
Many USB3 improvements
New paravirtualized hardware random number generator device.
Support for Glusterfs volumes with "gluster://" -drive URI
Block job commands for live block commit and storage migration
2012-12-07 13:18:14 -05:00

1047 lines
33 KiB
Diff

From 501ffec04b2b5104ef854624027f0cd769d5d314 Mon Sep 17 00:00:00 2001
Message-Id: <501ffec04b2b5104ef854624027f0cd769d5d314.1354903384.git.crobinso@redhat.com>
In-Reply-To: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
References: <9f0944a25bc1094fa7a74ac9df14e184e2c5c82d.1354903384.git.crobinso@redhat.com>
From: Amit Shah <amit.shah@redhat.com>
Date: Mon, 21 Mar 2011 20:31:45 +0100
Subject: [PATCH] char: Add a QemuChrHandlers struct to initialise chardev
handlers
Instead of passing each handler in the qemu_add_handlers() function,
create a struct of handlers that can be passed to the function instead.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
backends/rng-egd.c | 12 +++++++++---
gdbstub.c | 9 +++++++--
hw/cadence_uart.c | 9 +++++++--
hw/ccid-card-passthru.c | 11 +++++++----
hw/debugcon.c | 2 +-
hw/escc.c | 9 +++++++--
hw/etraxfs_ser.c | 13 +++++++++----
hw/exynos4210_uart.c | 9 +++++++--
hw/grlib_apbuart.c | 12 +++++++-----
hw/imx_serial.c | 9 +++++++--
hw/ivshmem.c | 28 ++++++++++++++++++++++------
hw/lm32_juart.c | 8 +++++++-
hw/lm32_uart.c | 8 +++++++-
hw/mcf_uart.c | 9 +++++++--
hw/milkymist-uart.c | 8 +++++++-
hw/pl011.c | 9 +++++++--
hw/pxa2xx.c | 13 +++++++++----
hw/qdev-properties.c | 2 +-
hw/s390x/sclpconsole.c | 9 +++++++--
hw/serial.c | 11 ++++++++---
hw/sh_serial.c | 12 +++++++++---
hw/spapr_vty.c | 8 ++++++--
hw/strongarm.c | 12 +++++++-----
hw/usb/dev-serial.c | 11 ++++++++---
hw/usb/redirect.c | 9 +++++++--
hw/virtio-console.c | 9 +++++++--
hw/xen_console.c | 16 +++++++++++-----
hw/xilinx_uartlite.c | 11 +++++++++--
monitor.c | 18 ++++++++++++++----
net/slirp.c | 8 ++++++--
qemu-char.c | 32 ++++++++++++++++++++++----------
qemu-char.h | 13 +++++++++----
qtest.c | 9 ++++++++-
33 files changed, 273 insertions(+), 95 deletions(-)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index ad84737..30194be 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -133,6 +133,13 @@ static void rng_egd_cancel_requests(RngBackend *b)
rng_egd_free_requests(s);
}
+static const QemuChrHandlers rng_egd_handlers = {
+ .fd_can_read = rng_egd_chr_can_read,
+ .fd_read = rng_egd_chr_read,
+ .fd_event = NULL,
+};
+
+
static void rng_egd_opened(RngBackend *b, Error **errp)
{
RngEgd *s = RNG_EGD(b);
@@ -150,8 +157,7 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
}
/* 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);
+ qemu_chr_add_handlers(s->chr, &rng_egd_handlers, s);
}
static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
@@ -190,7 +196,7 @@ static void rng_egd_finalize(Object *obj)
RngEgd *s = RNG_EGD(obj);
if (s->chr) {
- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ qemu_chr_add_handlers(s->chr, NULL, NULL);
}
g_free(s->chr_name);
diff --git a/gdbstub.c b/gdbstub.c
index d02ec75..5d93d20 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2973,6 +2973,12 @@ static void gdb_sigterm_handler(int signal)
}
#endif
+static const QemuChrHandlers gdb_handlers = {
+ .fd_can_read = gdb_chr_can_receive,
+ .fd_read = gdb_chr_receive,
+ .fd_event = gdb_chr_event,
+};
+
int gdbserver_start(const char *device)
{
GDBState *s;
@@ -3002,8 +3008,7 @@ int gdbserver_start(const char *device)
if (!chr)
return -1;
- qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
- gdb_chr_event, NULL);
+ qemu_chr_add_handlers(chr, &gdb_handlers, NULL);
}
s = gdbserver_state;
diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
index 686e617..36ad620 100644
--- a/hw/cadence_uart.c
+++ b/hw/cadence_uart.c
@@ -438,6 +438,12 @@ static void cadence_uart_reset(UartState *s)
s->rx_wpos = 0;
}
+static const QemuChrHandlers cadence_uart_handlers = {
+ .fd_can_read = uart_can_receive,
+ .fd_read = uart_receive,
+ .fd_event = uart_event,
+};
+
static int cadence_uart_init(SysBusDevice *dev)
{
UartState *s = FROM_SYSBUS(UartState, dev);
@@ -459,8 +465,7 @@ static int cadence_uart_init(SysBusDevice *dev)
cadence_uart_reset(s);
if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive,
- uart_event, s);
+ qemu_chr_add_handlers(s->chr, &cadence_uart_handlers, s);
}
return 0;
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index bd6c777..fb32107 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -274,6 +274,12 @@ static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
return card->atr;
}
+static const QemuChrHandlers passthru_handlers = {
+ .fd_can_read = ccid_card_vscard_can_read,
+ .fd_read = ccid_card_vscard_read,
+ .fd_event = ccid_card_vscard_event,
+};
+
static int passthru_initfn(CCIDCardState *base)
{
PassthruState *card = DO_UPCAST(PassthruState, base, base);
@@ -282,10 +288,7 @@ static int passthru_initfn(CCIDCardState *base)
card->vscard_in_hdr = 0;
if (card->cs) {
DPRINTF(card, D_INFO, "initing chardev\n");
- qemu_chr_add_handlers(card->cs,
- ccid_card_vscard_can_read,
- ccid_card_vscard_read,
- ccid_card_vscard_event, card);
+ qemu_chr_add_handlers(card->cs, &passthru_handlers, card);
ccid_card_vscard_send_init(card);
} else {
error_report("missing chardev");
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 14ab326..7887fd2 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s)
exit(1);
}
- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
+ qemu_chr_add_handlers(s->chr, NULL, s);
}
static int debugcon_isa_initfn(ISADevice *dev)
diff --git a/hw/escc.c b/hw/escc.c
index a356613..3f26f45 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -867,6 +867,12 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
sysbus_mmio_map(s, 0, base);
}
+static const QemuChrHandlers serial_handlers = {
+ .fd_can_read = serial_can_receive,
+ .fd_read = serial_receive1,
+ .fd_event = serial_event,
+};
+
static int escc_init1(SysBusDevice *dev)
{
SerialState *s = FROM_SYSBUS(SerialState, dev);
@@ -879,8 +885,7 @@ static int escc_init1(SysBusDevice *dev)
s->chn[i].chn = 1 - i;
s->chn[i].clock = s->frequency / 2;
if (s->chn[i].chr) {
- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
- serial_receive1, serial_event, &s->chn[i]);
+ qemu_chr_add_handlers(s->chn[i].chr, &serial_handlers, &s->chn[i]);
}
}
s->chn[0].otherchn = &s->chn[1];
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index ee0d72b..64552cc 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -208,6 +208,12 @@ static void etraxfs_ser_reset(DeviceState *d)
}
+static const QemuChrHandlers serial_handlers = {
+ .fd_can_read = serial_can_receive,
+ .fd_read = serial_receive,
+ .fd_event = serial_event,
+};
+
static int etraxfs_ser_init(SysBusDevice *dev)
{
struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
@@ -217,10 +223,9 @@ static int etraxfs_ser_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
s->chr = qemu_char_get_next_serial();
- if (s->chr)
- qemu_chr_add_handlers(s->chr,
- serial_can_receive, serial_receive,
- serial_event, s);
+ if (s->chr) {
+ qemu_chr_add_handlers(s->chr, &serial_handlers, s);
+ }
return 0;
}
diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
index 20dcd9f..f2949aa 100644
--- a/hw/exynos4210_uart.c
+++ b/hw/exynos4210_uart.c
@@ -625,6 +625,12 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
return dev;
}
+static const QemuChrHandlers exynos4210_handlers = {
+ .fd_can_read = exynos4210_uart_can_receive,
+ .fd_read = exynos4210_uart_receive,
+ .fd_event = exynos4210_uart_event,
+};
+
static int exynos4210_uart_init(SysBusDevice *dev)
{
Exynos4210UartState *s = FROM_SYSBUS(Exynos4210UartState, dev);
@@ -636,8 +642,7 @@ static int exynos4210_uart_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
- qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive,
- exynos4210_uart_receive, exynos4210_uart_event, s);
+ qemu_chr_add_handlers(s->chr, &exynos4210_handlers, s);
return 0;
}
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 0865764..fb0e703 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -222,15 +222,17 @@ static const MemoryRegionOps grlib_apbuart_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static const QemuChrHandlers grlib_handlers = {
+ .fd_can_read = grlib_apbuart_can_receive,
+ .fd_read = grlib_apbuart_receive,
+ .fd_event = grlib_apbuart_event,
+};
+
static int grlib_apbuart_init(SysBusDevice *dev)
{
UART *uart = FROM_SYSBUS(typeof(*uart), dev);
- qemu_chr_add_handlers(uart->chr,
- grlib_apbuart_can_receive,
- grlib_apbuart_receive,
- grlib_apbuart_event,
- uart);
+ qemu_chr_add_handlers(uart->chr, &grlib_handlers, uart);
sysbus_init_irq(dev, &uart->irq);
diff --git a/hw/imx_serial.c b/hw/imx_serial.c
index dcd125f..5347ec8 100644
--- a/hw/imx_serial.c
+++ b/hw/imx_serial.c
@@ -381,6 +381,12 @@ static const struct MemoryRegionOps imx_serial_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static const QemuChrHandlers imx_handlers = {
+ .fd_can_read = imx_can_receive,
+ .fd_read = imx_receive,
+ .fd_event = imx_event,
+};
+
static int imx_serial_init(SysBusDevice *dev)
{
IMXSerialState *s = FROM_SYSBUS(IMXSerialState, dev);
@@ -391,8 +397,7 @@ static int imx_serial_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq);
if (s->chr) {
- qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
- imx_event, s);
+ qemu_chr_add_handlers(s->chr, &imx_handlers, s);
} else {
DPRINTF("No char dev for uart at 0x%lx\n",
(unsigned long)s->iomem.ram_addr);
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index f6dbb21..0e56a97 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -274,6 +274,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) {
msix_notify(pdev, entry->vector);
}
+static const QemuChrHandlers ivshmem_handlers = {
+ .fd_can_read = ivshmem_can_receive,
+ .fd_read = ivshmem_receive,
+ .fd_event = ivshmem_event,
+};
+
+static const QemuChrHandlers ivshmem_msi_handlers = {
+ .fd_can_read = ivshmem_can_receive,
+ .fd_read = fake_irqfd,
+ .fd_event = ivshmem_event,
+};
+
static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n,
int vector)
{
@@ -294,11 +306,10 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *
s->eventfd_table[vector].pdev = &s->dev;
s->eventfd_table[vector].vector = vector;
- qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd,
- ivshmem_event, &s->eventfd_table[vector]);
+ qemu_chr_add_handlers(chr, &ivshmem_msi_handlers,
+ &s->eventfd_table[vector]);
} else {
- qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive,
- ivshmem_event, s);
+ qemu_chr_add_handlers(chr, &ivshmem_handlers, s);
}
return chr;
@@ -632,6 +643,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
msix_write_config(pci_dev, address, val, len);
}
+static const QemuChrHandlers ivshmem_server_handlers = {
+ .fd_can_read = ivshmem_can_receive,
+ .fd_read = ivshmem_read,
+ .fd_event = ivshmem_event,
+};
+
static int pci_ivshmem_init(PCIDevice *dev)
{
IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
@@ -722,8 +739,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
- qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read,
- ivshmem_event, s);
+ qemu_chr_add_handlers(s->server_chr, &ivshmem_server_handlers, s);
} else {
/* just map the file immediately, we're not using a server */
int fd;
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index f07ed39..d4daeb8 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -110,13 +110,19 @@ static void juart_reset(DeviceState *d)
s->jrx = 0;
}
+static const QemuChrHandlers juart_handlers = {
+ .fd_can_read = juart_can_rx,
+ .fd_read = juart_rx,
+ .fd_event = juart_event,
+};
+
static int lm32_juart_init(SysBusDevice *dev)
{
LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev);
s->chr = qemu_char_get_next_serial();
if (s->chr) {
- qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
+ qemu_chr_add_handlers(s->chr, &juart_handlers, s);
}
return 0;
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index adb9287..e581bea 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -243,6 +243,12 @@ static void uart_reset(DeviceState *d)
s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
}
+static const QemuChrHandlers uart_handlers = {
+ .fd_can_read = uart_can_rx,
+ .fd_read = uart_rx,
+ .fd_event = uart_event,
+};
+
static int lm32_uart_init(SysBusDevice *dev)
{
LM32UartState *s = FROM_SYSBUS(typeof(*s), dev);
@@ -254,7 +260,7 @@ static int lm32_uart_init(SysBusDevice *dev)
s->chr = qemu_char_get_next_serial();
if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ qemu_chr_add_handlers(s->chr, &uart_handlers, s);
}
return 0;
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index d1655f8..8ead254 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -272,6 +272,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
mcf_uart_push_byte(s, buf[0]);
}
+static const QemuChrHandlers mcf_uart_handlers = {
+ .fd_can_read = mcf_uart_can_receive,
+ .fd_read = mcf_uart_receive,
+ .fd_event = mcf_uart_event,
+};
+
void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
{
mcf_uart_state *s;
@@ -280,8 +286,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
s->chr = chr;
s->irq = irq;
if (chr) {
- qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
- mcf_uart_event, s);
+ qemu_chr_add_handlers(chr, &mcf_uart_handlers, s);
}
mcf_uart_reset(s);
return s;
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index aefa8c7..0c924f2 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -189,6 +189,12 @@ static void milkymist_uart_reset(DeviceState *d)
s->regs[R_STAT] = STAT_THRE;
}
+static const QemuChrHandlers uart_handlers = {
+ .fd_can_read = uart_can_rx,
+ .fd_read = uart_rx,
+ .fd_event = uart_event,
+};
+
static int milkymist_uart_init(SysBusDevice *dev)
{
MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
@@ -201,7 +207,7 @@ static int milkymist_uart_init(SysBusDevice *dev)
s->chr = qemu_char_get_next_serial();
if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ qemu_chr_add_handlers(s->chr, &uart_handlers, s);
}
return 0;
diff --git a/hw/pl011.c b/hw/pl011.c
index 1f7ce2f..7f44c55 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -261,6 +261,12 @@ static const VMStateDescription vmstate_pl011 = {
}
};
+static const QemuChrHandlers pl011_handlers = {
+ .fd_can_read = pl011_can_receive,
+ .fd_read = pl011_receive,
+ .fd_event = pl011_event,
+};
+
static int pl011_init(SysBusDevice *dev, const unsigned char *id)
{
pl011_state *s = FROM_SYSBUS(pl011_state, dev);
@@ -276,8 +282,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
s->cr = 0x300;
s->flags = 0x90;
if (s->chr) {
- qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
- pl011_event, s);
+ qemu_chr_add_handlers(s->chr, &pl011_handlers, s);
}
vmstate_register(&dev->qdev, -1, &vmstate_pl011, s);
return 0;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index e616979..f9ca062 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1962,6 +1962,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+static const QemuChrHandlers pxa2xx_handlers = {
+ .fd_can_read = pxa2xx_fir_is_empty,
+ .fd_read = pxa2xx_fir_rx,
+ .fd_event = pxa2xx_fir_event,
+};
+
static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
hwaddr base,
qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma,
@@ -1980,10 +1986,9 @@ 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)
- qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
- pxa2xx_fir_rx, pxa2xx_fir_event, s);
-
+ if (chr) {
+ qemu_chr_add_handlers(chr, &pxa2xx_handlers, s);
+ }
register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
pxa2xx_fir_load, s);
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 81d901c..9e2b893 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -550,7 +550,7 @@ static void release_chr(Object *obj, const char *name, void *opaque)
CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
if (*ptr) {
- qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
+ qemu_chr_add_handlers(*ptr, NULL, NULL);
}
}
diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
index 0ec5623..b3d1d6b 100644
--- a/hw/s390x/sclpconsole.c
+++ b/hw/s390x/sclpconsole.c
@@ -240,6 +240,12 @@ static void trigger_ascii_console_data(void *env, int n, int level)
sclp_service_interrupt(0);
}
+static const QemuChrHandlers sclp_chr_handlers = {
+ .fd_can_read = chr_can_read,
+ .fd_read = chr_read,
+ .fd_event = chr_event,
+};
+
/* qemu object creation and initialization functions */
/* tell character layer our call-back functions */
@@ -256,8 +262,7 @@ static int console_init(SCLPEvent *event)
console_available = true;
event->event_type = SCLP_EVENT_ASCII_CONSOLE_DATA;
if (scon->chr) {
- qemu_chr_add_handlers(scon->chr, chr_can_read,
- chr_read, chr_event, scon);
+ qemu_chr_add_handlers(scon->chr, &sclp_chr_handlers, scon);
}
scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
NULL, 1);
diff --git a/hw/serial.c b/hw/serial.c
index 60283ea..9134d01 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -676,6 +676,12 @@ static void serial_reset(void *opaque)
qemu_irq_lower(s->irq);
}
+static const QemuChrHandlers serial_handlers = {
+ .fd_can_read = serial_can_receive1,
+ .fd_read = serial_receive1,
+ .fd_event = serial_event,
+};
+
void serial_init_core(SerialState *s)
{
if (!s->chr) {
@@ -690,13 +696,12 @@ void serial_init_core(SerialState *s)
qemu_register_reset(serial_reset, s);
- qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
- serial_event, s);
+ qemu_chr_add_handlers(s->chr, &serial_handlers, s);
}
void serial_exit_core(SerialState *s)
{
- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ qemu_chr_add_handlers(s->chr, NULL, NULL);
qemu_unregister_reset(serial_reset, s);
}
diff --git a/hw/sh_serial.c b/hw/sh_serial.c
index 9da5d08..260185d 100644
--- a/hw/sh_serial.c
+++ b/hw/sh_serial.c
@@ -352,6 +352,12 @@ static const MemoryRegionOps sh_serial_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static const QemuChrHandlers sh_serial_handlers = {
+ .fd_can_read = sh_serial_can_receive1,
+ .fd_read = sh_serial_receive1,
+ .fd_event = sh_serial_event,
+};
+
void sh_serial_init(MemoryRegion *sysmem,
hwaddr base, int feat,
uint32_t freq, CharDriverState *chr,
@@ -396,9 +402,9 @@ void sh_serial_init(MemoryRegion *sysmem,
s->chr = chr;
- if (chr)
- qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
- sh_serial_event, s);
+ if (chr) {
+ qemu_chr_add_handlers(chr, &sh_serial_handlers, s);
+ }
s->eri = eri_source;
s->rxi = rxi_source;
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 14f862f..9fbe7dd 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -54,6 +54,11 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
qemu_chr_fe_write(dev->chardev, buf, len);
}
+static const QemuChrHandlers vty_handlers = {
+ .fd_can_read = vty_can_receive,
+ .fd_read = vty_receive,
+};
+
static int spapr_vty_init(VIOsPAPRDevice *sdev)
{
VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
@@ -63,8 +68,7 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
exit(1);
}
- qemu_chr_add_handlers(dev->chardev, vty_can_receive,
- vty_receive, NULL, dev);
+ qemu_chr_add_handlers(dev->chardev, &vty_handlers, dev);
return 0;
}
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 4385515..3567218 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1199,6 +1199,12 @@ static const MemoryRegionOps strongarm_uart_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static const QemuChrHandlers strongarm_uart_handlers = {
+ .fd_can_read = strongarm_uart_can_receive,
+ .fd_read = strongarm_uart_receive,
+ .fd_event = strongarm_uart_event,
+};
+
static int strongarm_uart_init(SysBusDevice *dev)
{
StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
@@ -1211,11 +1217,7 @@ static int strongarm_uart_init(SysBusDevice *dev)
s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
if (s->chr) {
- qemu_chr_add_handlers(s->chr,
- strongarm_uart_can_receive,
- strongarm_uart_receive,
- strongarm_uart_event,
- s);
+ qemu_chr_add_handlers(s->chr, &strongarm_uart_handlers, s);
}
return 0;
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 99b19df..7307ad2 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -414,7 +414,7 @@ static void usb_serial_handle_destroy(USBDevice *dev)
{
USBSerialState *s = (USBSerialState *)dev;
- qemu_chr_add_handlers(s->cs, NULL, NULL, NULL, NULL);
+ qemu_chr_add_handlers(s->cs, NULL, NULL);
}
static int usb_serial_can_read(void *opaque)
@@ -478,6 +478,12 @@ static void usb_serial_event(void *opaque, int event)
}
}
+static const QemuChrHandlers usb_serial_handlers = {
+ .fd_can_read = usb_serial_can_read,
+ .fd_read = usb_serial_read,
+ .fd_event = usb_serial_event,
+};
+
static int usb_serial_initfn(USBDevice *dev)
{
USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);
@@ -491,8 +497,7 @@ static int usb_serial_initfn(USBDevice *dev)
return -1;
}
- qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
- usb_serial_event, s);
+ qemu_chr_add_handlers(s->cs, &usb_serial_handlers, s);
usb_serial_handle_reset(dev);
if (s->cs->opened && !dev->attached) {
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 490c90f..c921d2d 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1037,6 +1037,12 @@ static void usbredir_chardev_event(void *opaque, int event)
}
}
+static const QemuChrHandlers usbredir_chr_handlers = {
+ .fd_can_read = usbredir_chardev_can_read,
+ .fd_read = usbredir_chardev_read,
+ .fd_event = usbredir_chardev_event,
+};
+
/*
* init + destroy
*/
@@ -1088,8 +1094,7 @@ static int usbredir_initfn(USBDevice *udev)
/* Let the backend know we are ready */
qemu_chr_fe_open(dev->cs);
- qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
- usbredir_chardev_read, usbredir_chardev_event, dev);
+ qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index cffee3d..066590c 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -106,6 +106,12 @@ static void chr_event(void *opaque, int event)
}
}
+static const QemuChrHandlers chr_handlers = {
+ .fd_can_read = chr_can_read,
+ .fd_read = chr_read,
+ .fd_event = chr_event,
+};
+
static int virtconsole_initfn(VirtIOSerialPort *port)
{
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
@@ -117,8 +123,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
}
if (vcon->chr) {
- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
- vcon);
+ qemu_chr_add_handlers(vcon->chr, &chr_handlers, vcon);
}
return 0;
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 9426d73..e9fcadc 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -211,6 +211,11 @@ out:
return ret;
}
+static const QemuChrHandlers xencons_handlers = {
+ .fd_can_read = xencons_can_receive,
+ .fd_read = xencons_receive,
+};
+
static int con_initialise(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
@@ -231,9 +236,9 @@ 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) {
+ qemu_chr_add_handlers(con->chr, &xencons_handlers, con);
+ }
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
con->ring_ref,
@@ -250,8 +255,9 @@ static void con_disconnect(struct XenDevice *xendev)
if (!xendev->dev) {
return;
}
- if (con->chr)
- qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
+ if (con->chr) {
+ qemu_chr_add_handlers(con->chr, NULL, NULL);
+ }
xen_be_unbind_evtchn(&con->xendev);
if (con->sring) {
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index d20fc41..6605fb1 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -195,6 +195,12 @@ static void uart_event(void *opaque, int event)
}
+static const QemuChrHandlers uart_handlers = {
+ .fd_can_read = uart_can_rx,
+ .fd_read = uart_rx,
+ .fd_event = uart_event,
+};
+
static int xilinx_uartlite_init(SysBusDevice *dev)
{
struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
@@ -207,8 +213,9 @@ static int xilinx_uartlite_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->mmio);
s->chr = qemu_char_get_next_serial();
- if (s->chr)
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ if (s->chr) {
+ qemu_chr_add_handlers(s->chr, &uart_handlers, s);
+ }
return 0;
}
diff --git a/monitor.c b/monitor.c
index c0e32d6..ce0c90a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4685,6 +4685,18 @@ static void sortcmdlist(void)
* End:
*/
+static const QemuChrHandlers monitor_handlers = {
+ .fd_can_read = monitor_can_read,
+ .fd_read = monitor_read,
+ .fd_event = monitor_event,
+};
+
+static const QemuChrHandlers monitor_control_handlers = {
+ .fd_can_read = monitor_can_read,
+ .fd_read = monitor_control_read,
+ .fd_event = monitor_control_event,
+};
+
void monitor_init(CharDriverState *chr, int flags)
{
static int is_first_init = 1;
@@ -4707,14 +4719,12 @@ void monitor_init(CharDriverState *chr, int flags)
if (monitor_ctrl_mode(mon)) {
mon->mc = g_malloc0(sizeof(MonitorControl));
/* Control mode requires special handlers */
- qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
- monitor_control_event, mon);
+ qemu_chr_add_handlers(chr, &monitor_control_handlers, mon);
qemu_chr_fe_set_echo(chr, true);
json_message_parser_init(&mon->mc->parser, handle_qmp_command);
} else {
- qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
- monitor_event, mon);
+ qemu_chr_add_handlers(chr, &monitor_handlers, mon);
}
QLIST_INSERT_HEAD(&mon_list, mon, entry);
diff --git a/net/slirp.c b/net/slirp.c
index afb52c3..07ae92f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -594,6 +594,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
}
+static const QemuChrHandlers guestfwd_handlers = {
+ .fd_can_read = guestfwd_can_read,
+ .fd_read = guestfwd_read,
+};
+
static int slirp_guestfwd(SlirpState *s, const char *config_str,
int legacy_format)
{
@@ -659,8 +664,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
fwd->port = port;
fwd->slirp = s->slirp;
- qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
- NULL, fwd);
+ qemu_chr_add_handlers(fwd->hd, &guestfwd_handlers, fwd);
}
return 0;
diff --git a/qemu-char.c b/qemu-char.c
index 77776dc..97247fb 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -193,19 +193,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
va_end(ap);
}
+static const QemuChrHandlers null_handlers = {
+ /* All handlers are initialised to NULL */
+};
+
void qemu_chr_add_handlers(CharDriverState *s,
- IOCanReadHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque)
+ const QemuChrHandlers *handlers, void *opaque)
{
- if (!opaque && !fd_can_read && !fd_read && !fd_event) {
+ if (!s) {
+ return;
+ }
+ if (!opaque && !handlers) {
/* chr driver being released. */
++s->avail_connections;
}
- s->chr_can_read = fd_can_read;
- s->chr_read = fd_read;
- s->chr_event = fd_event;
+ if (!handlers) {
+ handlers = &null_handlers;
+ }
+ s->chr_can_read = handlers->fd_can_read;
+ s->chr_read = handlers->fd_read;
+ s->chr_event = handlers->fd_event;
s->handler_opaque = opaque;
if (s->chr_update_read_handler)
s->chr_update_read_handler(s);
@@ -443,6 +450,12 @@ static void mux_chr_event(void *opaque, int event)
mux_chr_send_event(d, i, event);
}
+static const QemuChrHandlers mux_chr_handlers = {
+ .fd_can_read = mux_chr_can_read,
+ .fd_read = mux_chr_read,
+ .fd_event = mux_chr_event,
+};
+
static void mux_chr_update_read_handler(CharDriverState *chr)
{
MuxDriver *d = chr->opaque;
@@ -457,8 +470,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
d->chr_event[d->mux_cnt] = chr->chr_event;
/* Fix up the real driver with mux routines */
if (d->mux_cnt == 0) {
- qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
- mux_chr_event, chr);
+ qemu_chr_add_handlers(d->drv, &mux_chr_handlers, chr);
}
if (d->focus != -1) {
mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);
diff --git a/qemu-char.h b/qemu-char.h
index a121e04..ff206cb 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -223,10 +223,15 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
*/
void qemu_chr_be_event(CharDriverState *s, int event);
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanReadHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
+
+typedef struct QemuChrHandlers {
+ IOCanReadHandler *fd_can_read;
+ IOReadHandler *fd_read;
+ IOHandler *fd_write_unblocked;
+ IOEventHandler *fd_event;
+} QemuChrHandlers;
+
+void qemu_chr_add_handlers(CharDriverState *s, const QemuChrHandlers *handlers,
void *opaque);
void qemu_chr_generic_open(CharDriverState *s);
diff --git a/qtest.c b/qtest.c
index fbfab4e..4ab5b69 100644
--- a/qtest.c
+++ b/qtest.c
@@ -416,6 +416,13 @@ static void qtest_event(void *opaque, int event)
}
}
+static const QemuChrHandlers test_handlers = {
+ .fd_can_read = qtest_can_read,
+ .fd_read = qtest_read,
+ .fd_event = qtest_event,
+};
+
+
int qtest_init(void)
{
CharDriverState *chr;
@@ -425,7 +432,7 @@ int qtest_init(void)
configure_icount("0");
chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
- qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
+ qemu_chr_add_handlers(chr, &test_handlers, chr);
qemu_chr_fe_set_echo(chr, true);
inbuf = g_string_new("");
--
1.8.0