diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2016-10-22 12:52:51 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-10-24 15:27:20 +0200 |
commit | becdfa00cfa2995e859ccefa4b7d72a72eb96581 (patch) | |
tree | 8973236c181dcde0dbcd9fd36d122fc7a4bac6d7 | |
parent | ecb672d14f092f481000ac9cd9d7dc0500692eba (diff) | |
download | qemu-becdfa00cfa2995e859ccefa4b7d72a72eb96581.zip qemu-becdfa00cfa2995e859ccefa4b7d72a72eb96581.tar.gz qemu-becdfa00cfa2995e859ccefa4b7d72a72eb96581.tar.bz2 |
char: replace PROP_CHR with CharBackend
Store the property in a CharBackend instead of CharDriverState*. This
also replace systematically chr by chr.chr to access the
CharDriverState*. The following patches will replace it with calls to
qemu_chr_fe CharBackend functions.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20161022095318.17775-12-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
37 files changed, 302 insertions, 265 deletions
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 9898287..27f112c 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -1764,7 +1764,7 @@ struct PXA2xxFIrState { qemu_irq rx_dma; qemu_irq tx_dma; uint32_t enable; - CharDriverState *chr; + CharBackend chr; uint8_t control[3]; uint8_t status[2]; @@ -1898,14 +1898,16 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr, pxa2xx_fir_update(s); break; case ICDR: - if (s->control[2] & (1 << 2)) /* TXP */ + if (s->control[2] & (1 << 2)) { /* TXP */ ch = value; - else + } else { ch = ~value; - if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */ + } + if (s->chr.chr && s->enable && (s->control[0] & (1 << 3))) { /* TXE */ /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); + } break; case ICSR0: s->status[0] &= ~(value & 0x66); @@ -1973,9 +1975,9 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp) { PXA2xxFIrState *s = PXA2XX_FIR(dev); - if (s->chr) { - qemu_chr_fe_claim_no_fail(s->chr); - qemu_chr_add_handlers(s->chr, pxa2xx_fir_is_empty, + if (s->chr.chr) { + qemu_chr_fe_claim_no_fail(s->chr.chr); + qemu_chr_add_handlers(s->chr.chr, pxa2xx_fir_is_empty, pxa2xx_fir_rx, pxa2xx_fir_event, s); } } diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index 021cbf9..d3e8aff 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -912,7 +912,7 @@ typedef struct StrongARMUARTState { SysBusDevice parent_obj; MemoryRegion iomem; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint8_t utcr0; @@ -1020,8 +1020,8 @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s) ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size; - if (s->chr) { - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + if (s->chr.chr) { + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label, @@ -1107,10 +1107,10 @@ static void strongarm_uart_tx(void *opaque) if (s->utcr3 & UTCR3_LBM) /* loopback */ { strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1); - } else if (s->chr) { + } else if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &s->tx_fifo[s->tx_start], 1); + qemu_chr_fe_write_all(s->chr.chr, &s->tx_fifo[s->tx_start], 1); } s->tx_start = (s->tx_start + 1) % 8; @@ -1239,8 +1239,8 @@ static void strongarm_uart_init(Object *obj) s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s); s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s); - if (s->chr) { - qemu_chr_add_handlers(s->chr, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, strongarm_uart_can_receive, strongarm_uart_receive, strongarm_uart_event, diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index f7a845d..4bc5d02 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -79,8 +79,8 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) s->read_pos = 0; } } - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } bcm2835_aux_update(s); return c; @@ -168,10 +168,10 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, case AUX_MU_IO_REG: /* "DLAB bit set means access baudrate register" is NYI */ ch = value; - if (s->chr) { + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } break; @@ -282,8 +282,8 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp) { BCM2835AuxState *s = BCM2835_AUX(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, bcm2835_aux_can_receive, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, bcm2835_aux_can_receive, bcm2835_aux_receive, NULL, s); } } diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index e3bc52f..d5687dd 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -142,8 +142,8 @@ static void uart_rx_reset(CadenceUARTState *s) { s->rx_wpos = 0; s->rx_count = 0; - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } } @@ -156,8 +156,8 @@ static void uart_send_breaks(CadenceUARTState *s) { int break_enabled = 1; - if (s->chr) { - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK, + if (s->chr.chr) { + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_BREAK, &break_enabled); } } @@ -210,8 +210,8 @@ static void uart_parameters_setup(CadenceUARTState *s) packet_size += ssp.data_bits + ssp.stop_bits; s->char_tx_time = (NANOSECONDS_PER_SECOND / ssp.speed) * packet_size; - if (s->chr) { - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + if (s->chr.chr) { + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } } @@ -278,7 +278,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, int ret; /* instant drain the fifo when there's no back-end */ - if (!s->chr) { + if (!s->chr.chr) { s->tx_count = 0; return FALSE; } @@ -287,7 +287,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, return FALSE; } - ret = qemu_chr_fe_write(s->chr, s->tx_fifo, s->tx_count); + ret = qemu_chr_fe_write(s->chr.chr, s->tx_fifo, s->tx_count); if (ret >= 0) { s->tx_count -= ret; @@ -295,7 +295,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, } if (s->tx_count) { - guint r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + guint r = qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP, cadence_uart_xmit, s); if (!r) { s->tx_count = 0; @@ -368,8 +368,8 @@ static void uart_read_rx_fifo(CadenceUARTState *s, uint32_t *c) *c = s->rx_fifo[rx_rpos]; s->rx_count--; - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } } else { *c = 0; @@ -474,8 +474,8 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp) s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL, fifo_trigger_update, s); - if (s->chr) { - qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, uart_can_receive, uart_receive, uart_event, s); } } diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c index 4402033..b405109 100644 --- a/hw/char/debugcon.c +++ b/hw/char/debugcon.c @@ -39,7 +39,7 @@ typedef struct DebugconState { MemoryRegion io; - CharDriverState *chr; + CharBackend chr; uint32_t readback; } DebugconState; @@ -62,7 +62,7 @@ static void debugcon_ioport_write(void *opaque, hwaddr addr, uint64_t val, /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } @@ -87,12 +87,12 @@ static const MemoryRegionOps debugcon_ops = { static void debugcon_realize_core(DebugconState *s, Error **errp) { - if (!s->chr) { + if (!s->chr.chr) { error_setg(errp, "Can't create debugcon device, empty char device"); return; } - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s); + qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, s); } static void debugcon_isa_realizefn(DeviceState *dev, Error **errp) diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c index e96a9b2..fb4969f 100644 --- a/hw/char/digic-uart.c +++ b/hw/char/digic-uart.c @@ -76,10 +76,10 @@ static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value, switch (addr) { case R_TX: - if (s->chr) { + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } break; @@ -147,8 +147,8 @@ static void digic_uart_realize(DeviceState *dev, Error **errp) { DigicUartState *s = DIGIC_UART(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); } } diff --git a/hw/char/escc.c b/hw/char/escc.c index aa17397..ae69b39 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -88,7 +88,7 @@ typedef struct ChannelState { uint32_t reg; uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS]; SERIOQueue queue; - CharDriverState *chr; + CharBackend chr; int e0_mode, led_mode, caps_lock_mode, num_lock_mode; int disabled; int clock; @@ -416,7 +416,7 @@ static void escc_update_parameters(ChannelState *s) int speed, parity, data_bits, stop_bits; QEMUSerialSetParams ssp; - if (!s->chr || s->type != ser) + if (!s->chr.chr || s->type != ser) return; if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) { @@ -466,7 +466,7 @@ static void escc_update_parameters(ChannelState *s) ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits); - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } static void escc_mem_write(void *opaque, hwaddr addr, @@ -556,11 +556,11 @@ static void escc_mem_write(void *opaque, hwaddr addr, trace_escc_mem_writeb_data(CHN_C(s), val); s->tx = val; if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled - if (s->chr) + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &s->tx, 1); - else if (s->type == kbd && !s->disabled) { + qemu_chr_fe_write_all(s->chr.chr, &s->tx, 1); + } else if (s->type == kbd && !s->disabled) { handle_kbd_command(s, val); } } @@ -599,8 +599,9 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr, else ret = s->rx; trace_escc_mem_readb_data(CHN_C(s), ret); - if (s->chr) - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); + } return ret; default: break; @@ -1013,9 +1014,9 @@ static void escc_realize(DeviceState *dev, Error **errp) ESCC_SIZE << s->it_shift); for (i = 0; i < 2; i++) { - if (s->chn[i].chr) { + if (s->chn[i].chr.chr) { s->chn[i].clock = s->frequency / 2; - qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, + qemu_chr_add_handlers(s->chn[i].chr.chr, serial_can_receive, serial_receive1, serial_event, &s->chn[i]); } } diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c index c99cc5d..99c4801 100644 --- a/hw/char/etraxfs_ser.c +++ b/hw/char/etraxfs_ser.c @@ -53,7 +53,7 @@ typedef struct ETRAXSerial { SysBusDevice parent_obj; MemoryRegion mmio; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; int pending_tx; @@ -128,7 +128,7 @@ ser_write(void *opaque, hwaddr addr, case RW_DOUT: /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); s->regs[R_INTR] |= 3; s->pending_tx = 1; s->regs[addr] = value; @@ -231,8 +231,8 @@ static void etraxfs_ser_realize(DeviceState *dev, Error **errp) { ETRAXSerial *s = ETRAX_SERIAL(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, serial_can_receive, serial_receive, serial_event, s); } diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 66e6304..3f71059 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -181,7 +181,7 @@ typedef struct Exynos4210UartState { Exynos4210UartFIFO rx; Exynos4210UartFIFO tx; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint32_t channel; @@ -346,7 +346,7 @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s) ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n", s->channel, speed, parity, data_bits, stop_bits); @@ -383,13 +383,13 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, break; case UTXH: - if (s->chr) { + if (s->chr.chr) { s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY | UTRSTAT_Tx_BUFFER_EMPTY); ch = (uint8_t)val; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); #if DEBUG_Tx_DATA fprintf(stderr, "%c", ch); #endif @@ -640,7 +640,7 @@ static int exynos4210_uart_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); - qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive, + qemu_chr_add_handlers(s->chr.chr, exynos4210_uart_can_receive, exynos4210_uart_receive, exynos4210_uart_event, s); return 0; diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c index 778148a..13c9455 100644 --- a/hw/char/grlib_apbuart.c +++ b/hw/char/grlib_apbuart.c @@ -78,7 +78,7 @@ typedef struct UART { MemoryRegion iomem; qemu_irq irq; - CharDriverState *chr; + CharBackend chr; /* registers */ uint32_t status; @@ -201,11 +201,11 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr, case DATA_OFFSET: case DATA_OFFSET + 3: /* When only one byte write */ /* Transmit when character device available and transmitter enabled */ - if ((uart->chr) && (uart->control & UART_TRANSMIT_ENABLE)) { + if (uart->chr.chr && (uart->control & UART_TRANSMIT_ENABLE)) { c = value & 0xFF; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(uart->chr, &c, 1); + qemu_chr_fe_write_all(uart->chr.chr, &c, 1); /* Generate interrupt */ if (uart->control & UART_TRANSMIT_INTERRUPT) { qemu_irq_pulse(uart->irq); @@ -242,7 +242,7 @@ static int grlib_apbuart_init(SysBusDevice *dev) { UART *uart = GRLIB_APB_UART(dev); - qemu_chr_add_handlers(uart->chr, + qemu_chr_add_handlers(uart->chr.chr, grlib_apbuart_can_receive, grlib_apbuart_receive, grlib_apbuart_event, diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c index 5c3fa61..5c11de2 100644 --- a/hw/char/imx_serial.c +++ b/hw/char/imx_serial.c @@ -121,8 +121,8 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset, s->usr2 &= ~USR2_RDR; s->uts1 |= UTS1_RXEMPTY; imx_update(s); - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } } return c; @@ -175,16 +175,17 @@ static void imx_serial_write(void *opaque, hwaddr offset, unsigned char ch; DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n", - offset, (unsigned int)value, s->chr ? s->chr->label : "NODEV"); + offset, (unsigned int)value, + s->chr.chr ? s->chr.chr->label : "NODEV"); switch (offset >> 2) { case 0x10: /* UTXD */ ch = value; if (s->ucr2 & UCR2_TXEN) { - if (s->chr) { + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } s->usr1 &= ~USR1_TRDY; imx_update(s); @@ -214,8 +215,8 @@ static void imx_serial_write(void *opaque, hwaddr offset, } if (value & UCR2_RXEN) { if (!(s->ucr2 & UCR2_RXEN)) { - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } } } @@ -318,8 +319,8 @@ static void imx_serial_realize(DeviceState *dev, Error **errp) { IMXSerialState *s = IMX_SERIAL(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, imx_can_receive, imx_receive, imx_event, s); } else { DPRINTF("No char dev for uart\n"); diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c index 2859fdd..0c9dea3 100644 --- a/hw/char/ipoctal232.c +++ b/hw/char/ipoctal232.c @@ -93,7 +93,7 @@ typedef struct SCC2698Block SCC2698Block; struct SCC2698Channel { IPOctalState *ipoctal; - CharDriverState *dev; + CharBackend dev; bool rx_enabled; uint8_t mr[2]; uint8_t mr_idx; @@ -288,8 +288,8 @@ static uint16_t io_read(IPackDevice *ip, uint8_t addr) if (ch->rx_pending == 0) { ch->sr &= ~SR_RXRDY; blk->isr &= ~ISR_RXRDY(channel); - if (ch->dev) { - qemu_chr_accept_input(ch->dev); + if (ch->dev.chr) { + qemu_chr_accept_input(ch->dev.chr); } } else { ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE; @@ -358,11 +358,11 @@ static void io_write(IPackDevice *ip, uint8_t addr, uint16_t val) case REG_THRb: if (ch->sr & SR_TXRDY) { DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg); - if (ch->dev) { + if (ch->dev.chr) { uint8_t thr = reg; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(ch->dev, &thr, 1); + qemu_chr_fe_write_all(ch->dev.chr, &thr, 1); } } else { DPRINTF("Write THR%c (0x%x), Tx disabled\n", channel + 'a', reg); @@ -546,8 +546,8 @@ static void ipoctal_realize(DeviceState *dev, Error **errp) ch->ipoctal = s; /* Redirect IP-Octal channels to host character devices */ - if (ch->dev) { - qemu_chr_add_handlers(ch->dev, hostdev_can_receive, + if (ch->dev.chr) { + qemu_chr_add_handlers(ch->dev.chr, hostdev_can_receive, hostdev_receive, hostdev_event, ch); DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label); } else { diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c index cb1ac76..a0eb312 100644 --- a/hw/char/lm32_juart.c +++ b/hw/char/lm32_juart.c @@ -44,7 +44,7 @@ enum { struct LM32JuartState { SysBusDevice parent_obj; - CharDriverState *chr; + CharBackend chr; uint32_t jtx; uint32_t jrx; @@ -75,10 +75,10 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx) trace_lm32_juart_set_jtx(s->jtx); s->jtx = jtx; - if (s->chr) { + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } } @@ -120,8 +120,9 @@ static void lm32_juart_realize(DeviceState *dev, Error **errp) { LM32JuartState *s = LM32_JUART(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s); + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, juart_can_rx, + juart_rx, juart_event, s); } } diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c index be93697..72fc41c 100644 --- a/hw/char/lm32_uart.c +++ b/hw/char/lm32_uart.c @@ -97,7 +97,7 @@ struct LM32UartState { SysBusDevice parent_obj; MemoryRegion iomem; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint32_t regs[R_MAX]; @@ -142,7 +142,7 @@ static uint64_t uart_read(void *opaque, hwaddr addr, r = s->regs[R_RXTX]; s->regs[R_LSR] &= ~LSR_DR; uart_update_irq(s); - qemu_chr_accept_input(s->chr); + qemu_chr_accept_input(s->chr.chr); break; case R_IIR: case R_LSR: @@ -177,10 +177,10 @@ static void uart_write(void *opaque, hwaddr addr, addr >>= 2; switch (addr) { case R_RXTX: - if (s->chr) { + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } break; case R_IER: @@ -267,8 +267,8 @@ static void lm32_uart_realize(DeviceState *dev, Error **errp) { LM32UartState *s = LM32_UART(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); } } diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c index baddb37..a6518e6 100644 --- a/hw/char/milkymist-uart.c +++ b/hw/char/milkymist-uart.c @@ -61,7 +61,7 @@ struct MilkymistUartState { SysBusDevice parent_obj; MemoryRegion regs_region; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint32_t regs[R_MAX]; @@ -124,8 +124,8 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value, addr >>= 2; switch (addr) { case R_RXTX: - if (s->chr) { - qemu_chr_fe_write_all(s->chr, &ch, 1); + if (s->chr.chr) { + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } s->regs[R_STAT] |= STAT_TX_EVT; break; @@ -138,7 +138,7 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value, case R_STAT: /* write one to clear bits */ s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT)); - qemu_chr_accept_input(s->chr); + qemu_chr_accept_input(s->chr.chr); break; default: @@ -200,8 +200,8 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp) { MilkymistUartState *s = MILKYMIST_UART(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); } } diff --git a/hw/char/parallel.c b/hw/char/parallel.c index da22e36..80576af 100644 --- a/hw/char/parallel.c +++ b/hw/char/parallel.c @@ -74,7 +74,7 @@ typedef struct ParallelState { uint8_t control; qemu_irq irq; int irq_pending; - CharDriverState *chr; + CharBackend chr; int hw_driver; int epp_timeout; uint32_t last_read_offset; /* For debugging */ @@ -131,7 +131,7 @@ parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val) if ((s->control & PARA_CTR_STROBE) == 0) /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &s->dataw, 1); + qemu_chr_fe_write_all(s->chr.chr, &s->dataw, 1); } else { if (s->control & PARA_CTR_INTEN) { s->irq_pending = 1; @@ -161,7 +161,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) if (s->dataw == val) return; pdebug("wd%02x\n", val); - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_WRITE_DATA, &parm); s->dataw = val; break; case PARA_REG_STS: @@ -181,11 +181,11 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) } else { dir = 0; } - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_DATA_DIR, &dir); parm &= ~PARA_CTR_DIR; } - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm); s->control = val; break; case PARA_REG_EPP_ADDR: @@ -194,7 +194,8 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) pdebug("wa%02x s\n", val); else { struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 }; - if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr.chr, + CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) { s->epp_timeout = 1; pdebug("wa%02x t\n", val); } @@ -208,7 +209,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) pdebug("we%02x s\n", val); else { struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 }; - if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) { s->epp_timeout = 1; pdebug("we%02x t\n", val); } @@ -233,7 +234,7 @@ parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val) pdebug("we%04x s\n", val); return; } - err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); + err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); if (err) { s->epp_timeout = 1; pdebug("we%04x t\n", val); @@ -256,7 +257,7 @@ parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val) pdebug("we%08x s\n", val); return; } - err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); + err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); if (err) { s->epp_timeout = 1; pdebug("we%08x t\n", val); @@ -308,13 +309,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) addr &= 7; switch(addr) { case PARA_REG_DATA: - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_DATA, &ret); if (s->last_read_offset != addr || s->datar != ret) pdebug("rd%02x\n", ret); s->datar = ret; break; case PARA_REG_STS: - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_STATUS, &ret); ret &= ~PARA_STS_TMOUT; if (s->epp_timeout) ret |= PARA_STS_TMOUT; @@ -326,7 +327,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) /* s->control has some bits fixed to 1. It is zero only when it has not been yet written to. */ if (s->control == 0) { - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_CONTROL, &ret); if (s->last_read_offset != addr) pdebug("rc%02x\n", ret); s->control = ret; @@ -338,12 +339,14 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) } break; case PARA_REG_EPP_ADDR: - if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) + if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) != + (PARA_CTR_DIR | PARA_CTR_INIT)) /* Controls not correct for EPP addr cycle, so do nothing */ pdebug("ra%02x s\n", ret); else { struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 }; - if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr.chr, + CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) { s->epp_timeout = 1; pdebug("ra%02x t\n", ret); } @@ -352,12 +355,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) } break; case PARA_REG_EPP_DATA: - if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) + if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) != + (PARA_CTR_DIR | PARA_CTR_INIT)) /* Controls not correct for EPP data cycle, so do nothing */ pdebug("re%02x s\n", ret); else { struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 }; - if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) { s->epp_timeout = 1; pdebug("re%02x t\n", ret); } @@ -385,7 +389,7 @@ parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr) pdebug("re%04x s\n", eppdata); return eppdata; } - err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg); + err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_READ, &ioarg); ret = le16_to_cpu(eppdata); if (err) { @@ -412,7 +416,7 @@ parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr) pdebug("re%08x s\n", eppdata); return eppdata; } - err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg); + err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_READ, &ioarg); ret = le32_to_cpu(eppdata); if (err) { @@ -508,7 +512,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp) int base; uint8_t dummy; - if (!s->chr) { + if (!s->chr.chr) { error_setg(errp, "Can't create parallel device, empty char device"); return; } @@ -530,7 +534,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp) isa_init_irq(isadev, &s->irq, isa->isairq); qemu_register_reset(parallel_reset, s); - if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) { + if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) { s->hw_driver = 1; s->status = dummy; } @@ -605,7 +609,7 @@ bool parallel_mm_init(MemoryRegion *address_space, s = g_malloc0(sizeof(ParallelState)); s->irq = irq; - s->chr = chr; + qemu_chr_fe_init(&s->chr, chr, &error_abort); s->it_shift = it_shift; qemu_register_reset(parallel_reset, s); diff --git a/hw/char/pl011.c b/hw/char/pl011.c index 1a7911f..9645195 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -36,7 +36,7 @@ typedef struct PL011State { int read_pos; int read_count; int read_trigger; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; const unsigned char *id; } PL011State; @@ -87,8 +87,8 @@ static uint64_t pl011_read(void *opaque, hwaddr offset, trace_pl011_read_fifo(s->read_count); s->rsr = c >> 8; pl011_update(s); - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } r = c; break; @@ -168,10 +168,11 @@ static void pl011_write(void *opaque, hwaddr offset, case 0: /* UARTDR */ /* ??? Check if transmitter is enabled. */ ch = value; - if (s->chr) + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); + } s->int_level |= PL011_INT_TX; pl011_update(s); break; @@ -331,8 +332,8 @@ static void pl011_realize(DeviceState *dev, Error **errp) { PL011State *s = PL011(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, pl011_can_receive, pl011_receive, pl011_event, s); } } diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c index 9a56326..3ef1517 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c @@ -37,7 +37,7 @@ typedef struct OprtnsCommand { typedef struct SCLPConsoleLM { SCLPEvent event; - CharDriverState *chr; + CharBackend chr; bool echo; /* immediate echo of input if true */ uint32_t write_errors; /* errors writing to char layer */ uint32_t length; /* length of byte stream in buffer */ @@ -91,7 +91,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) if (scon->echo) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(scon->chr, buf, size); + qemu_chr_fe_write_all(scon->chr.chr, buf, size); } } @@ -195,14 +195,14 @@ static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len) { SCLPConsoleLM *scon = SCLPLM_CONSOLE(event); - if (!scon->chr) { + if (!scon->chr.chr) { /* If there's no backend, we can just say we consumed all data. */ return len; } /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - return qemu_chr_fe_write_all(scon->chr, buf, len); + return qemu_chr_fe_write_all(scon->chr.chr, buf, len); } static int process_mdb(SCLPEvent *event, MDBO *mdbo) @@ -312,8 +312,9 @@ static int console_init(SCLPEvent *event) } console_available = true; - if (scon->chr) { - qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon); + if (scon->chr.chr) { + qemu_chr_add_handlers(scon->chr.chr, chr_can_read, + chr_read, NULL, scon); } return 0; diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index a75ad4f..bb51a2c 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -31,7 +31,7 @@ typedef struct ASCIIConsoleData { typedef struct SCLPConsole { SCLPEvent event; - CharDriverState *chr; + CharBackend chr; uint8_t iov[SIZE_BUFFER_VT220]; uint32_t iov_sclp; /* offset in buf for SCLP read operation */ uint32_t iov_bs; /* offset in buf for char layer read operation */ @@ -163,14 +163,14 @@ static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf, { SCLPConsole *scon = SCLP_CONSOLE(event); - if (!scon->chr) { + if (!scon->chr.chr) { /* If there's no backend, we can just say we consumed all data. */ return len; } /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - return qemu_chr_fe_write_all(scon->chr, buf, len); + return qemu_chr_fe_write_all(scon->chr.chr, buf, len); } static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr) @@ -227,8 +227,8 @@ static int console_init(SCLPEvent *event) return -1; } console_available = true; - if (scon->chr) { - qemu_chr_add_handlers(scon->chr, chr_can_read, + if (scon->chr.chr) { + qemu_chr_add_handlers(scon->chr.chr, chr_can_read, chr_read, NULL, scon); } diff --git a/hw/char/serial.c b/hw/char/serial.c index eec72b7..18c7482 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -182,7 +182,7 @@ static void serial_update_parameters(SerialState *s) ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size; - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); DPRINTF("speed=%d parity=%c data=%d stop=%d\n", speed, parity, data_bits, stop_bits); @@ -195,7 +195,8 @@ static void serial_update_msl(SerialState *s) timer_del(s->modem_status_poll); - if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) { + if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_GET_TIOCM, + &flags) == -ENOTSUP) { s->poll_msl = -1; return; } @@ -260,11 +261,12 @@ static void serial_xmit(SerialState *s) if (s->mcr & UART_MCR_LOOP) { /* in loopback mode, say that we just received a char */ serial_receive1(s, &s->tsr, 1); - } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1 && + } else if (qemu_chr_fe_write(s->chr.chr, &s->tsr, 1) != 1 && s->tsr_retry < MAX_XMIT_RETRY) { assert(s->watch_tag == 0); - s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, - serial_watch_cb, s); + s->watch_tag = + qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP, + serial_watch_cb, s); if (s->watch_tag > 0) { s->tsr_retry++; return; @@ -417,7 +419,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, break_enable = (val >> 6) & 1; if (break_enable != s->last_break_enable) { s->last_break_enable = break_enable; - qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK, + qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_BREAK, &break_enable); } } @@ -432,7 +434,8 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, if (s->poll_msl >= 0 && old_mcr != s->mcr) { - qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->chr.chr, + CHR_IOCTL_SERIAL_GET_TIOCM, &flags); flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR); @@ -441,7 +444,8 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, if (val & UART_MCR_DTR) flags |= CHR_TIOCM_DTR; - qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->chr.chr, + CHR_IOCTL_SERIAL_SET_TIOCM, &flags); /* Update the modem status after a one-character-send wait-time, since there may be a response from the device/computer at the other end of the serial line */ timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time); @@ -486,7 +490,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size) serial_update_irq(s); if (!(s->mcr & UART_MCR_LOOP)) { /* in loopback mode, don't receive any data */ - qemu_chr_accept_input(s->chr); + qemu_chr_accept_input(s->chr.chr); } } break; @@ -659,7 +663,7 @@ static int serial_post_load(void *opaque, int version_id) } assert(s->watch_tag == 0); - s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + s->watch_tag = qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP, serial_watch_cb, s); } else { /* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */ @@ -884,7 +888,7 @@ static void serial_reset(void *opaque) void serial_realize_core(SerialState *s, Error **errp) { - if (!s->chr) { + if (!s->chr.chr) { error_setg(errp, "Can't create serial device, empty char device"); return; } @@ -894,7 +898,7 @@ void serial_realize_core(SerialState *s, Error **errp) s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) fifo_timeout_int, s); qemu_register_reset(serial_reset, s); - qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1, + qemu_chr_add_handlers(s->chr.chr, serial_can_receive1, serial_receive1, serial_event, s); fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH); fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH); @@ -903,7 +907,7 @@ void serial_realize_core(SerialState *s, Error **errp) void serial_exit_core(SerialState *s) { - qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL); + qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, NULL); qemu_unregister_reset(serial_reset, s); } @@ -933,7 +937,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, s->irq = irq; s->baudbase = baudbase; - s->chr = chr; + qemu_chr_fe_init(&s->chr, chr, &error_abort); serial_realize_core(s, &error_fatal); vmstate_register(NULL, base, &vmstate_serial, s); @@ -990,7 +994,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space, s->it_shift = it_shift; s->irq = irq; s->baudbase = baudbase; - s->chr = chr; + qemu_chr_fe_init(&s->chr, chr, &error_abort); serial_realize_core(s, &error_fatal); vmstate_register(NULL, base, &vmstate_serial, s); diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 9aeafc0..dcb4a85 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -11,7 +11,7 @@ typedef struct VIOsPAPRVTYDevice { VIOsPAPRDevice sdev; - CharDriverState *chardev; + CharBackend chardev; uint32_t in, out; uint8_t buf[VTERM_BUFSIZE]; } VIOsPAPRVTYDevice; @@ -51,7 +51,7 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max) buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; } - qemu_chr_accept_input(dev->chardev); + qemu_chr_accept_input(dev->chardev.chr); return n; } @@ -62,19 +62,19 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len) /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(dev->chardev, buf, len); + qemu_chr_fe_write_all(dev->chardev.chr, buf, len); } static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp) { VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev); - if (!dev->chardev) { + if (!dev->chardev.chr) { error_setg(errp, "chardev property not set"); return; } - qemu_chr_add_handlers(dev->chardev, vty_can_receive, + qemu_chr_add_handlers(dev->chardev.chr, vty_can_receive, vty_receive, NULL, dev); } diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c index 4c6640d..8cc2737 100644 --- a/hw/char/stm32f2xx_usart.c +++ b/hw/char/stm32f2xx_usart.c @@ -97,16 +97,16 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr, case USART_SR: retvalue = s->usart_sr; s->usart_sr &= ~USART_SR_TC; - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } return retvalue; case USART_DR: DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr); s->usart_sr |= USART_SR_TXE; s->usart_sr &= ~USART_SR_RXNE; - if (s->chr) { - qemu_chr_accept_input(s->chr); + if (s->chr.chr) { + qemu_chr_accept_input(s->chr.chr); } qemu_set_irq(s->irq, 0); return s->usart_dr & 0x3FF; @@ -152,10 +152,10 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr, case USART_DR: if (value < 0xF000) { ch = value; - if (s->chr) { + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); } s->usart_sr |= USART_SR_TC; s->usart_sr &= ~USART_SR_TXE; @@ -212,8 +212,8 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp) { STM32F2XXUsartState *s = STM32F2XX_USART(dev); - if (s->chr) { - qemu_chr_add_handlers(s->chr, stm32f2xx_usart_can_receive, + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, stm32f2xx_usart_can_receive, stm32f2xx_usart_receive, NULL, s); } } diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index d44c18c..a4730ba 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -24,7 +24,7 @@ typedef struct VirtConsole { VirtIOSerialPort parent_obj; - CharDriverState *chr; + CharBackend chr; guint watch; } VirtConsole; @@ -49,12 +49,12 @@ static ssize_t flush_buf(VirtIOSerialPort *port, VirtConsole *vcon = VIRTIO_CONSOLE(port); ssize_t ret; - if (!vcon->chr) { + if (!vcon->chr.chr) { /* If there's no backend, we can just say we consumed all data. */ return len; } - ret = qemu_chr_fe_write(vcon->chr, buf, len); + ret = qemu_chr_fe_write(vcon->chr.chr, buf, len); trace_virtio_console_flush_buf(port->id, len, ret); if (ret < len) { @@ -92,8 +92,8 @@ static ssize_t flush_buf(VirtIOSerialPort *port, if (!k->is_console) { virtio_serial_throttle_port(port, true); if (!vcon->watch) { - vcon->watch = qemu_chr_fe_add_watch(vcon->chr, - G_IO_OUT|G_IO_HUP, + vcon->watch = qemu_chr_fe_add_watch(vcon->chr.chr, + G_IO_OUT | G_IO_HUP, chr_write_unblocked, vcon); } } @@ -108,8 +108,8 @@ static void set_guest_connected(VirtIOSerialPort *port, int guest_connected) DeviceState *dev = DEVICE(port); VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port); - if (vcon->chr && !k->is_console) { - qemu_chr_fe_set_open(vcon->chr, guest_connected); + if (vcon->chr.chr && !k->is_console) { + qemu_chr_fe_set_open(vcon->chr.chr, guest_connected); } if (dev->id) { @@ -122,8 +122,8 @@ static void guest_writable(VirtIOSerialPort *port) { VirtConsole *vcon = VIRTIO_CONSOLE(port); - if (vcon->chr) { - qemu_chr_accept_input(vcon->chr); + if (vcon->chr.chr) { + qemu_chr_accept_input(vcon->chr.chr); } } @@ -177,7 +177,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp) return; } - if (vcon->chr) { + if (vcon->chr.chr) { /* * For consoles we don't block guest data transfer just * because nothing is connected - we'll just let it go @@ -188,13 +188,13 @@ static void virtconsole_realize(DeviceState *dev, Error **errp) * trigger open/close of the device */ if (k->is_console) { - vcon->chr->explicit_fe_open = 0; - qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, + vcon->chr.chr->explicit_fe_open = 0; + qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read, NULL, vcon); virtio_serial_open(port); } else { - vcon->chr->explicit_fe_open = 1; - qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, + vcon->chr.chr->explicit_fe_open = 1; + qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read, chr_event, vcon); } } diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c index 3766dc2..0e809d5 100644 --- a/hw/char/xilinx_uartlite.c +++ b/hw/char/xilinx_uartlite.c @@ -55,7 +55,7 @@ typedef struct XilinxUARTLite { SysBusDevice parent_obj; MemoryRegion mmio; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint8_t rx_fifo[8]; @@ -107,7 +107,7 @@ uart_read(void *opaque, hwaddr addr, unsigned int size) s->rx_fifo_len--; uart_update_status(s); uart_update_irq(s); - qemu_chr_accept_input(s->chr); + qemu_chr_accept_input(s->chr.chr); break; default: @@ -143,11 +143,11 @@ uart_write(void *opaque, hwaddr addr, break; case R_TX: - if (s->chr) + if (s->chr.chr) { /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->chr, &ch, 1); - + qemu_chr_fe_write_all(s->chr.chr, &ch, 1); + } s->regs[addr] = value; /* hax. */ @@ -213,8 +213,9 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp) { XilinxUARTLite *s = XILINX_UARTLITE(dev); - if (s->chr) - qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); + if (s->chr.chr) { + qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); + } } static void xilinx_uartlite_init(Object *obj) diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index e55afe6..6d45d32 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -160,55 +160,71 @@ PropertyInfo qdev_prop_drive = { /* --- character device --- */ -static void parse_chr(DeviceState *dev, const char *str, void **ptr, - const char *propname, Error **errp) +static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque, + Error **errp) { - CharDriverState *chr = qemu_chr_find(str); - if (chr == NULL) { - error_setg(errp, "Property '%s.%s' can't find value '%s'", - object_get_typename(OBJECT(dev)), propname, str); - return; - } - if (qemu_chr_fe_claim(chr) != 0) { - error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", - object_get_typename(OBJECT(dev)), propname, str); - return; - } - *ptr = chr; + DeviceState *dev = DEVICE(obj); + CharBackend *be = qdev_get_prop_ptr(dev, opaque); + char *p; + + p = g_strdup(be->chr && be->chr->label ? be->chr->label : ""); + visit_type_str(v, name, &p, errp); + g_free(p); } -static void release_chr(Object *obj, const char *name, void *opaque) +static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque, + Error **errp) { DeviceState *dev = DEVICE(obj); + Error *local_err = NULL; Property *prop = opaque; - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); - CharDriverState *chr = *ptr; + CharBackend *be = qdev_get_prop_ptr(dev, prop); + CharDriverState *s; + char *str; - if (chr) { - qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(chr); + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; } -} + visit_type_str(v, name, &str, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } -static char *print_chr(void *ptr) -{ - CharDriverState *chr = ptr; - const char *val = chr->label ? chr->label : ""; + if (!*str) { + g_free(str); + be->chr = NULL; + return; + } - return g_strdup(val); -} + s = qemu_chr_find(str); + g_free(str); + if (s == NULL) { + error_setg(errp, "Property '%s.%s' can't find value '%s'", + object_get_typename(obj), prop->name, str); + return; + } + if (qemu_chr_fe_claim(s) != 0) { + error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", + object_get_typename(obj), prop->name, str); + return; + } -static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque, - Error **errp) -{ - get_pointer(obj, v, opaque, print_chr, name, errp); + qemu_chr_fe_init(be, s, errp); } -static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque, - Error **errp) +static void release_chr(Object *obj, const char *name, void *opaque) { - set_pointer(obj, v, opaque, parse_chr, name, errp); + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + CharBackend *be = qdev_get_prop_ptr(dev, prop); + + if (be->chr) { + qemu_chr_fe_set_handlers(be, NULL, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(be->chr); + } } PropertyInfo qdev_prop_chr = { diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index d93e3f3..af9b6f3 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -62,7 +62,7 @@ typedef struct IPMIBmcExtern { IPMIBmc parent; - CharDriverState *chr; + CharBackend chr; bool connected; @@ -105,7 +105,7 @@ static void continue_send(IPMIBmcExtern *ibe) goto check_reset; } send: - ret = qemu_chr_fe_write(ibe->chr, ibe->outbuf + ibe->outpos, + ret = qemu_chr_fe_write(ibe->chr.chr, ibe->outbuf + ibe->outpos, ibe->outlen - ibe->outpos); if (ret > 0) { ibe->outpos += ret; @@ -442,12 +442,12 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp) { IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev); - if (!ibe->chr) { + if (!ibe->chr.chr) { error_setg(errp, "IPMI external bmc requires chardev attribute"); return; } - qemu_chr_add_handlers(ibe->chr, can_receive, receive, chr_event, ibe); + qemu_chr_add_handlers(ibe->chr.chr, can_receive, receive, chr_event, ibe); } static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id) diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index f803dfd..efca8b0 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -88,7 +88,7 @@ typedef struct IVShmemState { /* exactly one of these two may be set */ HostMemoryBackend *hostmem; /* with interrupts */ - CharDriverState *server_chr; /* without interrupts */ + CharBackend server_chr; /* without interrupts */ /* registers */ uint32_t intrmask; @@ -627,7 +627,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) msg = le64_to_cpu(s->msg_buf); s->msg_buffered_bytes = 0; - fd = qemu_chr_fe_get_msgfd(s->server_chr); + fd = qemu_chr_fe_get_msgfd(s->server_chr.chr); process_msg(s, msg, fd, &err); if (err) { @@ -642,7 +642,7 @@ static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp) n = 0; do { - ret = qemu_chr_fe_read_all(s->server_chr, (uint8_t *)&msg + n, + ret = qemu_chr_fe_read_all(s->server_chr.chr, (uint8_t *)&msg + n, sizeof(msg) - n); if (ret < 0 && ret != -EINTR) { error_setg_errno(errp, -ret, "read from server failed"); @@ -651,7 +651,7 @@ static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp) n += ret; } while (n < sizeof(msg)); - *pfd = qemu_chr_fe_get_msgfd(s->server_chr); + *pfd = qemu_chr_fe_get_msgfd(s->server_chr.chr); return msg; } @@ -868,10 +868,10 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem, &error_abort); } else { - assert(s->server_chr); + assert(s->server_chr.chr); IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", - s->server_chr->filename); + s->server_chr.chr->filename); /* we allocate enough space for 16 peers and grow as needed */ resize_peers(s, 16); @@ -893,7 +893,7 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) return; } - qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, + qemu_chr_add_handlers(s->server_chr.chr, ivshmem_can_receive, ivshmem_read, NULL, s); if (ivshmem_setup_interrupts(s) < 0) { @@ -1121,7 +1121,7 @@ static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp) { IVShmemState *s = IVSHMEM_COMMON(dev); - if (!s->server_chr) { + if (!s->server_chr.chr) { error_setg(errp, "You must specify a 'chardev'"); return; } @@ -1250,7 +1250,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp) " or ivshmem-doorbell instead"); } - if (!!s->server_chr + !!s->shmobj != 1) { + if (!!s->server_chr.chr + !!s->shmobj != 1) { error_setg(errp, "You must specify either 'shm' or 'chardev'"); return; } diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c index 2eacea7..ebe3942 100644 --- a/hw/usb/ccid-card-passthru.c +++ b/hw/usb/ccid-card-passthru.c @@ -48,7 +48,7 @@ typedef struct PassthruState PassthruState; struct PassthruState { CCIDCardState base; - CharDriverState *cs; + CharBackend cs; uint8_t vscard_in_data[VSCARD_IN_SIZE]; uint32_t vscard_in_pos; uint32_t vscard_in_hdr; @@ -77,9 +77,9 @@ static void ccid_card_vscard_send_msg(PassthruState *s, scr_msg_header.length = htonl(length); /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->cs, (uint8_t *)&scr_msg_header, + qemu_chr_fe_write_all(s->cs.chr, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader)); - qemu_chr_fe_write_all(s->cs, payload, length); + qemu_chr_fe_write_all(s->cs.chr, payload, length); } static void ccid_card_vscard_send_apdu(PassthruState *s, @@ -264,7 +264,7 @@ static void ccid_card_vscard_handle_message(PassthruState *card, static void ccid_card_vscard_drop_connection(PassthruState *card) { - qemu_chr_delete(card->cs); + qemu_chr_delete(card->cs.chr); card->vscard_in_pos = card->vscard_in_hdr = 0; } @@ -324,7 +324,7 @@ static void passthru_apdu_from_guest( { PassthruState *card = PASSTHRU_CCID_CARD(base); - if (!card->cs) { + if (!card->cs.chr) { printf("ccid-passthru: no chardev, discarding apdu length %d\n", len); return; } @@ -345,9 +345,9 @@ static int passthru_initfn(CCIDCardState *base) card->vscard_in_pos = 0; card->vscard_in_hdr = 0; - if (card->cs) { + if (card->cs.chr) { DPRINTF(card, D_INFO, "initing chardev\n"); - qemu_chr_add_handlers(card->cs, + qemu_chr_add_handlers(card->cs.chr, ccid_card_vscard_can_read, ccid_card_vscard_read, ccid_card_vscard_event, card); diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 61452b5..b8774b4 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -103,7 +103,7 @@ typedef struct { uint8_t event_trigger; QEMUSerialSetParams params; int latency; /* ms */ - CharDriverState *cs; + CharBackend cs; } USBSerialState; #define TYPE_USB_SERIAL "usb-serial-dev" @@ -209,8 +209,10 @@ static uint8_t usb_get_modem_lines(USBSerialState *s) int flags; uint8_t ret; - if (qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) + if (qemu_chr_fe_ioctl(s->cs.chr, + CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) { return FTDI_CTS|FTDI_DSR|FTDI_RLSD; + } ret = 0; if (flags & CHR_TIOCM_CTS) @@ -260,7 +262,7 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p, case DeviceOutVendor | FTDI_SET_MDM_CTRL: { static int flags; - qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_GET_TIOCM, &flags); if (value & FTDI_SET_RTS) { if (value & FTDI_RTS) flags |= CHR_TIOCM_RTS; @@ -273,7 +275,7 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p, else flags &= ~CHR_TIOCM_DTR; } - qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_SET_TIOCM, &flags); break; } case DeviceOutVendor | FTDI_SET_FLOW_CTRL: @@ -292,7 +294,7 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p, divisor = 1; s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8); - qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); + qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); break; } case DeviceOutVendor | FTDI_SET_DATA: @@ -321,7 +323,7 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p, DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP); goto fail; } - qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); + qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); /* TODO: TX ON/OFF */ break; case DeviceInVendor | FTDI_GET_MDM_ST: @@ -368,7 +370,7 @@ static void usb_serial_handle_data(USBDevice *dev, USBPacket *p) iov = p->iov.iov + i; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(s->cs, iov->iov_base, iov->iov_len); + qemu_chr_fe_write_all(s->cs.chr, iov->iov_base, iov->iov_len); } p->actual_length = p->iov.size; break; @@ -488,7 +490,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp) usb_desc_init(dev); dev->auto_attach = 0; - if (!s->cs) { + if (!s->cs.chr) { error_setg(errp, "Property chardev is required"); return; } @@ -499,11 +501,11 @@ static void usb_serial_realize(USBDevice *dev, Error **errp) return; } - qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read, + qemu_chr_add_handlers(s->cs.chr, usb_serial_can_read, usb_serial_read, usb_serial_event, s); usb_serial_handle_reset(dev); - if (s->cs->be_open && !dev->attached) { + if (s->cs.chr->be_open && !dev->attached) { usb_device_attach(dev, &error_abort); } } diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index d4ca026..0b21804 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -105,7 +105,7 @@ struct PacketIdQueue { struct USBRedirDevice { USBDevice dev; /* Properties */ - CharDriverState *cs; + CharBackend cs; uint8_t debug; char *filter_str; int32_t bootindex; @@ -285,7 +285,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count) USBRedirDevice *dev = priv; int r; - if (!dev->cs->be_open) { + if (!dev->cs.chr->be_open) { return 0; } @@ -294,10 +294,10 @@ static int usbredir_write(void *priv, uint8_t *data, int count) return 0; } - r = qemu_chr_fe_write(dev->cs, data, count); + r = qemu_chr_fe_write(dev->cs.chr, data, count); if (r < count) { if (!dev->watch) { - dev->watch = qemu_chr_fe_add_watch(dev->cs, G_IO_OUT|G_IO_HUP, + dev->watch = qemu_chr_fe_add_watch(dev->cs.chr, G_IO_OUT | G_IO_HUP, usbredir_write_unblocked, dev); } if (r < 0) { @@ -1375,7 +1375,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp) USBRedirDevice *dev = USB_REDIRECT(udev); int i; - if (dev->cs == NULL) { + if (dev->cs.chr == NULL) { error_setg(errp, QERR_MISSING_PARAMETER, "chardev"); return; } @@ -1406,7 +1406,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp) dev->compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH; /* Let the backend know we are ready */ - qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, + qemu_chr_add_handlers(dev->cs.chr, usbredir_chardev_can_read, usbredir_chardev_read, usbredir_chardev_event, dev); qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev); @@ -1427,8 +1427,8 @@ static void usbredir_handle_destroy(USBDevice *udev) { USBRedirDevice *dev = USB_REDIRECT(udev); - qemu_chr_delete(dev->cs); - dev->cs = NULL; + qemu_chr_delete(dev->cs.chr); + dev->cs.chr = NULL; /* Note must be done after qemu_chr_close, as that causes a close event */ qemu_bh_delete(dev->chardev_close_bh); qemu_bh_delete(dev->device_reject_bh); diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h index 42f0ee7..6865f15 100644 --- a/include/hw/char/bcm2835_aux.h +++ b/include/hw/char/bcm2835_aux.h @@ -22,7 +22,7 @@ typedef struct { /*< public >*/ MemoryRegion iomem; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN]; diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h index a12773c..ca75eb5 100644 --- a/include/hw/char/cadence_uart.h +++ b/include/hw/char/cadence_uart.h @@ -44,7 +44,7 @@ typedef struct { uint32_t rx_count; uint32_t tx_count; uint64_t char_tx_time; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; QEMUTimer *fifo_trigger_handle; } CadenceUARTState; diff --git a/include/hw/char/digic-uart.h b/include/hw/char/digic-uart.h index 7b3f145..340c8e1 100644 --- a/include/hw/char/digic-uart.h +++ b/include/hw/char/digic-uart.h @@ -19,6 +19,7 @@ #define HW_CHAR_DIGIC_UART_H #include "hw/sysbus.h" +#include "sysemu/char.h" #define TYPE_DIGIC_UART "digic-uart" #define DIGIC_UART(obj) \ @@ -37,7 +38,7 @@ typedef struct DigicUartState { /*< public >*/ MemoryRegion regs_region; - CharDriverState *chr; + CharBackend chr; uint32_t reg_rx; uint32_t reg_st; diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h index 6cd75c0..4cc3fbc 100644 --- a/include/hw/char/imx_serial.h +++ b/include/hw/char/imx_serial.h @@ -19,6 +19,7 @@ #define IMX_SERIAL_H #include "hw/sysbus.h" +#include "sysemu/char.h" #define TYPE_IMX_SERIAL "imx.serial" #define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL) @@ -96,7 +97,7 @@ typedef struct IMXSerialState { uint32_t ucr3; qemu_irq irq; - CharDriverState *chr; + CharBackend chr; } IMXSerialState; #endif diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 4f3b73c..c3312fb 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -30,6 +30,7 @@ #include "sysemu/sysemu.h" #include "exec/memory.h" #include "qemu/fifo8.h" +#include "sysemu/char.h" #define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */ @@ -52,7 +53,7 @@ struct SerialState { it can be reset while reading iir */ int thr_ipending; qemu_irq irq; - CharDriverState *chr; + CharBackend chr; int last_break_enable; int it_shift; int baudbase; diff --git a/include/hw/char/stm32f2xx_usart.h b/include/hw/char/stm32f2xx_usart.h index b97f192..3267523 100644 --- a/include/hw/char/stm32f2xx_usart.h +++ b/include/hw/char/stm32f2xx_usart.h @@ -67,7 +67,7 @@ typedef struct { uint32_t usart_cr3; uint32_t usart_gtpr; - CharDriverState *chr; + CharBackend chr; qemu_irq irq; } STM32F2XXUsartState; #endif /* HW_STM32F2XX_USART_H */ diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 2a9d2f9..306bbab 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -146,7 +146,7 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) #define DEFINE_PROP_CHR(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) + DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend) #define DEFINE_PROP_STRING(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) #define DEFINE_PROP_NETDEV(_n, _s, _f) \ |