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>
This commit is contained in:
Marc-André Lureau 2016-10-22 12:52:51 +03:00 committed by Paolo Bonzini
parent ecb672d14f
commit becdfa00cf
37 changed files with 302 additions and 265 deletions

View File

@ -1764,7 +1764,7 @@ struct PXA2xxFIrState {
qemu_irq rx_dma; qemu_irq rx_dma;
qemu_irq tx_dma; qemu_irq tx_dma;
uint32_t enable; uint32_t enable;
CharDriverState *chr; CharBackend chr;
uint8_t control[3]; uint8_t control[3];
uint8_t status[2]; uint8_t status[2];
@ -1898,14 +1898,16 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
pxa2xx_fir_update(s); pxa2xx_fir_update(s);
break; break;
case ICDR: case ICDR:
if (s->control[2] & (1 << 2)) /* TXP */ if (s->control[2] & (1 << 2)) { /* TXP */
ch = value; ch = value;
else } else {
ch = ~value; 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 /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; break;
case ICSR0: case ICSR0:
s->status[0] &= ~(value & 0x66); s->status[0] &= ~(value & 0x66);
@ -1973,9 +1975,9 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
{ {
PXA2xxFIrState *s = PXA2XX_FIR(dev); PXA2xxFIrState *s = PXA2XX_FIR(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_fe_claim_no_fail(s->chr); qemu_chr_fe_claim_no_fail(s->chr.chr);
qemu_chr_add_handlers(s->chr, pxa2xx_fir_is_empty, qemu_chr_add_handlers(s->chr.chr, pxa2xx_fir_is_empty,
pxa2xx_fir_rx, pxa2xx_fir_event, s); pxa2xx_fir_rx, pxa2xx_fir_event, s);
} }
} }

View File

@ -912,7 +912,7 @@ typedef struct StrongARMUARTState {
SysBusDevice parent_obj; SysBusDevice parent_obj;
MemoryRegion iomem; MemoryRegion iomem;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
uint8_t utcr0; uint8_t utcr0;
@ -1020,8 +1020,8 @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s)
ssp.data_bits = data_bits; ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits; ssp.stop_bits = stop_bits;
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size; s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
if (s->chr) { if (s->chr.chr) {
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(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label, 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 */ { if (s->utcr3 & UTCR3_LBM) /* loopback */ {
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1); 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 /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; 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->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); s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, qemu_chr_add_handlers(s->chr.chr,
strongarm_uart_can_receive, strongarm_uart_can_receive,
strongarm_uart_receive, strongarm_uart_receive,
strongarm_uart_event, strongarm_uart_event,

View File

@ -79,8 +79,8 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
s->read_pos = 0; s->read_pos = 0;
} }
} }
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
bcm2835_aux_update(s); bcm2835_aux_update(s);
return c; return c;
@ -168,10 +168,10 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
case AUX_MU_IO_REG: case AUX_MU_IO_REG:
/* "DLAB bit set means access baudrate register" is NYI */ /* "DLAB bit set means access baudrate register" is NYI */
ch = value; ch = value;
if (s->chr) { if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; break;
@ -282,8 +282,8 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp)
{ {
BCM2835AuxState *s = BCM2835_AUX(dev); BCM2835AuxState *s = BCM2835_AUX(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, bcm2835_aux_can_receive, qemu_chr_add_handlers(s->chr.chr, bcm2835_aux_can_receive,
bcm2835_aux_receive, NULL, s); bcm2835_aux_receive, NULL, s);
} }
} }

View File

@ -142,8 +142,8 @@ static void uart_rx_reset(CadenceUARTState *s)
{ {
s->rx_wpos = 0; s->rx_wpos = 0;
s->rx_count = 0; s->rx_count = 0;
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
} }
@ -156,8 +156,8 @@ static void uart_send_breaks(CadenceUARTState *s)
{ {
int break_enabled = 1; int break_enabled = 1;
if (s->chr) { if (s->chr.chr) {
qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK, qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_BREAK,
&break_enabled); &break_enabled);
} }
} }
@ -210,8 +210,8 @@ static void uart_parameters_setup(CadenceUARTState *s)
packet_size += ssp.data_bits + ssp.stop_bits; packet_size += ssp.data_bits + ssp.stop_bits;
s->char_tx_time = (NANOSECONDS_PER_SECOND / ssp.speed) * packet_size; s->char_tx_time = (NANOSECONDS_PER_SECOND / ssp.speed) * packet_size;
if (s->chr) { if (s->chr.chr) {
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);
} }
} }
@ -278,7 +278,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
int ret; int ret;
/* instant drain the fifo when there's no back-end */ /* instant drain the fifo when there's no back-end */
if (!s->chr) { if (!s->chr.chr) {
s->tx_count = 0; s->tx_count = 0;
return FALSE; return FALSE;
} }
@ -287,7 +287,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
return FALSE; 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) { if (ret >= 0) {
s->tx_count -= ret; s->tx_count -= ret;
@ -295,7 +295,7 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
} }
if (s->tx_count) { 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); cadence_uart_xmit, s);
if (!r) { if (!r) {
s->tx_count = 0; 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]; *c = s->rx_fifo[rx_rpos];
s->rx_count--; s->rx_count--;
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
} else { } else {
*c = 0; *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, s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
fifo_trigger_update, s); fifo_trigger_update, s);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive, qemu_chr_add_handlers(s->chr.chr, uart_can_receive, uart_receive,
uart_event, s); uart_event, s);
} }
} }

View File

@ -39,7 +39,7 @@
typedef struct DebugconState { typedef struct DebugconState {
MemoryRegion io; MemoryRegion io;
CharDriverState *chr; CharBackend chr;
uint32_t readback; uint32_t readback;
} DebugconState; } 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 /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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) 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"); error_setg(errp, "Can't create debugcon device, empty char device");
return; 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) static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)

View File

