diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2016-10-22 12:52:59 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-10-24 15:27:21 +0200 |
commit | fa394ed625731c18f904578903718bf16617fe92 (patch) | |
tree | 224ba9825ba286e3fcffc48394a3a4c1afbc9531 | |
parent | c39860e6dc90f6ee2e82ee078f978c5d7f3df86a (diff) |
char: make some qemu_chr_fe skip if no driver
In most cases, front ends do not care about the side effect of
CharBackend, so we can simply skip the checks and call the qemu_chr_fe
functions even without associated CharDriver.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20161022095318.17775-20-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | hw/arm/pxa2xx.c | 8 | ||||
-rw-r--r-- | hw/arm/strongarm.c | 16 | ||||
-rw-r--r-- | hw/char/bcm2835_aux.c | 18 | ||||
-rw-r--r-- | hw/char/cadence_uart.c | 24 | ||||
-rw-r--r-- | hw/char/digic-uart.c | 14 | ||||
-rw-r--r-- | hw/char/escc.c | 4 | ||||
-rw-r--r-- | hw/char/etraxfs_ser.c | 8 | ||||
-rw-r--r-- | hw/char/imx_serial.c | 26 | ||||
-rw-r--r-- | hw/char/ipoctal232.c | 14 | ||||
-rw-r--r-- | hw/char/lm32_juart.c | 14 | ||||
-rw-r--r-- | hw/char/lm32_uart.c | 14 | ||||
-rw-r--r-- | hw/char/mcf_uart.c | 8 | ||||
-rw-r--r-- | hw/char/milkymist-uart.c | 10 | ||||
-rw-r--r-- | hw/char/pl011.c | 18 | ||||
-rw-r--r-- | hw/char/sclpconsole-lm.c | 6 | ||||
-rw-r--r-- | hw/char/sclpconsole.c | 6 | ||||
-rw-r--r-- | hw/char/stm32f2xx_usart.c | 22 | ||||
-rw-r--r-- | hw/char/virtio-console.c | 6 | ||||
-rw-r--r-- | hw/char/xen_console.c | 6 | ||||
-rw-r--r-- | hw/char/xilinx_uartlite.c | 14 | ||||
-rw-r--r-- | include/sysemu/char.h | 40 | ||||
-rw-r--r-- | qemu-char.c | 50 |
22 files changed, 156 insertions, 190 deletions
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index cd9837914f..c9f4503481 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -1903,7 +1903,7 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr, } else { ch = ~value; } - if (s->chr.chr && s->enable && (s->control[0] & (1 << 3))) { /* TXE */ + if (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); @@ -1975,10 +1975,8 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp) { PXA2xxFIrState *s = PXA2XX_FIR(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty, - pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty, + pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL); } static bool pxa2xx_fir_vmstate_validate(void *opaque, int version_id) diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index fd13a39cf9..370198a889 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -1020,9 +1020,7 @@ 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.chr) { - qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); - } + qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label, speed, parity, data_bits, stop_bits); @@ -1239,13 +1237,11 @@ 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.chr) { - qemu_chr_fe_set_handlers(&s->chr, - strongarm_uart_can_receive, - strongarm_uart_receive, - strongarm_uart_event, - s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, + strongarm_uart_can_receive, + strongarm_uart_receive, + strongarm_uart_event, + s, NULL); } static void strongarm_uart_reset(DeviceState *dev) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index c49ec8ce41..af329aab50 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -79,9 +79,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) s->read_pos = 0; } } - if (s->chr.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); bcm2835_aux_update(s); return c; @@ -168,11 +166,9 @@ 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.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); - } + /* 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); break; case AUX_MU_IER_REG: @@ -282,10 +278,8 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp) { BCM2835AuxState *s = BCM2835_AUX(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, bcm2835_aux_can_receive, - bcm2835_aux_receive, NULL, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, bcm2835_aux_can_receive, + bcm2835_aux_receive, NULL, s, NULL); } static Property bcm2835_aux_props[] = { diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 4459b2d6af..291818e0e1 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -142,9 +142,7 @@ static void uart_rx_reset(CadenceUARTState *s) { s->rx_wpos = 0; s->rx_count = 0; - if (s->chr.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); } static void uart_tx_reset(CadenceUARTState *s) @@ -156,10 +154,8 @@ static void uart_send_breaks(CadenceUARTState *s) { int break_enabled = 1; - if (s->chr.chr) { - qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK, - &break_enabled); - } + qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK, + &break_enabled); } static void uart_parameters_setup(CadenceUARTState *s) @@ -210,9 +206,7 @@ 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.chr) { - qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); - } + qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } static int uart_can_receive(void *opaque) @@ -368,9 +362,7 @@ static void uart_read_rx_fifo(CadenceUARTState *s, uint32_t *c) *c = s->rx_fifo[rx_rpos]; s->rx_count--; - if (s->chr.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); } else { *c = 0; } @@ -474,10 +466,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.chr) { - qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive, - uart_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive, + uart_event, s, NULL); } static void cadence_uart_init(Object *obj) diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c index c7b3db631d..2955e19f67 100644 --- a/hw/char/digic-uart.c +++ b/hw/char/digic-uart.c @@ -76,11 +76,9 @@ static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value, switch (addr) { case R_TX: - 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); - } + /* 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); break; case R_ST: @@ -147,10 +145,8 @@ static void digic_uart_realize(DeviceState *dev, Error **errp) { DigicUartState *s = DIGIC_UART(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, - uart_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, + uart_event, s, NULL); } static void digic_uart_init(Object *obj) diff --git a/hw/char/escc.c b/hw/char/escc.c index 4578a46f10..c71b0a8e56 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -599,9 +599,7 @@ 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.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); return ret; default: break; diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c index d812954345..18c374b95c 100644 --- a/hw/char/etraxfs_ser.c +++ b/hw/char/etraxfs_ser.c @@ -231,11 +231,9 @@ static void etraxfs_ser_realize(DeviceState *dev, Error **errp) { ETRAXSerial *s = ETRAX_SERIAL(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, - serial_can_receive, serial_receive, - serial_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, + serial_can_receive, serial_receive, + serial_event, s, NULL); } static void etraxfs_ser_class_init(ObjectClass *klass, void *data) diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c index d9a0a25d44..8dbb7b26e6 100644 --- a/hw/char/imx_serial.c +++ b/hw/char/imx_serial.c @@ -121,9 +121,7 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset, s->usr2 &= ~USR2_RDR; s->uts1 |= UTS1_RXEMPTY; imx_update(s); - if (s->chr.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); } return c; @@ -182,11 +180,9 @@ static void imx_serial_write(void *opaque, hwaddr offset, case 0x10: /* UTXD */ ch = value; if (s->ucr2 & UCR2_TXEN) { - 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); - } + /* 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); s->usr1 &= ~USR1_TRDY; imx_update(s); s->usr1 |= USR1_TRDY; @@ -215,9 +211,7 @@ static void imx_serial_write(void *opaque, hwaddr offset, } if (value & UCR2_RXEN) { if (!(s->ucr2 & UCR2_RXEN)) { - if (s->chr.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); } } s->ucr2 = value & 0xffff; @@ -319,12 +313,10 @@ static void imx_serial_realize(DeviceState *dev, Error **errp) { IMXSerialState *s = IMX_SERIAL(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive, - imx_event, s, NULL); - } else { - DPRINTF("No char dev for uart\n"); - } + DPRINTF("char dev for uart: %p\n", qemu_chr_fe_get_driver(&s->chr)); + + qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive, + imx_event, s, NULL); } static void imx_serial_init(Object *obj) diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c index d504721a99..6f150e09fb 100644 --- a/hw/char/ipoctal232.c +++ b/hw/char/ipoctal232.c @@ -288,9 +288,7 @@ 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.chr) { - qemu_chr_fe_accept_input(&ch->dev); - } + qemu_chr_fe_accept_input(&ch->dev); } else { ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE; } @@ -357,13 +355,11 @@ static void io_write(IPackDevice *ip, uint8_t addr, uint16_t val) case REG_THRa: case REG_THRb: if (ch->sr & SR_TXRDY) { + uint8_t thr = reg; DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg); - 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); - } + /* 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); } else { DPRINTF("Write THR%c (0x%x), Tx disabled\n", channel + 'a', reg); } diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c index 9629e9e4b7..febb41213f 100644 --- a/hw/char/lm32_juart.c +++ b/hw/char/lm32_juart.c @@ -75,11 +75,9 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx) trace_lm32_juart_set_jtx(s->jtx); s->jtx = jtx; - 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); - } + /* 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); } void lm32_juart_set_jrx(DeviceState *d, uint32_t jtx) @@ -120,10 +118,8 @@ static void lm32_juart_realize(DeviceState *dev, Error **errp) { LM32JuartState *s = LM32_JUART(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx, - juart_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx, + juart_event, s, NULL); } static const VMStateDescription vmstate_lm32_juart = { diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c index e325b917b3..1b2746f487 100644 --- a/hw/char/lm32_uart.c +++ b/hw/char/lm32_uart.c @@ -177,11 +177,9 @@ static void uart_write(void *opaque, hwaddr addr, addr >>= 2; switch (addr) { case R_RXTX: - 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); - } + /* 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); break; case R_IER: case R_LCR: @@ -267,10 +265,8 @@ static void lm32_uart_realize(DeviceState *dev, Error **errp) { LM32UartState *s = LM32_UART(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, - uart_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, + uart_event, s, NULL); } static const VMStateDescription vmstate_lm32_uart = { diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c index b5053431e5..456591ac2f 100644 --- a/hw/char/mcf_uart.c +++ b/hw/char/mcf_uart.c @@ -114,11 +114,9 @@ uint64_t mcf_uart_read(void *opaque, hwaddr addr, static void mcf_uart_do_tx(mcf_uart_state *s) { if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) { - 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, (unsigned char *)&s->tb, 1); - } + /* XXX this blocks entire thread. Rewrite to use + * qemu_chr_fe_write and background I/O callbacks */ + qemu_chr_fe_write_all(&s->chr, (unsigned char *)&s->tb, 1); s->sr |= MCF_UART_TxEMP; } if (s->tx_enabled) { diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c index 0a4c617a7f..dec0a8c8df 100644 --- a/hw/char/milkymist-uart.c +++ b/hw/char/milkymist-uart.c @@ -124,9 +124,7 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value, addr >>= 2; switch (addr) { case R_RXTX: - if (s->chr.chr) { - qemu_chr_fe_write_all(&s->chr, &ch, 1); - } + qemu_chr_fe_write_all(&s->chr, &ch, 1); s->regs[R_STAT] |= STAT_TX_EVT; break; case R_DIV: @@ -200,10 +198,8 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp) { MilkymistUartState *s = MILKYMIST_UART(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, - uart_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, + uart_event, s, NULL); } static void milkymist_uart_init(Object *obj) diff --git a/hw/char/pl011.c b/hw/char/pl011.c index 52ec86658e..900ee5db9f 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -87,9 +87,7 @@ 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.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); r = c; break; case 1: /* UARTRSR */ @@ -168,11 +166,9 @@ static void pl011_write(void *opaque, hwaddr offset, case 0: /* UARTDR */ /* ??? Check if transmitter is enabled. */ ch = value; - 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); - } + /* 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); s->int_level |= PL011_INT_TX; pl011_update(s); break; @@ -332,10 +328,8 @@ static void pl011_realize(DeviceState *dev, Error **errp) { PL011State *s = PL011(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive, - pl011_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive, + pl011_event, s, NULL); } static void pl011_class_init(ObjectClass *oc, void *data) diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c index 0660cbcde4..7191717c7d 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c @@ -312,10 +312,8 @@ static int console_init(SCLPEvent *event) } console_available = true; - if (scon->chr.chr) { - qemu_chr_fe_set_handlers(&scon->chr, chr_can_read, - chr_read, NULL, scon, NULL); - } + qemu_chr_fe_set_handlers(&scon->chr, chr_can_read, + chr_read, NULL, scon, NULL); return 0; } diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 0559208c24..27a60343d8 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -227,10 +227,8 @@ static int console_init(SCLPEvent *event) return -1; } console_available = true; - if (scon->chr.chr) { - qemu_chr_fe_set_handlers(&scon->chr, chr_can_read, - chr_read, NULL, scon, NULL); - } + qemu_chr_fe_set_handlers(&scon->chr, chr_can_read, + chr_read, NULL, scon, NULL); return 0; } diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c index 03ccc52384..8e9852b032 100644 --- a/hw/char/stm32f2xx_usart.c +++ b/hw/char/stm32f2xx_usart.c @@ -97,17 +97,13 @@ 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.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->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.chr) { - qemu_chr_fe_accept_input(&s->chr); - } + qemu_chr_fe_accept_input(&s->chr); qemu_set_irq(s->irq, 0); return s->usart_dr & 0x3FF; case USART_BRR: @@ -152,11 +148,9 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr, case USART_DR: if (value < 0xF000) { ch = value; - 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); - } + /* 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); s->usart_sr |= USART_SR_TC; s->usart_sr &= ~USART_SR_TXE; } @@ -212,10 +206,8 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp) { STM32F2XXUsartState *s = STM32F2XX_USART(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, stm32f2xx_usart_can_receive, - stm32f2xx_usart_receive, NULL, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, stm32f2xx_usart_can_receive, + stm32f2xx_usart_receive, NULL, s, NULL); } static void stm32f2xx_usart_class_init(ObjectClass *klass, void *data) diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index 135f589f54..378c1c1c45 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -108,7 +108,7 @@ 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.chr && !k->is_console) { + if (!k->is_console) { qemu_chr_fe_set_open(&vcon->chr, guest_connected); } @@ -122,9 +122,7 @@ static void guest_writable(VirtIOSerialPort *port) { VirtConsole *vcon = VIRTIO_CONSOLE(port); - if (vcon->chr.chr) { - qemu_chr_fe_accept_input(&vcon->chr); - } + qemu_chr_fe_accept_input(&vcon->chr); } /* Readiness of the guest to accept data on a port */ diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index f664366f7c..785bf8616e 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -244,10 +244,8 @@ static int con_initialise(struct XenDevice *xendev) return -1; xen_be_bind_evtchn(&con->xendev); - if (con->chr.chr) { - qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive, - xencons_receive, NULL, con, NULL); - } + qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive, + xencons_receive, NULL, con, NULL); xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", con->ring_ref, diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c index d6df64335d..c7888f7292 100644 --- a/hw/char/xilinx_uartlite.c +++ b/hw/char/xilinx_uartlite.c @@ -143,11 +143,9 @@ uart_write(void *opaque, hwaddr addr, break; case R_TX: - 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); - } + /* 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); s->regs[addr] = value; /* hax. */ @@ -213,10 +211,8 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp) { XilinxUARTLite *s = XILINX_UARTLITE(dev); - if (s->chr.chr) { - qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, - uart_event, s, NULL); - } + qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, + uart_event, s, NULL); } static void xilinx_uartlite_init(Object *obj) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index b81dbcc33b..2f60a104e8 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -168,6 +168,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename); * @qemu_chr_fe_disconnect: * * Close a fd accpeted by character backend. + * Without associated CharDriver, do nothing. */ void qemu_chr_fe_disconnect(CharBackend *be); @@ -181,7 +182,8 @@ void qemu_chr_cleanup(void); /** * @qemu_chr_fe_wait_connected: * - * Wait for characted backend to be connected. + * Wait for characted backend to be connected, return < 0 on error or + * if no assicated CharDriver. */ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp); @@ -220,6 +222,7 @@ void qemu_chr_free(CharDriverState *chr); * Ask the backend to override its normal echo setting. This only really * applies to the stdio backend and is used by the QMP server such that you * can see what you type if you try to type QMP commands. + * Without associated CharDriver, do nothing. * * @echo true to enable echo, false to disable echo */ @@ -230,13 +233,15 @@ void qemu_chr_fe_set_echo(CharBackend *be, bool echo); * * Set character frontend open status. This is an indication that the * front end is ready (or not) to begin doing I/O. + * Without associated CharDriver, do nothing. */ void qemu_chr_fe_set_open(CharBackend *be, int fe_open); /** * @qemu_chr_fe_event: * - * Send an event from the front end to the back end. + * Send an event from the front end to the back end. It does nothing + * without associated CharDriver. * * @event the event to send */ @@ -245,8 +250,9 @@ void qemu_chr_fe_event(CharBackend *be, int event); /** * @qemu_chr_fe_printf: * - * Write to a character backend using a printf style interface. - * This function is thread-safe. + * Write to a character backend using a printf style interface. This + * function is thread-safe. It does nothing without associated + * CharDriver. * * @fmt see #printf */ @@ -259,7 +265,7 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...) * If the backend is connected, create and add a #GSource that fires * when the given condition (typically G_IO_OUT|G_IO_HUP or G_IO_HUP) * is active; return the #GSource's tag. If it is disconnected, - * return 0. + * or without associated CharDriver, return 0. * * @cond the condition to poll for * @func the function to call when the condition happens @@ -278,7 +284,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, * @buf the data * @len the number of bytes to send * - * Returns: the number of bytes consumed + * Returns: the number of bytes consumed (0 if no assicated CharDriver) */ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len); @@ -293,7 +299,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len); * @buf the data * @len the number of bytes to send * - * Returns: the number of bytes consumed + * Returns: the number of bytes consumed (0 if no assicated CharDriver) */ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len); @@ -305,7 +311,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len); * @buf the data buffer * @len the number of bytes to read * - * Returns: the number of bytes read + * Returns: the number of bytes read (0 if no assicated CharDriver) */ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len); @@ -317,8 +323,9 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len); * @cmd see CHR_IOCTL_* * @arg the data associated with @cmd * - * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the - * return value depends on the semantics of @cmd + * Returns: if @cmd is not supported by the backend or there is no + * associated CharDriver, -ENOTSUP, otherwise the return + * value depends on the semantics of @cmd */ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg); @@ -357,7 +364,7 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num); * result in overwriting the fd array with the new value without being send. * Upon writing the message the fd array is freed. * - * Returns: -1 if fd passing isn't supported. + * Returns: -1 if fd passing isn't supported or no associated CharDriver. */ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num); @@ -418,7 +425,8 @@ bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp); /** * @qemu_chr_fe_get_driver: * - * Returns the driver associated with a CharBackend or NULL. + * Returns the driver associated with a CharBackend or NULL if no + * associated CharDriver. */ CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); @@ -426,6 +434,8 @@ CharDriverState *qemu_chr_fe_get_driver(CharBackend *be); * @qemu_chr_fe_deinit: * * Dissociate the CharBackend from the CharDriver. + * + * Safe to call without associated CharDriver. */ void qemu_chr_fe_deinit(CharBackend *b); @@ -441,6 +451,8 @@ void qemu_chr_fe_deinit(CharBackend *b); * * Set the front end char handlers. The front end takes the focus if * any of the handler is non-NULL. + * + * Without associated CharDriver, nothing is changed. */ void qemu_chr_fe_set_handlers(CharBackend *b, IOCanReadHandler *fd_can_read, @@ -452,7 +464,9 @@ void qemu_chr_fe_set_handlers(CharBackend *b, /** * @qemu_chr_fe_take_focus: * - * Take the focus (if the front end is muxed) + * Take the focus (if the front end is muxed). + * + * Without associated CharDriver, nothing is changed. */ void qemu_chr_fe_take_focus(CharBackend *b); diff --git a/qemu-char.c b/qemu-char.c index e5e80381d7..3bfde82b04 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -273,6 +273,10 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len) CharDriverState *s = be->chr; int ret; + if (!s) { + return 0; + } + if (s->replay && replay_mode == REPLAY_MODE_PLAY) { int offset; replay_char_write_event_load(&ret, &offset); @@ -325,6 +329,10 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len) { CharDriverState *s = be->chr; + if (!s) { + return 0; + } + return qemu_chr_write_all(s, buf, len); } @@ -334,10 +342,10 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len) int offset = 0, counter = 10; int res; - if (!s->chr_sync_read) { + if (!s || !s->chr_sync_read) { return 0; } - + if (s->replay && replay_mode == REPLAY_MODE_PLAY) { return replay_char_read_all_load(buf); } @@ -378,7 +386,8 @@ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg) { CharDriverState *s = be->chr; int res; - if (!s->chr_ioctl || s->replay) { + + if (!s || !s->chr_ioctl || s->replay) { res = -ENOTSUP; } else { res = s->chr_ioctl(s, cmd, arg); @@ -418,7 +427,7 @@ int qemu_chr_fe_get_msgfd(CharBackend *be) CharDriverState *s = be->chr; int fd; int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1; - if (s->replay) { + if (s && s->replay) { fprintf(stderr, "Replay: get msgfd is not supported for serial devices yet\n"); exit(1); @@ -430,6 +439,10 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len) { CharDriverState *s = be->chr; + if (!s) { + return -1; + } + return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1; } @@ -437,6 +450,10 @@ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num) { CharDriverState *s = be->chr; + if (!s) { + return -1; + } + return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1; } @@ -449,6 +466,10 @@ void qemu_chr_fe_accept_input(CharBackend *be) { CharDriverState *s = be->chr; + if (!s) { + return; + } + if (s->chr_accept_input) s->chr_accept_input(s); qemu_notify_event(); @@ -945,6 +966,10 @@ void qemu_chr_fe_set_handlers(CharBackend *b, void qemu_chr_fe_take_focus(CharBackend *b) { + if (!b->chr) { + return; + } + if (b->chr->is_mux) { mux_set_focus(b->chr->opaque, b->tag); } @@ -3347,6 +3372,11 @@ static int qemu_chr_wait_connected(CharDriverState *chr, Error **errp) int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp) { + if (!be->chr) { + error_setg(errp, "missing associated backend"); + return -1; + } + return qemu_chr_wait_connected(be->chr, errp); } @@ -4151,7 +4181,7 @@ void qemu_chr_fe_set_echo(CharBackend *be, bool echo) { CharDriverState *chr = be->chr; - if (chr->chr_set_echo) { + if (chr && chr->chr_set_echo) { chr->chr_set_echo(chr, echo); } } @@ -4160,6 +4190,10 @@ void qemu_chr_fe_set_open(CharBackend *be, int fe_open) { CharDriverState *chr = be->chr; + if (!chr) { + return; + } + if (chr->fe_open == fe_open) { return; } @@ -4173,7 +4207,7 @@ void qemu_chr_fe_event(CharBackend *be, int event) { CharDriverState *chr = be->chr; - if (chr->chr_fe_event) { + if (chr && chr->chr_fe_event) { chr->chr_fe_event(chr, event); } } @@ -4185,7 +4219,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, GSource *src; guint tag; - if (s->chr_add_watch == NULL) { + if (!s || s->chr_add_watch == NULL) { return 0; } @@ -4205,7 +4239,7 @@ void qemu_chr_fe_disconnect(CharBackend *be) { CharDriverState *chr = be->chr; - if (chr->chr_disconnect) { + if (chr && chr->chr_disconnect) { chr->chr_disconnect(chr); } } |