@ -76,10 +76,10 @@ static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value,
switch (addr) { switch (addr) {
case R_TX: case R_TX:
if (s->chr) { if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; break;
@ -147,8 +147,8 @@ static void digic_uart_realize(DeviceState *dev, Error **errp)
{ {
DigicUartState *s = DIGIC_UART(dev); DigicUartState *s = DIGIC_UART(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
} }
} }

View File

@ -88,7 +88,7 @@ typedef struct ChannelState {
uint32_t reg; uint32_t reg;
uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS]; uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
SERIOQueue queue; SERIOQueue queue;
CharDriverState *chr; CharBackend chr;
int e0_mode, led_mode, caps_lock_mode, num_lock_mode; int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
int disabled; int disabled;
int clock; int clock;
@ -416,7 +416,7 @@ static void escc_update_parameters(ChannelState *s)
int speed, parity, data_bits, stop_bits; int speed, parity, data_bits, stop_bits;
QEMUSerialSetParams ssp; QEMUSerialSetParams ssp;
if (!s->chr || s->type != ser) if (!s->chr.chr || s->type != ser)
return; return;
if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) { if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
@ -466,7 +466,7 @@ static void escc_update_parameters(ChannelState *s)
ssp.data_bits = data_bits; ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits; ssp.stop_bits = stop_bits;
trace_escc_update_parameters(CHN_C(s), speed, parity, data_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, 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); trace_escc_mem_writeb_data(CHN_C(s), val);
s->tx = val; s->tx = val;
if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
if (s->chr) if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(s->chr, &s->tx, 1); qemu_chr_fe_write_all(s->chr.chr, &s->tx, 1);
else if (s->type == kbd && !s->disabled) { } else if (s->type == kbd && !s->disabled) {
handle_kbd_command(s, val); handle_kbd_command(s, val);
} }
} }
@ -599,8 +599,9 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
else else
ret = s->rx; ret = s->rx;
trace_escc_mem_readb_data(CHN_C(s), ret); trace_escc_mem_readb_data(CHN_C(s), ret);
if (s->chr) if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
}
return ret; return ret;
default: default:
break; break;
@ -1013,9 +1014,9 @@ static void escc_realize(DeviceState *dev, Error **errp)
ESCC_SIZE << s->it_shift); ESCC_SIZE << s->it_shift);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (s->chn[i].chr) { if (s->chn[i].chr.chr) {
s->chn[i].clock = s->frequency / 2; 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]); serial_receive1, serial_event, &s->chn[i]);
} }
} }

View File

@ -53,7 +53,7 @@ typedef struct ETRAXSerial {
SysBusDevice parent_obj; SysBusDevice parent_obj;
MemoryRegion mmio; MemoryRegion mmio;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
int pending_tx; int pending_tx;
@ -128,7 +128,7 @@ ser_write(void *opaque, hwaddr addr,
case RW_DOUT: case RW_DOUT:
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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->regs[R_INTR] |= 3;
s->pending_tx = 1; s->pending_tx = 1;
s->regs[addr] = value; s->regs[addr] = value;
@ -231,8 +231,8 @@ static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
{ {
ETRAXSerial *s = ETRAX_SERIAL(dev); ETRAXSerial *s = ETRAX_SERIAL(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, qemu_chr_add_handlers(s->chr.chr,
serial_can_receive, serial_receive, serial_can_receive, serial_receive,
serial_event, s); serial_event, s);
} }

View File

@ -181,7 +181,7 @@ typedef struct Exynos4210UartState {
Exynos4210UartFIFO rx; Exynos4210UartFIFO rx;
Exynos4210UartFIFO tx; Exynos4210UartFIFO tx;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
uint32_t channel; uint32_t channel;
@ -346,7 +346,7 @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
ssp.data_bits = data_bits; ssp.data_bits = data_bits;
ssp.stop_bits = stop_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", PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n",
s->channel, speed, parity, data_bits, stop_bits); s->channel, speed, parity, data_bits, stop_bits);
@ -383,13 +383,13 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset,
break; break;
case UTXH: case UTXH:
if (s->chr) { if (s->chr.chr) {
s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY | s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY |
UTRSTAT_Tx_BUFFER_EMPTY); UTRSTAT_Tx_BUFFER_EMPTY);
ch = (uint8_t)val; ch = (uint8_t)val;
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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 #if DEBUG_Tx_DATA
fprintf(stderr, "%c", ch); fprintf(stderr, "%c", ch);
#endif #endif
@ -640,7 +640,7 @@ static int exynos4210_uart_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq); 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); exynos4210_uart_receive, exynos4210_uart_event, s);
return 0; return 0;

View File

@ -78,7 +78,7 @@ typedef struct UART {
MemoryRegion iomem; MemoryRegion iomem;
qemu_irq irq; qemu_irq irq;
CharDriverState *chr; CharBackend chr;
/* registers */ /* registers */
uint32_t status; uint32_t status;
@ -201,11 +201,11 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr,
case DATA_OFFSET: case DATA_OFFSET:
case DATA_OFFSET + 3: /* When only one byte write */ case DATA_OFFSET + 3: /* When only one byte write */
/* Transmit when character device available and transmitter enabled */ /* 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; c = value & 0xFF;
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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 */ /* Generate interrupt */
if (uart->control & UART_TRANSMIT_INTERRUPT) { if (uart->control & UART_TRANSMIT_INTERRUPT) {
qemu_irq_pulse(uart->irq); qemu_irq_pulse(uart->irq);
@ -242,7 +242,7 @@ static int grlib_apbuart_init(SysBusDevice *dev)
{ {
UART *uart = GRLIB_APB_UART(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_can_receive,
grlib_apbuart_receive, grlib_apbuart_receive,
grlib_apbuart_event, grlib_apbuart_event,

View File

@ -121,8 +121,8 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
s->usr2 &= ~USR2_RDR; s->usr2 &= ~USR2_RDR;
s->uts1 |= UTS1_RXEMPTY; s->uts1 |= UTS1_RXEMPTY;
imx_update(s); imx_update(s);
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
} }
return c; return c;
@ -175,16 +175,17 @@ static void imx_serial_write(void *opaque, hwaddr offset,
unsigned char ch; unsigned char ch;
DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n", 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) { switch (offset >> 2) {
case 0x10: /* UTXD */ case 0x10: /* UTXD */
ch = value; ch = value;
if (s->ucr2 & UCR2_TXEN) { if (s->ucr2 & UCR2_TXEN) {
if (s->chr) { if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; s->usr1 &= ~USR1_TRDY;
imx_update(s); imx_update(s);
@ -214,8 +215,8 @@ static void imx_serial_write(void *opaque, hwaddr offset,
} }
if (value & UCR2_RXEN) { if (value & UCR2_RXEN) {
if (!(s->ucr2 & UCR2_RXEN)) { if (!(s->ucr2 & UCR2_RXEN)) {
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->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); IMXSerialState *s = IMX_SERIAL(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive, qemu_chr_add_handlers(s->chr.chr, imx_can_receive, imx_receive,
imx_event, s); imx_event, s);
} else { } else {
DPRINTF("No char dev for uart\n"); DPRINTF("No char dev for uart\n");

View File

@ -93,7 +93,7 @@ typedef struct SCC2698Block SCC2698Block;
struct SCC2698Channel { struct SCC2698Channel {
IPOctalState *ipoctal; IPOctalState *ipoctal;
CharDriverState *dev; CharBackend dev;
bool rx_enabled; bool rx_enabled;
uint8_t mr[2]; uint8_t mr[2];
uint8_t mr_idx; uint8_t mr_idx;
@ -288,8 +288,8 @@ static uint16_t io_read(IPackDevice *ip, uint8_t addr)
if (ch->rx_pending == 0) { if (ch->rx_pending == 0) {
ch->sr &= ~SR_RXRDY; ch->sr &= ~SR_RXRDY;
blk->isr &= ~ISR_RXRDY(channel); blk->isr &= ~ISR_RXRDY(channel);
if (ch->dev) { if (ch->dev.chr) {
qemu_chr_accept_input(ch->dev); qemu_chr_accept_input(ch->dev.chr);
} }
} else { } else {
ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE; 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: case REG_THRb:
if (ch->sr & SR_TXRDY) { if (ch->sr & SR_TXRDY) {
DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg); DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg);
if (ch->dev) { if (ch->dev.chr) {
uint8_t thr = reg; uint8_t thr = reg;
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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 { } else {
DPRINTF("Write THR%c (0x%x), Tx disabled\n", channel + 'a', reg); 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; ch->ipoctal = s;
/* Redirect IP-Octal channels to host character devices */ /* Redirect IP-Octal channels to host character devices */
if (ch->dev) { if (ch->dev.chr) {
qemu_chr_add_handlers(ch->dev, hostdev_can_receive, qemu_chr_add_handlers(ch->dev.chr, hostdev_can_receive,
hostdev_receive, hostdev_event, ch); hostdev_receive, hostdev_event, ch);
DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label); DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
} else { } else {

View File

@ -44,7 +44,7 @@ enum {
struct LM32JuartState { struct LM32JuartState {
SysBusDevice parent_obj; SysBusDevice parent_obj;
CharDriverState *chr; CharBackend chr;
uint32_t jtx; uint32_t jtx;
uint32_t jrx; uint32_t jrx;
@ -75,10 +75,10 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
trace_lm32_juart_set_jtx(s->jtx); trace_lm32_juart_set_jtx(s->jtx);
s->jtx = jtx; s->jtx = jtx;
if (s->chr) { if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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); LM32JuartState *s = LM32_JUART(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s); qemu_chr_add_handlers(s->chr.chr, juart_can_rx,
juart_rx, juart_event, s);
} }
} }

View File

@ -97,7 +97,7 @@ struct LM32UartState {
SysBusDevice parent_obj; SysBusDevice parent_obj;
MemoryRegion iomem; MemoryRegion iomem;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
uint32_t regs[R_MAX]; uint32_t regs[R_MAX];
@ -142,7 +142,7 @@ static uint64_t uart_read(void *opaque, hwaddr addr,
r = s->regs[R_RXTX]; r = s->regs[R_RXTX];
s->regs[R_LSR] &= ~LSR_DR; s->regs[R_LSR] &= ~LSR_DR;
uart_update_irq(s); uart_update_irq(s);
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
break; break;
case R_IIR: case R_IIR:
case R_LSR: case R_LSR:
@ -177,10 +177,10 @@ static void uart_write(void *opaque, hwaddr addr,
addr >>= 2; addr >>= 2;
switch (addr) { switch (addr) {
case R_RXTX: case R_RXTX:
if (s->chr) { if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; break;
case R_IER: case R_IER:
@ -267,8 +267,8 @@ static void lm32_uart_realize(DeviceState *dev, Error **errp)
{ {
LM32UartState *s = LM32_UART(dev); LM32UartState *s = LM32_UART(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
} }
} }

View File

@ -61,7 +61,7 @@ struct MilkymistUartState {
SysBusDevice parent_obj; SysBusDevice parent_obj;
MemoryRegion regs_region; MemoryRegion regs_region;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
uint32_t regs[R_MAX]; uint32_t regs[R_MAX];
@ -124,8 +124,8 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value,
addr >>= 2; addr >>= 2;
switch (addr) { switch (addr) {
case R_RXTX: case R_RXTX:
if (s->chr) { if (s->chr.chr) {
qemu_chr_fe_write_all(s->chr, &ch, 1); qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
} }
s->regs[R_STAT] |= STAT_TX_EVT; s->regs[R_STAT] |= STAT_TX_EVT;
break; break;
@ -138,7 +138,7 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value,
case R_STAT: case R_STAT:
/* write one to clear bits */ /* write one to clear bits */
s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT)); s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT));
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
break; break;
default: default:
@ -200,8 +200,8 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp)
{ {
MilkymistUartState *s = MILKYMIST_UART(dev); MilkymistUartState *s = MILKYMIST_UART(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
} }
} }

View File

@ -74,7 +74,7 @@ typedef struct ParallelState {
uint8_t control; uint8_t control;
qemu_irq irq; qemu_irq irq;
int irq_pending; int irq_pending;
CharDriverState *chr; CharBackend chr;
int hw_driver; int hw_driver;
int epp_timeout; int epp_timeout;
uint32_t last_read_offset; /* For debugging */ 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) if ((s->control & PARA_CTR_STROBE) == 0)
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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 { } else {
if (s->control & PARA_CTR_INTEN) { if (s->control & PARA_CTR_INTEN) {
s->irq_pending = 1; 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) if (s->dataw == val)
return; return;
pdebug("wd%02x\n", val); 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; s->dataw = val;
break; break;
case PARA_REG_STS: case PARA_REG_STS:
@ -181,11 +181,11 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
} else { } else {
dir = 0; 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; 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; s->control = val;
break; break;
case PARA_REG_EPP_ADDR: 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); pdebug("wa%02x s\n", val);
else { else {
struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 }; 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; s->epp_timeout = 1;
pdebug("wa%02x t\n", val); 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); pdebug("we%02x s\n", val);
else { else {
struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 }; 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; s->epp_timeout = 1;
pdebug("we%02x t\n", val); 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); pdebug("we%04x s\n", val);
return; 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) { if (err) {
s->epp_timeout = 1; s->epp_timeout = 1;
pdebug("we%04x t\n", val); 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); pdebug("we%08x s\n", val);
return; 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) { if (err) {
s->epp_timeout = 1; s->epp_timeout = 1;
pdebug("we%08x t\n", val); pdebug("we%08x t\n", val);
@ -308,13 +309,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
addr &= 7; addr &= 7;
switch(addr) { switch(addr) {
case PARA_REG_DATA: 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) if (s->last_read_offset != addr || s->datar != ret)
pdebug("rd%02x\n", ret); pdebug("rd%02x\n", ret);
s->datar = ret; s->datar = ret;
break; break;
case PARA_REG_STS: 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; ret &= ~PARA_STS_TMOUT;
if (s->epp_timeout) if (s->epp_timeout)
ret |= PARA_STS_TMOUT; 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 /* s->control has some bits fixed to 1. It is zero only when
it has not been yet written to. */ it has not been yet written to. */
if (s->control == 0) { 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) if (s->last_read_offset != addr)
pdebug("rc%02x\n", ret); pdebug("rc%02x\n", ret);
s->control = ret; s->control = ret;
@ -338,12 +339,14 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
} }
break; break;
case PARA_REG_EPP_ADDR: 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 */ /* Controls not correct for EPP addr cycle, so do nothing */
pdebug("ra%02x s\n", ret); pdebug("ra%02x s\n", ret);
else { else {
struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 }; 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; s->epp_timeout = 1;
pdebug("ra%02x t\n", ret); pdebug("ra%02x t\n", ret);
} }
@ -352,12 +355,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
} }
break; break;
case PARA_REG_EPP_DATA: 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 */ /* Controls not correct for EPP data cycle, so do nothing */
pdebug("re%02x s\n", ret); pdebug("re%02x s\n", ret);
else { else {
struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 }; 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; s->epp_timeout = 1;
pdebug("re%02x t\n", ret); 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); pdebug("re%04x s\n", eppdata);
return 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); ret = le16_to_cpu(eppdata);
if (err) { if (err) {
@ -412,7 +416,7 @@ parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
pdebug("re%08x s\n", eppdata); pdebug("re%08x s\n", eppdata);
return 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); ret = le32_to_cpu(eppdata);
if (err) { if (err) {
@ -508,7 +512,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
int base; int base;
uint8_t dummy; uint8_t dummy;
if (!s->chr) { if (!s->chr.chr) {
error_setg(errp, "Can't create parallel device, empty char device"); error_setg(errp, "Can't create parallel device, empty char device");
return; return;
} }
@ -530,7 +534,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
isa_init_irq(isadev, &s->irq, isa->isairq); isa_init_irq(isadev, &s->irq, isa->isairq);
qemu_register_reset(parallel_reset, s); 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->hw_driver = 1;
s->status = dummy; s->status = dummy;
} }
@ -605,7 +609,7 @@ bool parallel_mm_init(MemoryRegion *address_space,
s = g_malloc0(sizeof(ParallelState)); s = g_malloc0(sizeof(ParallelState));
s->irq = irq; s->irq = irq;
s->chr = chr; qemu_chr_fe_init(&s->chr, chr, &error_abort);
s->it_shift = it_shift; s->it_shift = it_shift;
qemu_register_reset(parallel_reset, s); qemu_register_reset(parallel_reset, s);

View File

@ -36,7 +36,7 @@ typedef struct PL011State {
int read_pos; int read_pos;
int read_count; int read_count;
int read_trigger; int read_trigger;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
const unsigned char *id; const unsigned char *id;
} PL011State; } PL011State;
@ -87,8 +87,8 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
trace_pl011_read_fifo(s->read_count); trace_pl011_read_fifo(s->read_count);
s->rsr = c >> 8; s->rsr = c >> 8;
pl011_update(s); pl011_update(s);
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
r = c; r = c;
break; break;
@ -168,10 +168,11 @@ static void pl011_write(void *opaque, hwaddr offset,
case 0: /* UARTDR */ case 0: /* UARTDR */
/* ??? Check if transmitter is enabled. */ /* ??? Check if transmitter is enabled. */
ch = value; ch = value;
if (s->chr) if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; s->int_level |= PL011_INT_TX;
pl011_update(s); pl011_update(s);
break; break;
@ -331,8 +332,8 @@ static void pl011_realize(DeviceState *dev, Error **errp)
{ {
PL011State *s = PL011(dev); PL011State *s = PL011(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, qemu_chr_add_handlers(s->chr.chr, pl011_can_receive, pl011_receive,
pl011_event, s); pl011_event, s);
} }
} }

View File

@ -37,7 +37,7 @@ typedef struct OprtnsCommand {
typedef struct SCLPConsoleLM { typedef struct SCLPConsoleLM {
SCLPEvent event; SCLPEvent event;
CharDriverState *chr; CharBackend chr;
bool echo; /* immediate echo of input if true */ bool echo; /* immediate echo of input if true */
uint32_t write_errors; /* errors writing to char layer */ uint32_t write_errors; /* errors writing to char layer */
uint32_t length; /* length of byte stream in buffer */ 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) { if (scon->echo) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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); 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. */ /* If there's no backend, we can just say we consumed all data. */
return len; return len;
} }
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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) static int process_mdb(SCLPEvent *event, MDBO *mdbo)
@ -312,8 +312,9 @@ static int console_init(SCLPEvent *event)
} }
console_available = true; console_available = true;
if (scon->chr) { if (scon->chr.chr) {
qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon); qemu_chr_add_handlers(scon->chr.chr, chr_can_read,
chr_read, NULL, scon);
} }
return 0; return 0;

View File

@ -31,7 +31,7 @@ typedef struct ASCIIConsoleData {
typedef struct SCLPConsole { typedef struct SCLPConsole {
SCLPEvent event; SCLPEvent event;
CharDriverState *chr; CharBackend chr;
uint8_t iov[SIZE_BUFFER_VT220]; uint8_t iov[SIZE_BUFFER_VT220];
uint32_t iov_sclp; /* offset in buf for SCLP read operation */ uint32_t iov_sclp; /* offset in buf for SCLP read operation */
uint32_t iov_bs; /* offset in buf for char layer 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); 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. */ /* If there's no backend, we can just say we consumed all data. */
return len; return len;
} }
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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) static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
@ -227,8 +227,8 @@ static int console_init(SCLPEvent *event)
return -1; return -1;
} }
console_available = true; console_available = true;
if (scon->chr) { if (scon->chr.chr) {
qemu_chr_add_handlers(scon->chr, chr_can_read, qemu_chr_add_handlers(scon->chr.chr, chr_can_read,
chr_read, NULL, scon); chr_read, NULL, scon);
} }

View File

@ -182,7 +182,7 @@ static void serial_update_parameters(SerialState *s)
ssp.data_bits = data_bits; ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits; ssp.stop_bits = stop_bits;
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size; 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", DPRINTF("speed=%d parity=%c data=%d stop=%d\n",
speed, parity, data_bits, stop_bits); speed, parity, data_bits, stop_bits);
@ -195,7 +195,8 @@ static void serial_update_msl(SerialState *s)
timer_del(s->modem_status_poll); 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; s->poll_msl = -1;
return; return;
} }
@ -260,11 +261,12 @@ static void serial_xmit(SerialState *s)
if (s->mcr & UART_MCR_LOOP) { if (s->mcr & UART_MCR_LOOP) {
/* in loopback mode, say that we just received a char */ /* in loopback mode, say that we just received a char */
serial_receive1(s, &s->tsr, 1); 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) { s->tsr_retry < MAX_XMIT_RETRY) {
assert(s->watch_tag == 0); assert(s->watch_tag == 0);
s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, s->watch_tag =
serial_watch_cb, s); qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP,
serial_watch_cb, s);
if (s->watch_tag > 0) { if (s->watch_tag > 0) {
s->tsr_retry++; s->tsr_retry++;
return; return;
@ -417,7 +419,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
break_enable = (val >> 6) & 1; break_enable = (val >> 6) & 1;
if (break_enable != s->last_break_enable) { if (break_enable != s->last_break_enable) {
s->last_break_enable = 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); &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) { 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); 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) if (val & UART_MCR_DTR)
flags |= CHR_TIOCM_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 /* 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 */ 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); 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); serial_update_irq(s);
if (!(s->mcr & UART_MCR_LOOP)) { if (!(s->mcr & UART_MCR_LOOP)) {
/* in loopback mode, don't receive any data */ /* in loopback mode, don't receive any data */
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
} }
break; break;
@ -659,7 +663,7 @@ static int serial_post_load(void *opaque, int version_id)
} }
assert(s->watch_tag == 0); 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); serial_watch_cb, s);
} else { } else {
/* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */ /* 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) 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"); error_setg(errp, "Can't create serial device, empty char device");
return; 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); s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) fifo_timeout_int, s);
qemu_register_reset(serial_reset, 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); serial_event, s);
fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH); fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
fifo8_create(&s->xmit_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) 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); qemu_unregister_reset(serial_reset, s);
} }
@ -933,7 +937,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
s->irq = irq; s->irq = irq;
s->baudbase = baudbase; s->baudbase = baudbase;
s->chr = chr; qemu_chr_fe_init(&s->chr, chr, &error_abort);
serial_realize_core(s, &error_fatal); serial_realize_core(s, &error_fatal);
vmstate_register(NULL, base, &vmstate_serial, s); vmstate_register(NULL, base, &vmstate_serial, s);
@ -990,7 +994,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
s->it_shift = it_shift; s->it_shift = it_shift;
s->irq = irq; s->irq = irq;
s->baudbase = baudbase; s->baudbase = baudbase;
s->chr = chr; qemu_chr_fe_init(&s->chr, chr, &error_abort);
serial_realize_core(s, &error_fatal); serial_realize_core(s, &error_fatal);
vmstate_register(NULL, base, &vmstate_serial, s); vmstate_register(NULL, base, &vmstate_serial, s);

View File

@ -11,7 +11,7 @@
typedef struct VIOsPAPRVTYDevice { typedef struct VIOsPAPRVTYDevice {
VIOsPAPRDevice sdev; VIOsPAPRDevice sdev;
CharDriverState *chardev; CharBackend chardev;
uint32_t in, out; uint32_t in, out;
uint8_t buf[VTERM_BUFSIZE]; uint8_t buf[VTERM_BUFSIZE];
} VIOsPAPRVTYDevice; } VIOsPAPRVTYDevice;
@ -51,7 +51,7 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
} }
qemu_chr_accept_input(dev->chardev); qemu_chr_accept_input(dev->chardev.chr);
return n; return n;
} }
@ -62,19 +62,19 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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) static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
{ {
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev); VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
if (!dev->chardev) { if (!dev->chardev.chr) {
error_setg(errp, "chardev property not set"); error_setg(errp, "chardev property not set");
return; return;
} }
qemu_chr_add_handlers(dev->chardev, vty_can_receive, qemu_chr_add_handlers(dev->chardev.chr, vty_can_receive,
vty_receive, NULL, dev); vty_receive, NULL, dev);
} }

View File

@ -97,16 +97,16 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
case USART_SR: case USART_SR:
retvalue = s->usart_sr; retvalue = s->usart_sr;
s->usart_sr &= ~USART_SR_TC; s->usart_sr &= ~USART_SR_TC;
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
return retvalue; return retvalue;
case USART_DR: case USART_DR:
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->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_TXE;
s->usart_sr &= ~USART_SR_RXNE; s->usart_sr &= ~USART_SR_RXNE;
if (s->chr) { if (s->chr.chr) {
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
} }
qemu_set_irq(s->irq, 0); qemu_set_irq(s->irq, 0);
return s->usart_dr & 0x3FF; return s->usart_dr & 0x3FF;
@ -152,10 +152,10 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
case USART_DR: case USART_DR:
if (value < 0xF000) { if (value < 0xF000) {
ch = value; ch = value;
if (s->chr) { if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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_TC;
s->usart_sr &= ~USART_SR_TXE; s->usart_sr &= ~USART_SR_TXE;
@ -212,8 +212,8 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp)
{ {
STM32F2XXUsartState *s = STM32F2XX_USART(dev); STM32F2XXUsartState *s = STM32F2XX_USART(dev);
if (s->chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, stm32f2xx_usart_can_receive, qemu_chr_add_handlers(s->chr.chr, stm32f2xx_usart_can_receive,
stm32f2xx_usart_receive, NULL, s); stm32f2xx_usart_receive, NULL, s);
} }
} }

View File

@ -24,7 +24,7 @@
typedef struct VirtConsole { typedef struct VirtConsole {
VirtIOSerialPort parent_obj; VirtIOSerialPort parent_obj;
CharDriverState *chr; CharBackend chr;
guint watch; guint watch;
} VirtConsole; } VirtConsole;
@ -49,12 +49,12 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
VirtConsole *vcon = VIRTIO_CONSOLE(port); VirtConsole *vcon = VIRTIO_CONSOLE(port);
ssize_t ret; ssize_t ret;
if (!vcon->chr) { if (!vcon->chr.chr) {
/* If there's no backend, we can just say we consumed all data. */ /* If there's no backend, we can just say we consumed all data. */
return len; 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); trace_virtio_console_flush_buf(port->id, len, ret);
if (ret < len) { if (ret < len) {
@ -92,8 +92,8 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
if (!k->is_console) { if (!k->is_console) {
virtio_serial_throttle_port(port, true); virtio_serial_throttle_port(port, true);
if (!vcon->watch) { if (!vcon->watch) {
vcon->watch = qemu_chr_fe_add_watch(vcon->chr, vcon->watch = qemu_chr_fe_add_watch(vcon->chr.chr,
G_IO_OUT|G_IO_HUP, G_IO_OUT | G_IO_HUP,
chr_write_unblocked, vcon); chr_write_unblocked, vcon);
} }
} }
@ -108,8 +108,8 @@ static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
DeviceState *dev = DEVICE(port); DeviceState *dev = DEVICE(port);
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port); VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
if (vcon->chr && !k->is_console) { if (vcon->chr.chr && !k->is_console) {
qemu_chr_fe_set_open(vcon->chr, guest_connected); qemu_chr_fe_set_open(vcon->chr.chr, guest_connected);
} }
if (dev->id) { if (dev->id) {
@ -122,8 +122,8 @@ static void guest_writable(VirtIOSerialPort *port)
{ {
VirtConsole *vcon = VIRTIO_CONSOLE(port); VirtConsole *vcon = VIRTIO_CONSOLE(port);
if (vcon->chr) { if (vcon->chr.chr) {
qemu_chr_accept_input(vcon->chr); qemu_chr_accept_input(vcon->chr.chr);
} }
} }
@ -177,7 +177,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
return; return;
} }
if (vcon->chr) { if (vcon->chr.chr) {
/* /*
* For consoles we don't block guest data transfer just * For consoles we don't block guest data transfer just
* because nothing is connected - we'll just let it go * 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 * trigger open/close of the device
*/ */
if (k->is_console) { if (k->is_console) {
vcon->chr->explicit_fe_open = 0; vcon->chr.chr->explicit_fe_open = 0;
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read,
NULL, vcon); NULL, vcon);
virtio_serial_open(port); virtio_serial_open(port);
} else { } else {
vcon->chr->explicit_fe_open = 1; vcon->chr.chr->explicit_fe_open = 1;
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read,
chr_event, vcon); chr_event, vcon);
} }
} }

View File

@ -55,7 +55,7 @@ typedef struct XilinxUARTLite {
SysBusDevice parent_obj; SysBusDevice parent_obj;
MemoryRegion mmio; MemoryRegion mmio;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
uint8_t rx_fifo[8]; uint8_t rx_fifo[8];
@ -107,7 +107,7 @@ uart_read(void *opaque, hwaddr addr, unsigned int size)
s->rx_fifo_len--; s->rx_fifo_len--;
uart_update_status(s); uart_update_status(s);
uart_update_irq(s); uart_update_irq(s);
qemu_chr_accept_input(s->chr); qemu_chr_accept_input(s->chr.chr);
break; break;
default: default:
@ -143,11 +143,11 @@ uart_write(void *opaque, hwaddr addr,
break; break;
case R_TX: case R_TX:
if (s->chr) if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; s->regs[addr] = value;
/* hax. */ /* hax. */
@ -213,8 +213,9 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp)
{ {
XilinxUARTLite *s = XILINX_UARTLITE(dev); XilinxUARTLite *s = XILINX_UARTLITE(dev);
if (s->chr) if (s->chr.chr) {
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
}
} }
static void xilinx_uartlite_init(Object *obj) static void xilinx_uartlite_init(Object *obj)

View File

@ -160,57 +160,73 @@ PropertyInfo qdev_prop_drive = {
/* --- character device --- */ /* --- character device --- */
static void parse_chr(DeviceState *dev, const char *str, void **ptr, static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
const char *propname, Error **errp) Error **errp)
{ {
CharDriverState *chr = qemu_chr_find(str); DeviceState *dev = DEVICE(obj);
if (chr == NULL) { 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 set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
DeviceState *dev = DEVICE(obj);
Error *local_err = NULL;
Property *prop = opaque;
CharBackend *be = qdev_get_prop_ptr(dev, prop);
CharDriverState *s;
char *str;
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;
}
if (!*str) {
g_free(str);
be->chr = NULL;
return;
}
s = qemu_chr_find(str);
g_free(str);
if (s == NULL) {
error_setg(errp, "Property '%s.%s' can't find value '%s'", error_setg(errp, "Property '%s.%s' can't find value '%s'",
object_get_typename(OBJECT(dev)), propname, str); object_get_typename(obj), prop->name, str);
return; return;
} }
if (qemu_chr_fe_claim(chr) != 0) { if (qemu_chr_fe_claim(s) != 0) {
error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
object_get_typename(OBJECT(dev)), propname, str); object_get_typename(obj), prop->name, str);
return; return;
} }
*ptr = chr;
qemu_chr_fe_init(be, s, errp);
} }
static void release_chr(Object *obj, const char *name, void *opaque) static void release_chr(Object *obj, const char *name, void *opaque)
{ {
DeviceState *dev = DEVICE(obj); DeviceState *dev = DEVICE(obj);
Property *prop = opaque; Property *prop = opaque;
CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); CharBackend *be = qdev_get_prop_ptr(dev, prop);
CharDriverState *chr = *ptr;
if (chr) { if (be->chr) {
qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(be, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(chr); qemu_chr_fe_release(be->chr);
} }
} }
static char *print_chr(void *ptr)
{
CharDriverState *chr = ptr;
const char *val = chr->label ? chr->label : "";
return g_strdup(val);
}
static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
get_pointer(obj, v, opaque, print_chr, name, errp);
}
static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
set_pointer(obj, v, opaque, parse_chr, name, errp);
}
PropertyInfo qdev_prop_chr = { PropertyInfo qdev_prop_chr = {
.name = "str", .name = "str",
.description = "ID of a chardev to use as a backend", .description = "ID of a chardev to use as a backend",

View File

@ -62,7 +62,7 @@
typedef struct IPMIBmcExtern { typedef struct IPMIBmcExtern {
IPMIBmc parent; IPMIBmc parent;
CharDriverState *chr; CharBackend chr;
bool connected; bool connected;
@ -105,7 +105,7 @@ static void continue_send(IPMIBmcExtern *ibe)
goto check_reset; goto check_reset;
} }
send: 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); ibe->outlen - ibe->outpos);
if (ret > 0) { if (ret > 0) {
ibe->outpos += ret; ibe->outpos += ret;
@ -442,12 +442,12 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
{ {
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev); IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
if (!ibe->chr) { if (!ibe->chr.chr) {
error_setg(errp, "IPMI external bmc requires chardev attribute"); error_setg(errp, "IPMI external bmc requires chardev attribute");
return; 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) static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)

View File

@ -88,7 +88,7 @@ typedef struct IVShmemState {
/* exactly one of these two may be set */ /* exactly one of these two may be set */
HostMemoryBackend *hostmem; /* with interrupts */ HostMemoryBackend *hostmem; /* with interrupts */
CharDriverState *server_chr; /* without interrupts */ CharBackend server_chr; /* without interrupts */
/* registers */ /* registers */
uint32_t intrmask; 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); msg = le64_to_cpu(s->msg_buf);
s->msg_buffered_bytes = 0; 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); process_msg(s, msg, fd, &err);
if (err) { if (err) {
@ -642,7 +642,7 @@ static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp)
n = 0; n = 0;
do { 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); sizeof(msg) - n);
if (ret < 0 && ret != -EINTR) { if (ret < 0 && ret != -EINTR) {
error_setg_errno(errp, -ret, "read from server failed"); 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; n += ret;
} while (n < sizeof(msg)); } 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; 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, s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem,
&error_abort); &error_abort);
} else { } else {
assert(s->server_chr); assert(s->server_chr.chr);
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", 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 */ /* we allocate enough space for 16 peers and grow as needed */
resize_peers(s, 16); resize_peers(s, 16);
@ -893,7 +893,7 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
return; 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); ivshmem_read, NULL, s);
if (ivshmem_setup_interrupts(s) < 0) { if (ivshmem_setup_interrupts(s) < 0) {
@ -1121,7 +1121,7 @@ static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)
{ {
IVShmemState *s = IVSHMEM_COMMON(dev); IVShmemState *s = IVSHMEM_COMMON(dev);
if (!s->server_chr) { if (!s->server_chr.chr) {
error_setg(errp, "You must specify a 'chardev'"); error_setg(errp, "You must specify a 'chardev'");
return; return;
} }
@ -1250,7 +1250,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
" or ivshmem-doorbell instead"); " 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'"); error_setg(errp, "You must specify either 'shm' or 'chardev'");
return; return;
} }

View File

@ -48,7 +48,7 @@ typedef struct PassthruState PassthruState;
struct PassthruState { struct PassthruState {
CCIDCardState base; CCIDCardState base;
CharDriverState *cs; CharBackend cs;
uint8_t vscard_in_data[VSCARD_IN_SIZE]; uint8_t vscard_in_data[VSCARD_IN_SIZE];
uint32_t vscard_in_pos; uint32_t vscard_in_pos;
uint32_t vscard_in_hdr; uint32_t vscard_in_hdr;
@ -77,9 +77,9 @@ static void ccid_card_vscard_send_msg(PassthruState *s,
scr_msg_header.length = htonl(length); scr_msg_header.length = htonl(length);
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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)); 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, 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) 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; 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); PassthruState *card = PASSTHRU_CCID_CARD(base);
if (!card->cs) { if (!card->cs.chr) {
printf("ccid-passthru: no chardev, discarding apdu length %d\n", len); printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
return; return;
} }
@ -345,9 +345,9 @@ static int passthru_initfn(CCIDCardState *base)
card->vscard_in_pos = 0; card->vscard_in_pos = 0;
card->vscard_in_hdr = 0; card->vscard_in_hdr = 0;
if (card->cs) { if (card->cs.chr) {
DPRINTF(card, D_INFO, "initing chardev\n"); 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_can_read,
ccid_card_vscard_read, ccid_card_vscard_read,
ccid_card_vscard_event, card); ccid_card_vscard_event, card);

View File

@ -103,7 +103,7 @@ typedef struct {
uint8_t event_trigger; uint8_t event_trigger;
QEMUSerialSetParams params; QEMUSerialSetParams params;
int latency; /* ms */ int latency; /* ms */
CharDriverState *cs; CharBackend cs;
} USBSerialState; } USBSerialState;
#define TYPE_USB_SERIAL "usb-serial-dev" #define TYPE_USB_SERIAL "usb-serial-dev"
@ -209,8 +209,10 @@ static uint8_t usb_get_modem_lines(USBSerialState *s)
int flags; int flags;
uint8_t ret; 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; return FTDI_CTS|FTDI_DSR|FTDI_RLSD;
}
ret = 0; ret = 0;
if (flags & CHR_TIOCM_CTS) 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: case DeviceOutVendor | FTDI_SET_MDM_CTRL:
{ {
static int flags; 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_SET_RTS) {
if (value & FTDI_RTS) if (value & FTDI_RTS)
flags |= CHR_TIOCM_RTS; flags |= CHR_TIOCM_RTS;
@ -273,7 +275,7 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p,
else else
flags &= ~CHR_TIOCM_DTR; 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; break;
} }
case DeviceOutVendor | FTDI_SET_FLOW_CTRL: case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
@ -292,7 +294,7 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p,
divisor = 1; divisor = 1;
s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8); 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; break;
} }
case DeviceOutVendor | FTDI_SET_DATA: 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); DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
goto fail; 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 */ /* TODO: TX ON/OFF */
break; break;
case DeviceInVendor | FTDI_GET_MDM_ST: 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; iov = p->iov.iov + i;
/* XXX this blocks entire thread. Rewrite to use /* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */ * 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; p->actual_length = p->iov.size;
break; break;
@ -488,7 +490,7 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
usb_desc_init(dev); usb_desc_init(dev);
dev->auto_attach = 0; dev->auto_attach = 0;
if (!s->cs) { if (!s->cs.chr) {
error_setg(errp, "Property chardev is required"); error_setg(errp, "Property chardev is required");
return; return;
} }
@ -499,11 +501,11 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
return; 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_event, s);
usb_serial_handle_reset(dev); 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); usb_device_attach(dev, &error_abort);
} }
} }

View File

@ -105,7 +105,7 @@ struct PacketIdQueue {
struct USBRedirDevice { struct USBRedirDevice {
USBDevice dev; USBDevice dev;
/* Properties */ /* Properties */
CharDriverState *cs; CharBackend cs;
uint8_t debug; uint8_t debug;
char *filter_str; char *filter_str;
int32_t bootindex; int32_t bootindex;
@ -285,7 +285,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
USBRedirDevice *dev = priv; USBRedirDevice *dev = priv;
int r; int r;
if (!dev->cs->be_open) { if (!dev->cs.chr->be_open) {
return 0; return 0;
} }
@ -294,10 +294,10 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
return 0; 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 (r < count) {
if (!dev->watch) { 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); usbredir_write_unblocked, dev);
} }
if (r < 0) { if (r < 0) {
@ -1375,7 +1375,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
USBRedirDevice *dev = USB_REDIRECT(udev); USBRedirDevice *dev = USB_REDIRECT(udev);
int i; int i;
if (dev->cs == NULL) { if (dev->cs.chr == NULL) {
error_setg(errp, QERR_MISSING_PARAMETER, "chardev"); error_setg(errp, QERR_MISSING_PARAMETER, "chardev");
return; return;
} }
@ -1406,7 +1406,7 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
dev->compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH; dev->compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH;
/* Let the backend know we are ready */ /* 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); usbredir_chardev_read, usbredir_chardev_event, dev);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, 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); USBRedirDevice *dev = USB_REDIRECT(udev);
qemu_chr_delete(dev->cs); qemu_chr_delete(dev->cs.chr);
dev->cs = NULL; dev->cs.chr = NULL;
/* Note must be done after qemu_chr_close, as that causes a close event */ /* 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->chardev_close_bh);
qemu_bh_delete(dev->device_reject_bh); qemu_bh_delete(dev->device_reject_bh);

View File

@ -22,7 +22,7 @@ typedef struct {
/*< public >*/ /*< public >*/
MemoryRegion iomem; MemoryRegion iomem;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN]; uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN];

View File

@ -44,7 +44,7 @@ typedef struct {
uint32_t rx_count; uint32_t rx_count;
uint32_t tx_count; uint32_t tx_count;
uint64_t char_tx_time; uint64_t char_tx_time;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
QEMUTimer *fifo_trigger_handle; QEMUTimer *fifo_trigger_handle;
} CadenceUARTState; } CadenceUARTState;

View File

@ -19,6 +19,7 @@
#define HW_CHAR_DIGIC_UART_H #define HW_CHAR_DIGIC_UART_H
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "sysemu/char.h"
#define TYPE_DIGIC_UART "digic-uart" #define TYPE_DIGIC_UART "digic-uart"
#define DIGIC_UART(obj) \ #define DIGIC_UART(obj) \
@ -37,7 +38,7 @@ typedef struct DigicUartState {
/*< public >*/ /*< public >*/
MemoryRegion regs_region; MemoryRegion regs_region;
CharDriverState *chr; CharBackend chr;
uint32_t reg_rx; uint32_t reg_rx;
uint32_t reg_st; uint32_t reg_st;

View File

@ -19,6 +19,7 @@
#define IMX_SERIAL_H #define IMX_SERIAL_H
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "sysemu/char.h"
#define TYPE_IMX_SERIAL "imx.serial" #define TYPE_IMX_SERIAL "imx.serial"
#define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL) #define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL)
@ -96,7 +97,7 @@ typedef struct IMXSerialState {
uint32_t ucr3; uint32_t ucr3;
qemu_irq irq; qemu_irq irq;
CharDriverState *chr; CharBackend chr;
} IMXSerialState; } IMXSerialState;
#endif #endif

View File

@ -30,6 +30,7 @@
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "exec/memory.h" #include "exec/memory.h"
#include "qemu/fifo8.h" #include "qemu/fifo8.h"
#include "sysemu/char.h"
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */ #define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
@ -52,7 +53,7 @@ struct SerialState {
it can be reset while reading iir */ it can be reset while reading iir */
int thr_ipending; int thr_ipending;
qemu_irq irq; qemu_irq irq;
CharDriverState *chr; CharBackend chr;
int last_break_enable; int last_break_enable;
int it_shift; int it_shift;
int baudbase; int baudbase;

View File

@ -67,7 +67,7 @@ typedef struct {
uint32_t usart_cr3; uint32_t usart_cr3;
uint32_t usart_gtpr; uint32_t usart_gtpr;
CharDriverState *chr; CharBackend chr;
qemu_irq irq; qemu_irq irq;
} STM32F2XXUsartState; } STM32F2XXUsartState;
#endif /* HW_STM32F2XX_USART_H */ #endif /* HW_STM32F2XX_USART_H */

View File

@ -146,7 +146,7 @@ extern PropertyInfo qdev_prop_arraylen;
DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*)
#define DEFINE_PROP_CHR(_n, _s, _f) \ #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 DEFINE_PROP_STRING(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
#define DEFINE_PROP_NETDEV(_n, _s, _f) \ #define DEFINE_PROP_NETDEV(_n, _s, _f) \