char: use qemu_chr_fe* functions with CharBackend argument

This also switches from qemu_chr_add_handlers() to
qemu_chr_fe_set_handlers(). Note that qemu_chr_fe_set_handlers() now
takes the focus when fe_open (qemu_chr_add_handlers() did take the
focus)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20161022095318.17775-16-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
master
Marc-André Lureau 2016-10-22 12:52:55 +03:00 committed by Paolo Bonzini
parent fbf3cc3a67
commit 5345fdb446
47 changed files with 437 additions and 409 deletions

View File

@ -42,7 +42,7 @@ static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
/* 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.chr, header, sizeof(header)); qemu_chr_fe_write_all(&s->chr, header, sizeof(header));
size -= len; size -= len;
} }
@ -109,8 +109,8 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
} }
/* FIXME we should resubmit pending requests when the CDS reconnects. */ /* FIXME we should resubmit pending requests when the CDS reconnects. */
qemu_chr_add_handlers(s->chr.chr, rng_egd_chr_can_read, qemu_chr_fe_set_handlers(&s->chr, rng_egd_chr_can_read,
rng_egd_chr_read, NULL, s); rng_egd_chr_read, NULL, s, NULL);
} }
static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp) static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
@ -129,9 +129,10 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
static char *rng_egd_get_chardev(Object *obj, Error **errp) static char *rng_egd_get_chardev(Object *obj, Error **errp)
{ {
RngEgd *s = RNG_EGD(obj); RngEgd *s = RNG_EGD(obj);
CharDriverState *chr = qemu_chr_fe_get_driver(&s->chr);
if (s->chr.chr && s->chr.chr->label) { if (chr && chr->label) {
return g_strdup(s->chr.chr->label); return g_strdup(chr->label);
} }
return NULL; return NULL;
@ -149,7 +150,7 @@ static void rng_egd_finalize(Object *obj)
RngEgd *s = RNG_EGD(obj); RngEgd *s = RNG_EGD(obj);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(s->chr.chr); qemu_chr_fe_release(s->chr.chr);
} }

View File

@ -404,7 +404,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len)
#else #else
/* 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.chr, buf, len); qemu_chr_fe_write_all(&s->chr, buf, len);
#endif #endif
} }
@ -1471,6 +1471,9 @@ void gdb_exit(CPUArchState *env, int code)
{ {
GDBState *s; GDBState *s;
char buf[4]; char buf[4];
#ifndef CONFIG_USER_ONLY
CharDriverState *chr;
#endif
s = gdbserver_state; s = gdbserver_state;
if (!s) { if (!s) {
@ -1481,7 +1484,8 @@ void gdb_exit(CPUArchState *env, int code)
return; return;
} }
#else #else
if (!s->chr.chr) { chr = qemu_chr_fe_get_driver(&s->chr);
if (!chr) {
return; return;
} }
#endif #endif
@ -1490,7 +1494,7 @@ void gdb_exit(CPUArchState *env, int code)
put_packet(s, buf); put_packet(s, buf);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
qemu_chr_delete(s->chr.chr); qemu_chr_delete(chr);
#endif #endif
} }
@ -1764,8 +1768,8 @@ int gdbserver_start(const char *device)
mon_chr->chr_write = gdb_monitor_write; mon_chr->chr_write = gdb_monitor_write;
monitor_init(mon_chr, 0); monitor_init(mon_chr, 0);
} else { } else {
if (s->chr.chr) { if (qemu_chr_fe_get_driver(&s->chr)) {
qemu_chr_delete(s->chr.chr); qemu_chr_delete(qemu_chr_fe_get_driver(&s->chr));
} }
mon_chr = s->mon_chr; mon_chr = s->mon_chr;
memset(s, 0, sizeof(GDBState)); memset(s, 0, sizeof(GDBState));
@ -1775,8 +1779,8 @@ int gdbserver_start(const char *device)
s->g_cpu = first_cpu; s->g_cpu = first_cpu;
if (chr) { if (chr) {
qemu_chr_fe_init(&s->chr, chr, &error_abort); qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_add_handlers(s->chr.chr, gdb_chr_can_receive, gdb_chr_receive, qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,
gdb_chr_event, NULL); gdb_chr_event, NULL, NULL);
} }
s->state = chr ? RS_IDLE : RS_INACTIVE; s->state = chr ? RS_IDLE : RS_INACTIVE;
s->mon_chr = mon_chr; s->mon_chr = mon_chr;

View File

@ -771,14 +771,15 @@ static void omap_sti_fifo_write(void *opaque, hwaddr addr,
/* Flush channel <i>value</i>. */ /* Flush channel <i>value</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->chr.chr, (const uint8_t *) "\r", 1); qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\r", 1);
} else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) { } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
if (value == 0xc0 || value == 0xc3) { if (value == 0xc0 || value == 0xc3) {
/* Open channel <i>ch</i>. */ /* Open channel <i>ch</i>. */
} else if (value == 0x00) } else if (value == 0x00) {
qemu_chr_fe_write_all(s->chr.chr, (const uint8_t *) "\n", 1); qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\n", 1);
else } else {
qemu_chr_fe_write_all(s->chr.chr, &byte, 1); qemu_chr_fe_write_all(&s->chr, &byte, 1);
}
} }
} }

View File

@ -1906,7 +1906,7 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
break; break;
case ICSR0: case ICSR0:
@ -1977,8 +1977,8 @@ static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_claim_no_fail(s->chr.chr); qemu_chr_fe_claim_no_fail(s->chr.chr);
qemu_chr_add_handlers(s->chr.chr, pxa2xx_fir_is_empty, qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty,
pxa2xx_fir_rx, pxa2xx_fir_event, s); pxa2xx_fir_rx, pxa2xx_fir_event, s, NULL);
} }
} }

View File

@ -1021,7 +1021,7 @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s)
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.chr) { if (s->chr.chr) {
qemu_chr_fe_ioctl(s->chr.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, 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.chr) { } else if (qemu_chr_fe_get_driver(&s->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.chr, &s->tx_fifo[s->tx_start], 1); qemu_chr_fe_write_all(&s->chr, &s->tx_fifo[s->tx_start], 1);
} }
s->tx_start = (s->tx_start + 1) % 8; s->tx_start = (s->tx_start + 1) % 8;
@ -1240,11 +1240,11 @@ static void strongarm_uart_init(Object *obj)
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.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, qemu_chr_fe_set_handlers(&s->chr,
strongarm_uart_can_receive, strongarm_uart_can_receive,
strongarm_uart_receive, strongarm_uart_receive,
strongarm_uart_event, strongarm_uart_event,
s); s, NULL);
} }
} }

View File

@ -80,7 +80,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
} }
} }
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
bcm2835_aux_update(s); bcm2835_aux_update(s);
return c; return c;
@ -171,7 +171,7 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
break; break;
@ -283,8 +283,8 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp)
BCM2835AuxState *s = BCM2835_AUX(dev); BCM2835AuxState *s = BCM2835_AUX(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, bcm2835_aux_can_receive, qemu_chr_fe_set_handlers(&s->chr, bcm2835_aux_can_receive,
bcm2835_aux_receive, NULL, s); bcm2835_aux_receive, NULL, s, NULL);
} }
} }

View File

@ -143,7 +143,7 @@ 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.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
} }
@ -157,8 +157,8 @@ static void uart_send_breaks(CadenceUARTState *s)
int break_enabled = 1; int break_enabled = 1;
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_BREAK, qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
&break_enabled); &break_enabled);
} }
} }
@ -211,7 +211,7 @@ 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.chr) { if (s->chr.chr) {
qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); qemu_chr_fe_ioctl(&s->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.chr) { if (!qemu_chr_fe_get_driver(&s->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.chr, s->tx_fifo, s->tx_count); ret = qemu_chr_fe_write(&s->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.chr, G_IO_OUT | G_IO_HUP, guint r = qemu_chr_fe_add_watch(&s->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;
@ -369,7 +369,7 @@ static void uart_read_rx_fifo(CadenceUARTState *s, uint32_t *c)
s->rx_count--; s->rx_count--;
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
} else { } else {
*c = 0; *c = 0;
@ -475,8 +475,8 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
fifo_trigger_update, s); fifo_trigger_update, s);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, uart_can_receive, uart_receive, qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
uart_event, s); uart_event, s, NULL);
} }
} }

View File

@ -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.chr, &ch, 1); qemu_chr_fe_write_all(&s->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.chr) { if (!qemu_chr_fe_get_driver(&s->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.chr, NULL, NULL, NULL, s); qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, s, NULL);
} }
static void debugcon_isa_realizefn(DeviceState *dev, Error **errp) static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)

View File

@ -79,7 +79,7 @@ static void digic_uart_write(void *opaque, hwaddr addr, uint64_t value,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
break; break;
@ -148,7 +148,8 @@ static void digic_uart_realize(DeviceState *dev, Error **errp)
DigicUartState *s = DIGIC_UART(dev); DigicUartState *s = DIGIC_UART(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
uart_event, s, NULL);
} }
} }

View File

@ -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.chr || s->type != ser) if (!qemu_chr_fe_get_driver(&s->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, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); qemu_chr_fe_ioctl(&s->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,10 +556,10 @@ 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.chr) { if (qemu_chr_fe_get_driver(&s->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.chr, &s->tx, 1); qemu_chr_fe_write_all(&s->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);
} }
@ -600,7 +600,7 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
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.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
return ret; return ret;
default: default:
@ -1014,10 +1014,11 @@ 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.chr) { if (qemu_chr_fe_get_driver(&s->chn[i].chr)) {
s->chn[i].clock = s->frequency / 2; s->chn[i].clock = s->frequency / 2;
qemu_chr_add_handlers(s->chn[i].chr.chr, serial_can_receive, qemu_chr_fe_set_handlers(&s->chn[i].chr, serial_can_receive,
serial_receive1, serial_event, &s->chn[i]); serial_receive1, serial_event,
&s->chn[i], NULL);
} }
} }

View File

@ -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.chr, &ch, 1); qemu_chr_fe_write_all(&s->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;
@ -232,9 +232,9 @@ static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
ETRAXSerial *s = ETRAX_SERIAL(dev); ETRAXSerial *s = ETRAX_SERIAL(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, qemu_chr_fe_set_handlers(&s->chr,
serial_can_receive, serial_receive, serial_can_receive, serial_receive,
serial_event, s); serial_event, s, NULL);
} }
} }

View File

@ -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, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); qemu_chr_fe_ioctl(&s->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.chr) { if (qemu_chr_fe_get_driver(&s->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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
#if DEBUG_Tx_DATA #if DEBUG_Tx_DATA
fprintf(stderr, "%c", ch); fprintf(stderr, "%c", ch);
#endif #endif
@ -640,8 +640,9 @@ 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.chr, exynos4210_uart_can_receive, qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive,
exynos4210_uart_receive, exynos4210_uart_event, s); exynos4210_uart_receive, exynos4210_uart_event,
s, NULL);
return 0; return 0;
} }

View File

@ -201,11 +201,12 @@ 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.chr && (uart->control & UART_TRANSMIT_ENABLE)) { if (qemu_chr_fe_get_driver(&uart->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.chr, &c, 1); qemu_chr_fe_write_all(&uart->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,11 +243,11 @@ 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.chr, qemu_chr_fe_set_handlers(&uart->chr,
grlib_apbuart_can_receive, grlib_apbuart_can_receive,
grlib_apbuart_receive, grlib_apbuart_receive,
grlib_apbuart_event, grlib_apbuart_event,
uart); uart, NULL);
sysbus_init_irq(dev, &uart->irq); sysbus_init_irq(dev, &uart->irq);

View File

@ -122,7 +122,7 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
s->uts1 |= UTS1_RXEMPTY; s->uts1 |= UTS1_RXEMPTY;
imx_update(s); imx_update(s);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
} }
return c; return c;
@ -172,11 +172,11 @@ static void imx_serial_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size) uint64_t value, unsigned size)
{ {
IMXSerialState *s = (IMXSerialState *)opaque; IMXSerialState *s = (IMXSerialState *)opaque;
CharDriverState *chr = qemu_chr_fe_get_driver(&s->chr);
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, offset, (unsigned int)value, chr ? chr->label : "NODEV");
s->chr.chr ? s->chr.chr->label : "NODEV");
switch (offset >> 2) { switch (offset >> 2) {
case 0x10: /* UTXD */ case 0x10: /* UTXD */
@ -185,7 +185,7 @@ static void imx_serial_write(void *opaque, hwaddr offset,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
s->usr1 &= ~USR1_TRDY; s->usr1 &= ~USR1_TRDY;
imx_update(s); imx_update(s);
@ -216,7 +216,7 @@ 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.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
} }
} }
@ -320,8 +320,8 @@ static void imx_serial_realize(DeviceState *dev, Error **errp)
IMXSerialState *s = IMX_SERIAL(dev); IMXSerialState *s = IMX_SERIAL(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, imx_can_receive, imx_receive, qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive,
imx_event, s); imx_event, s, NULL);
} else { } else {
DPRINTF("No char dev for uart\n"); DPRINTF("No char dev for uart\n");
} }

View File

@ -289,7 +289,7 @@ static uint16_t io_read(IPackDevice *ip, uint8_t addr)
ch->sr &= ~SR_RXRDY; ch->sr &= ~SR_RXRDY;
blk->isr &= ~ISR_RXRDY(channel); blk->isr &= ~ISR_RXRDY(channel);
if (ch->dev.chr) { if (ch->dev.chr) {
qemu_chr_fe_accept_input(ch->dev.chr); qemu_chr_fe_accept_input(&ch->dev);
} }
} else { } else {
ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE; ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE;
@ -362,7 +362,7 @@ static void io_write(IPackDevice *ip, uint8_t addr, uint16_t val)
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.chr, &thr, 1); qemu_chr_fe_write_all(&ch->dev, &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,9 +546,9 @@ 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.chr) { if (qemu_chr_fe_get_driver(&ch->dev)) {
qemu_chr_add_handlers(ch->dev.chr, hostdev_can_receive, qemu_chr_fe_set_handlers(&ch->dev, hostdev_can_receive,
hostdev_receive, hostdev_event, ch); hostdev_receive, hostdev_event, ch, NULL);
DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label); DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
} else { } else {
DPRINTF("Could not redirect channel %u, no chardev set\n", i); DPRINTF("Could not redirect channel %u, no chardev set\n", i);

View File

@ -78,7 +78,7 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
} }
@ -121,8 +121,8 @@ static void lm32_juart_realize(DeviceState *dev, Error **errp)
LM32JuartState *s = LM32_JUART(dev); LM32JuartState *s = LM32_JUART(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, juart_can_rx, qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx,
juart_rx, juart_event, s); juart_event, s, NULL);
} }
} }

View File

@ -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_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
break; break;
case R_IIR: case R_IIR:
case R_LSR: case R_LSR:
@ -180,7 +180,7 @@ static void uart_write(void *opaque, hwaddr addr,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
break; break;
case R_IER: case R_IER:
@ -268,7 +268,8 @@ static void lm32_uart_realize(DeviceState *dev, Error **errp)
LM32UartState *s = LM32_UART(dev); LM32UartState *s = LM32_UART(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
uart_event, s, NULL);
} }
} }

View File

@ -93,7 +93,7 @@ uint64_t mcf_uart_read(void *opaque, hwaddr addr,
if (s->fifo_len == 0) if (s->fifo_len == 0)
s->sr &= ~MCF_UART_RxRDY; s->sr &= ~MCF_UART_RxRDY;
mcf_uart_update(s); mcf_uart_update(s);
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
return val; return val;
} }
case 0x10: case 0x10:
@ -117,7 +117,7 @@ static void mcf_uart_do_tx(mcf_uart_state *s)
if (s->chr.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.chr, (unsigned char *)&s->tb, 1); qemu_chr_fe_write_all(&s->chr, (unsigned char *)&s->tb, 1);
} }
s->sr |= MCF_UART_TxEMP; s->sr |= MCF_UART_TxEMP;
} }
@ -286,8 +286,8 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
if (chr) { if (chr) {
qemu_chr_fe_init(&s->chr, chr, &error_abort); qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_fe_claim_no_fail(chr); qemu_chr_fe_claim_no_fail(chr);
qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive, qemu_chr_fe_set_handlers(&s->chr, mcf_uart_can_receive,
mcf_uart_event, s); mcf_uart_receive, mcf_uart_event, s, NULL);
} }
mcf_uart_reset(s); mcf_uart_reset(s);
return s; return s;

View File

@ -125,7 +125,7 @@ static void uart_write(void *opaque, hwaddr addr, uint64_t value,
switch (addr) { switch (addr) {
case R_RXTX: case R_RXTX:
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_write_all(s->chr.chr, &ch, 1); qemu_chr_fe_write_all(&s->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_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
break; break;
default: default:
@ -201,7 +201,8 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp)
MilkymistUartState *s = MILKYMIST_UART(dev); MilkymistUartState *s = MILKYMIST_UART(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
uart_event, s, NULL);
} }
} }

View File

@ -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.chr, &s->dataw, 1); qemu_chr_fe_write_all(&s->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, CHR_IOCTL_PP_WRITE_DATA, &parm); qemu_chr_fe_ioctl(&s->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, CHR_IOCTL_PP_DATA_DIR, &dir); qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
parm &= ~PARA_CTR_DIR; parm &= ~PARA_CTR_DIR;
} }
qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm); qemu_chr_fe_ioctl(&s->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,7 @@ 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, if (qemu_chr_fe_ioctl(&s->chr,
CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) { 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);
@ -209,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, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) { if (qemu_chr_fe_ioctl(&s->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);
} }
@ -234,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, CHR_IOCTL_PP_EPP_WRITE, &ioarg); err = qemu_chr_fe_ioctl(&s->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);
@ -257,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, CHR_IOCTL_PP_EPP_WRITE, &ioarg); err = qemu_chr_fe_ioctl(&s->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);
@ -309,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, CHR_IOCTL_PP_READ_DATA, &ret); qemu_chr_fe_ioctl(&s->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, CHR_IOCTL_PP_READ_STATUS, &ret); qemu_chr_fe_ioctl(&s->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;
@ -327,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, CHR_IOCTL_PP_READ_CONTROL, &ret); qemu_chr_fe_ioctl(&s->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;
@ -345,7 +345,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
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, if (qemu_chr_fe_ioctl(&s->chr,
CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) { 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);
@ -361,7 +361,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
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, CHR_IOCTL_PP_EPP_READ, &ioarg)) { if (qemu_chr_fe_ioctl(&s->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);
} }
@ -389,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, CHR_IOCTL_PP_EPP_READ, &ioarg); err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
ret = le16_to_cpu(eppdata); ret = le16_to_cpu(eppdata);
if (err) { if (err) {
@ -416,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, CHR_IOCTL_PP_EPP_READ, &ioarg); err = qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
ret = le32_to_cpu(eppdata); ret = le32_to_cpu(eppdata);
if (err) { if (err) {
@ -512,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.chr) { if (!qemu_chr_fe_get_driver(&s->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;
} }
@ -534,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, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) { if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
s->hw_driver = 1; s->hw_driver = 1;
s->status = dummy; s->status = dummy;
} }

View File

@ -88,7 +88,7 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
s->rsr = c >> 8; s->rsr = c >> 8;
pl011_update(s); pl011_update(s);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
r = c; r = c;
break; break;
@ -171,7 +171,7 @@ static void pl011_write(void *opaque, hwaddr offset,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
s->int_level |= PL011_INT_TX; s->int_level |= PL011_INT_TX;
pl011_update(s); pl011_update(s);
@ -333,8 +333,8 @@ static void pl011_realize(DeviceState *dev, Error **errp)
PL011State *s = PL011(dev); PL011State *s = PL011(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, pl011_can_receive, pl011_receive, qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
pl011_event, s); pl011_event, s, NULL);
} }
} }

View File

@ -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.chr, buf, size); qemu_chr_fe_write_all(&scon->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.chr) { if (!qemu_chr_fe_get_driver(&scon->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.chr, buf, len); return qemu_chr_fe_write_all(&scon->chr, buf, len);
} }
static int process_mdb(SCLPEvent *event, MDBO *mdbo) static int process_mdb(SCLPEvent *event, MDBO *mdbo)
@ -313,8 +313,8 @@ static int console_init(SCLPEvent *event)
console_available = true; console_available = true;
if (scon->chr.chr) { if (scon->chr.chr) {
qemu_chr_add_handlers(scon->chr.chr, chr_can_read, qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
chr_read, NULL, scon); chr_read, NULL, scon, NULL);
} }
return 0; return 0;

View File

@ -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.chr) { if (!qemu_chr_fe_get_driver(&scon->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.chr, buf, len); return qemu_chr_fe_write_all(&scon->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)
@ -228,8 +228,8 @@ static int console_init(SCLPEvent *event)
} }
console_available = true; console_available = true;
if (scon->chr.chr) { if (scon->chr.chr) {
qemu_chr_add_handlers(scon->chr.chr, chr_can_read, qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
chr_read, NULL, scon); chr_read, NULL, scon, NULL);
} }
return 0; return 0;

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, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); qemu_chr_fe_ioctl(&s->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,7 @@ 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, CHR_IOCTL_SERIAL_GET_TIOCM, if (qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_GET_TIOCM,
&flags) == -ENOTSUP) { &flags) == -ENOTSUP) {
s->poll_msl = -1; s->poll_msl = -1;
return; return;
@ -261,11 +261,11 @@ 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.chr, &s->tsr, 1) != 1 && } else if (qemu_chr_fe_write(&s->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 = s->watch_tag =
qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP, qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
serial_watch_cb, s); serial_watch_cb, s);
if (s->watch_tag > 0) { if (s->watch_tag > 0) {
s->tsr_retry++; s->tsr_retry++;
@ -419,8 +419,8 @@ 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, CHR_IOCTL_SERIAL_SET_BREAK, qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
&break_enable); &break_enable);
} }
} }
break; break;
@ -434,8 +434,7 @@ 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, qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR); flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
@ -444,8 +443,7 @@ 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, qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
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);
@ -490,7 +488,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_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
} }
break; break;
@ -663,7 +661,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.chr, G_IO_OUT | G_IO_HUP, s->watch_tag = qemu_chr_fe_add_watch(&s->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). */
@ -888,7 +886,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.chr) { if (!qemu_chr_fe_get_driver(&s->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;
} }
@ -898,8 +896,8 @@ 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.chr, serial_can_receive1, serial_receive1, qemu_chr_fe_set_handlers(&s->chr, serial_can_receive1, serial_receive1,
serial_event, s); serial_event, s, NULL);
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);
serial_reset(s); serial_reset(s);
@ -907,7 +905,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.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
qemu_unregister_reset(serial_reset, s); qemu_unregister_reset(serial_reset, s);
} }

View File

@ -110,11 +110,11 @@ static void sh_serial_write(void *opaque, hwaddr offs,
} }
return; return;
case 0x0c: /* FTDR / TDR */ case 0x0c: /* FTDR / TDR */
if (s->chr.chr) { if (qemu_chr_fe_get_driver(&s->chr)) {
ch = val; ch = 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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
s->dr = val; s->dr = val;
s->flags &= ~SH_SERIAL_FLAG_TDE; s->flags &= ~SH_SERIAL_FLAG_TDE;
@ -399,8 +399,9 @@ void sh_serial_init(MemoryRegion *sysmem,
if (chr) { if (chr) {
qemu_chr_fe_claim_no_fail(chr); qemu_chr_fe_claim_no_fail(chr);
qemu_chr_fe_init(&s->chr, chr, &error_abort); qemu_chr_fe_init(&s->chr, chr, &error_abort);
qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, qemu_chr_fe_set_handlers(&s->chr, sh_serial_can_receive1,
sh_serial_event, s); sh_serial_receive1,
sh_serial_event, s, NULL);
} }
s->eri = eri_source; s->eri = eri_source;

View File

@ -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_fe_accept_input(dev->chardev.chr); qemu_chr_fe_accept_input(&dev->chardev);
return n; return n;
} }
@ -62,20 +62,20 @@ 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.chr, buf, len); qemu_chr_fe_write_all(&dev->chardev, 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.chr) { if (!qemu_chr_fe_get_driver(&dev->chardev)) {
error_setg(errp, "chardev property not set"); error_setg(errp, "chardev property not set");
return; return;
} }
qemu_chr_add_handlers(dev->chardev.chr, vty_can_receive, qemu_chr_fe_set_handlers(&dev->chardev, vty_can_receive,
vty_receive, NULL, dev); vty_receive, NULL, dev, NULL);
} }
/* Forward declaration */ /* Forward declaration */

View File

@ -98,7 +98,7 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
retvalue = s->usart_sr; retvalue = s->usart_sr;
s->usart_sr &= ~USART_SR_TC; s->usart_sr &= ~USART_SR_TC;
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
return retvalue; return retvalue;
case USART_DR: case USART_DR:
@ -106,7 +106,7 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
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.chr) { if (s->chr.chr) {
qemu_chr_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
} }
qemu_set_irq(s->irq, 0); qemu_set_irq(s->irq, 0);
return s->usart_dr & 0x3FF; return s->usart_dr & 0x3FF;
@ -155,7 +155,7 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->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;
@ -213,8 +213,8 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp)
STM32F2XXUsartState *s = STM32F2XX_USART(dev); STM32F2XXUsartState *s = STM32F2XX_USART(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, stm32f2xx_usart_can_receive, qemu_chr_fe_set_handlers(&s->chr, stm32f2xx_usart_can_receive,
stm32f2xx_usart_receive, NULL, s); stm32f2xx_usart_receive, NULL, s, NULL);
} }
} }

View File

@ -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.chr) { if (!qemu_chr_fe_get_driver(&vcon->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.chr, buf, len); ret = qemu_chr_fe_write(&vcon->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.chr, vcon->watch = qemu_chr_fe_add_watch(&vcon->chr,
G_IO_OUT | G_IO_HUP, G_IO_OUT|G_IO_HUP,
chr_write_unblocked, vcon); chr_write_unblocked, vcon);
} }
} }
@ -109,7 +109,7 @@ static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port); VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
if (vcon->chr.chr && !k->is_console) { if (vcon->chr.chr && !k->is_console) {
qemu_chr_fe_set_open(vcon->chr.chr, guest_connected); qemu_chr_fe_set_open(&vcon->chr, guest_connected);
} }
if (dev->id) { if (dev->id) {
@ -123,7 +123,7 @@ static void guest_writable(VirtIOSerialPort *port)
VirtConsole *vcon = VIRTIO_CONSOLE(port); VirtConsole *vcon = VIRTIO_CONSOLE(port);
if (vcon->chr.chr) { if (vcon->chr.chr) {
qemu_chr_fe_accept_input(vcon->chr.chr); qemu_chr_fe_accept_input(&vcon->chr);
} }
} }
@ -170,6 +170,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev); VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
VirtConsole *vcon = VIRTIO_CONSOLE(dev); VirtConsole *vcon = VIRTIO_CONSOLE(dev);
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev); VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
CharDriverState *chr = qemu_chr_fe_get_driver(&vcon->chr);
if (port->id == 0 && !k->is_console) { if (port->id == 0 && !k->is_console) {
error_setg(errp, "Port number 0 on virtio-serial devices reserved " error_setg(errp, "Port number 0 on virtio-serial devices reserved "
@ -177,7 +178,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp)
return; return;
} }
if (vcon->chr.chr) { if (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,14 +189,14 @@ 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.chr->explicit_fe_open = 0; chr->explicit_fe_open = 0;
qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read, qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
NULL, vcon); NULL, vcon, NULL);
virtio_serial_open(port); virtio_serial_open(port);
} else { } else {
vcon->chr.chr->explicit_fe_open = 1; chr->explicit_fe_open = 1;
qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read, qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
chr_event, vcon); chr_event, vcon, NULL);
} }
} }
} }

View File

@ -23,6 +23,7 @@
#include <sys/select.h> #include <sys/select.h>
#include <termios.h> #include <termios.h>
#include "qapi/error.h"
#include "hw/hw.h" #include "hw/hw.h"
#include "sysemu/char.h" #include "sysemu/char.h"
#include "hw/xen/xen_backend.h" #include "hw/xen/xen_backend.h"
@ -149,8 +150,8 @@ static void xencons_send(struct XenConsole *con)
ssize_t len, size; ssize_t len, size;
size = con->buffer.size - con->buffer.consumed; size = con->buffer.size - con->buffer.consumed;
if (con->chr.chr) { if (qemu_chr_fe_get_driver(&con->chr)) {
len = qemu_chr_fe_write(con->chr.chr, len = qemu_chr_fe_write(&con->chr,
con->buffer.data + con->buffer.consumed, con->buffer.data + con->buffer.consumed,
size); size);
} else { } else {
@ -209,7 +210,8 @@ static int con_init(struct XenDevice *xendev)
qemu_chr_new(label, output), &error_abort); qemu_chr_new(label, output), &error_abort);
} }
xenstore_store_pv_console_info(con->xendev.dev, con->chr.chr); xenstore_store_pv_console_info(con->xendev.dev,
qemu_chr_fe_get_driver(&con->chr));
out: out:
g_free(type); g_free(type);
@ -244,8 +246,8 @@ static int con_initialise(struct XenDevice *xendev)
xen_be_bind_evtchn(&con->xendev); xen_be_bind_evtchn(&con->xendev);
if (con->chr.chr) { if (con->chr.chr) {
if (qemu_chr_fe_claim(con->chr.chr) == 0) { if (qemu_chr_fe_claim(con->chr.chr) == 0) {
qemu_chr_add_handlers(con->chr.chr, xencons_can_receive, qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
xencons_receive, NULL, con); xencons_receive, NULL, con, NULL);
} else { } else {
xen_be_printf(xendev, 0, xen_be_printf(xendev, 0,
"xen_console_init error chardev %s already used\n", "xen_console_init error chardev %s already used\n",
@ -267,7 +269,7 @@ static void con_disconnect(struct XenDevice *xendev)
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
if (con->chr.chr) { if (con->chr.chr) {
qemu_chr_add_handlers(con->chr.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(con->chr.chr); qemu_chr_fe_release(con->chr.chr);
} }
xen_be_unbind_evtchn(&con->xendev); xen_be_unbind_evtchn(&con->xendev);

View File

@ -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_fe_accept_input(s->chr.chr); qemu_chr_fe_accept_input(&s->chr);
break; break;
default: default:
@ -146,7 +146,7 @@ uart_write(void *opaque, hwaddr addr,
if (s->chr.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.chr, &ch, 1); qemu_chr_fe_write_all(&s->chr, &ch, 1);
} }
s->regs[addr] = value; s->regs[addr] = value;
@ -214,7 +214,8 @@ static void xilinx_uartlite_realize(DeviceState *dev, Error **errp)
XilinxUARTLite *s = XILINX_UARTLITE(dev); XilinxUARTLite *s = XILINX_UARTLITE(dev);
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s); qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
uart_event, s, NULL);
} }
} }

View File

@ -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.chr, ibe->outbuf + ibe->outpos, ret = qemu_chr_fe_write(&ibe->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,13 @@ 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.chr) { if (!qemu_chr_fe_get_driver(&ibe->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.chr, can_receive, receive, chr_event, ibe); qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
chr_event, ibe, NULL);
} }
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

@ -125,9 +125,9 @@ static void malta_fpga_update_display(void *opaque)
} }
leds_text[8] = '\0'; leds_text[8] = '\0';
qemu_chr_fe_printf(s->display.chr, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", qemu_chr_fe_printf(&s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n",
leds_text); leds_text);
qemu_chr_fe_printf(s->display.chr, "\n\n\n\n|\e[31m%-8.8s\e[00m|", qemu_chr_fe_printf(&s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|",
s->display_text); s->display_text);
} }
@ -538,15 +538,15 @@ static void malta_fgpa_display_event(void *opaque, int event)
MaltaFPGAState *s = opaque; MaltaFPGAState *s = opaque;
if (event == CHR_EVENT_OPENED && !s->display_inited) { if (event == CHR_EVENT_OPENED && !s->display_inited) {
qemu_chr_fe_printf(s->display.chr, "\e[HMalta LEDBAR\r\n"); qemu_chr_fe_printf(&s->display, "\e[HMalta LEDBAR\r\n");
qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); qemu_chr_fe_printf(&s->display, "+--------+\r\n");
qemu_chr_fe_printf(s->display.chr, "+ +\r\n"); qemu_chr_fe_printf(&s->display, "+ +\r\n");
qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); qemu_chr_fe_printf(&s->display, "+--------+\r\n");
qemu_chr_fe_printf(s->display.chr, "\n"); qemu_chr_fe_printf(&s->display, "\n");
qemu_chr_fe_printf(s->display.chr, "Malta ASCII\r\n"); qemu_chr_fe_printf(&s->display, "Malta ASCII\r\n");
qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); qemu_chr_fe_printf(&s->display, "+--------+\r\n");
qemu_chr_fe_printf(s->display.chr, "+ +\r\n"); qemu_chr_fe_printf(&s->display, "+ +\r\n");
qemu_chr_fe_printf(s->display.chr, "+--------+\r\n"); qemu_chr_fe_printf(&s->display, "+--------+\r\n");
s->display_inited = true; s->display_inited = true;
} }
} }
@ -570,9 +570,9 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi); memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
chr = qemu_chr_new("fpga", "vc:320x200"); chr = qemu_chr_new("fpga", "vc:320x200");
qemu_chr_fe_init(&s->display, chr, &error_abort); qemu_chr_fe_init(&s->display, chr, NULL);
qemu_chr_add_handlers(s->display.chr, NULL, NULL, qemu_chr_fe_set_handlers(&s->display, NULL, NULL,
malta_fgpa_display_event, s); malta_fgpa_display_event, s, NULL);
s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq, s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
230400, uart_chr, DEVICE_NATIVE_ENDIAN); 230400, uart_chr, DEVICE_NATIVE_ENDIAN);

View File

@ -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.chr); fd = qemu_chr_fe_get_msgfd(&s->server_chr);
process_msg(s, msg, fd, &err); process_msg(s, msg, fd, &err);
if (err) { if (err) {
@ -642,8 +642,8 @@ 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.chr, (uint8_t *)&msg + n, ret = qemu_chr_fe_read_all(&s->server_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");
return INT64_MIN; return INT64_MIN;
@ -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.chr); *pfd = qemu_chr_fe_get_msgfd(&s->server_chr);
return msg; return msg;
} }
@ -868,10 +868,11 @@ 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.chr); CharDriverState *chr = qemu_chr_fe_get_driver(&s->server_chr);
assert(chr);
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
s->server_chr.chr->filename); 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,8 +894,8 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
return; return;
} }
qemu_chr_add_handlers(s->server_chr.chr, ivshmem_can_receive, qemu_chr_fe_set_handlers(&s->server_chr, ivshmem_can_receive,
ivshmem_read, NULL, s); ivshmem_read, NULL, s, NULL);
if (ivshmem_setup_interrupts(s) < 0) { if (ivshmem_setup_interrupts(s) < 0) {
error_setg(errp, "failed to initialize interrupts"); error_setg(errp, "failed to initialize interrupts");
@ -1121,7 +1122,7 @@ static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)
{ {
IVShmemState *s = IVSHMEM_COMMON(dev); IVShmemState *s = IVSHMEM_COMMON(dev);
if (!s->server_chr.chr) { if (!qemu_chr_fe_get_driver(&s->server_chr)) {
error_setg(errp, "You must specify a 'chardev'"); error_setg(errp, "You must specify a 'chardev'");
return; return;
} }
@ -1250,7 +1251,7 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
" or ivshmem-doorbell instead"); " or ivshmem-doorbell instead");
} }
if (!!s->server_chr.chr + !!s->shmobj != 1) { if (!!qemu_chr_fe_get_driver(&s->server_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

@ -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.chr, (uint8_t *)&scr_msg_header, qemu_chr_fe_write_all(&s->cs, (uint8_t *)&scr_msg_header,
sizeof(VSCMsgHeader)); sizeof(VSCMsgHeader));
qemu_chr_fe_write_all(s->cs.chr, payload, length); qemu_chr_fe_write_all(&s->cs, payload, length);
} }
static void ccid_card_vscard_send_apdu(PassthruState *s, static void ccid_card_vscard_send_apdu(PassthruState *s,
@ -264,7 +264,9 @@ 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.chr); CharDriverState *chr = qemu_chr_fe_get_driver(&card->cs);
qemu_chr_delete(chr);
card->vscard_in_pos = card->vscard_in_hdr = 0; card->vscard_in_pos = card->vscard_in_hdr = 0;
} }
@ -324,7 +326,7 @@ static void passthru_apdu_from_guest(
{ {
PassthruState *card = PASSTHRU_CCID_CARD(base); PassthruState *card = PASSTHRU_CCID_CARD(base);
if (!card->cs.chr) { if (!qemu_chr_fe_get_driver(&card->cs)) {
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,12 +347,12 @@ 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.chr) { if (qemu_chr_fe_get_driver(&card->cs)) {
DPRINTF(card, D_INFO, "initing chardev\n"); DPRINTF(card, D_INFO, "initing chardev\n");
qemu_chr_add_handlers(card->cs.chr, qemu_chr_fe_set_handlers(&card->cs,
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, NULL);
ccid_card_vscard_send_init(card); ccid_card_vscard_send_init(card);
} else { } else {
error_report("missing chardev"); error_report("missing chardev");

View File

@ -209,7 +209,7 @@ 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, if (qemu_chr_fe_ioctl(&s->cs,
CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) { CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
return FTDI_CTS|FTDI_DSR|FTDI_RLSD; return FTDI_CTS|FTDI_DSR|FTDI_RLSD;
} }
@ -262,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, CHR_IOCTL_SERIAL_GET_TIOCM, &flags); qemu_chr_fe_ioctl(&s->cs, 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;
@ -275,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, CHR_IOCTL_SERIAL_SET_TIOCM, &flags); qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
break; break;
} }
case DeviceOutVendor | FTDI_SET_FLOW_CTRL: case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
@ -294,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, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
break; break;
} }
case DeviceOutVendor | FTDI_SET_DATA: case DeviceOutVendor | FTDI_SET_DATA:
@ -323,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, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); qemu_chr_fe_ioctl(&s->cs, 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:
@ -370,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.chr, iov->iov_base, iov->iov_len); qemu_chr_fe_write_all(&s->cs, iov->iov_base, iov->iov_len);
} }
p->actual_length = p->iov.size; p->actual_length = p->iov.size;
break; break;
@ -485,12 +485,13 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
{ {
USBSerialState *s = USB_SERIAL_DEV(dev); USBSerialState *s = USB_SERIAL_DEV(dev);
Error *local_err = NULL; Error *local_err = NULL;
CharDriverState *chr = qemu_chr_fe_get_driver(&s->cs);
usb_desc_create_serial(dev); usb_desc_create_serial(dev);
usb_desc_init(dev); usb_desc_init(dev);
dev->auto_attach = 0; dev->auto_attach = 0;
if (!s->cs.chr) { if (!chr) {
error_setg(errp, "Property chardev is required"); error_setg(errp, "Property chardev is required");
return; return;
} }
@ -501,11 +502,11 @@ static void usb_serial_realize(USBDevice *dev, Error **errp)
return; return;
} }
qemu_chr_add_handlers(s->cs.chr, usb_serial_can_read, usb_serial_read, qemu_chr_fe_set_handlers(&s->cs, usb_serial_can_read, usb_serial_read,
usb_serial_event, s); usb_serial_event, s, NULL);
usb_serial_handle_reset(dev); usb_serial_handle_reset(dev);
if (s->cs.chr->be_open && !dev->attached) { if (chr->be_open && !dev->attached) {
usb_device_attach(dev, &error_abort); usb_device_attach(dev, &error_abort);
} }
} }

View File

@ -283,9 +283,10 @@ static gboolean usbredir_write_unblocked(GIOChannel *chan, GIOCondition cond,
static int usbredir_write(void *priv, uint8_t *data, int count) static int usbredir_write(void *priv, uint8_t *data, int count)
{ {
USBRedirDevice *dev = priv; USBRedirDevice *dev = priv;
CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs);
int r; int r;
if (!dev->cs.chr->be_open) { if (!chr->be_open) {
return 0; return 0;
} }
@ -294,10 +295,10 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
return 0; return 0;
} }
r = qemu_chr_fe_write(dev->cs.chr, data, count); r = qemu_chr_fe_write(&dev->cs, data, count);
if (r < count) { if (r < count) {
if (!dev->watch) { if (!dev->watch) {
dev->watch = qemu_chr_fe_add_watch(dev->cs.chr, G_IO_OUT | G_IO_HUP, dev->watch = qemu_chr_fe_add_watch(&dev->cs, G_IO_OUT | G_IO_HUP,
usbredir_write_unblocked, dev); usbredir_write_unblocked, dev);
} }
if (r < 0) { if (r < 0) {
@ -1375,7 +1376,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.chr == NULL) { if (!qemu_chr_fe_get_driver(&dev->cs)) {
error_setg(errp, QERR_MISSING_PARAMETER, "chardev"); error_setg(errp, QERR_MISSING_PARAMETER, "chardev");
return; return;
} }
@ -1406,8 +1407,9 @@ 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.chr, usbredir_chardev_can_read, qemu_chr_fe_set_handlers(&dev->cs, usbredir_chardev_can_read,
usbredir_chardev_read, usbredir_chardev_event, dev); usbredir_chardev_read, usbredir_chardev_event,
dev, NULL);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev); qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
} }
@ -1426,8 +1428,10 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
static void usbredir_handle_destroy(USBDevice *udev) static void usbredir_handle_destroy(USBDevice *udev)
{ {
USBRedirDevice *dev = USB_REDIRECT(udev); USBRedirDevice *dev = USB_REDIRECT(udev);
CharDriverState *chr = qemu_chr_fe_get_driver(&dev->cs);
qemu_chr_delete(chr);
qemu_chr_delete(dev->cs.chr);
dev->cs.chr = 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);

View File

@ -116,7 +116,7 @@ static bool ioeventfd_enabled(void)
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg) static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{ {
CharDriverState *chr = dev->opaque; CharBackend *chr = dev->opaque;
uint8_t *p = (uint8_t *) msg; uint8_t *p = (uint8_t *) msg;
int r, size = VHOST_USER_HDR_SIZE; int r, size = VHOST_USER_HDR_SIZE;
@ -196,7 +196,7 @@ static bool vhost_user_one_time_request(VhostUserRequest request)
static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg, static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
int *fds, int fd_num) int *fds, int fd_num)
{ {
CharDriverState *chr = dev->opaque; CharBackend *chr = dev->opaque;
int ret, size = VHOST_USER_HDR_SIZE + msg->size; int ret, size = VHOST_USER_HDR_SIZE + msg->size;
/* /*

View File

@ -28,6 +28,7 @@
#include "hw/hw.h" #include "hw/hw.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/char.h"
#include "exec/memory.h" #include "exec/memory.h"
#include "qemu/fifo8.h" #include "qemu/fifo8.h"
#include "sysemu/char.h" #include "sysemu/char.h"

View File

@ -169,7 +169,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename);
* *
* Close a fd accpeted by character backend. * Close a fd accpeted by character backend.
*/ */
void qemu_chr_fe_disconnect(CharDriverState *chr); void qemu_chr_fe_disconnect(CharBackend *be);
/** /**
* @qemu_chr_cleanup: * @qemu_chr_cleanup:
@ -179,11 +179,11 @@ void qemu_chr_fe_disconnect(CharDriverState *chr);
void qemu_chr_cleanup(void); void qemu_chr_cleanup(void);
/** /**
* @qemu_chr_wait_connected: * @qemu_chr_fe_wait_connected:
* *
* Wait for characted backend to be connected. * Wait for characted backend to be connected.
*/ */
int qemu_chr_wait_connected(CharDriverState *chr, Error **errp); int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
/** /**
* @qemu_chr_new_noreplay: * @qemu_chr_new_noreplay:
@ -223,7 +223,7 @@ void qemu_chr_free(CharDriverState *chr);
* *
* @echo true to enable echo, false to disable echo * @echo true to enable echo, false to disable echo
*/ */
void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo); void qemu_chr_fe_set_echo(CharBackend *be, bool echo);
/** /**
* @qemu_chr_fe_set_open: * @qemu_chr_fe_set_open:
@ -231,7 +231,7 @@ void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
* Set character frontend open status. This is an indication that the * Set character frontend open status. This is an indication that the
* front end is ready (or not) to begin doing I/O. * front end is ready (or not) to begin doing I/O.
*/ */
void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open); void qemu_chr_fe_set_open(CharBackend *be, int fe_open);
/** /**
* @qemu_chr_fe_event: * @qemu_chr_fe_event:
@ -240,7 +240,7 @@ void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open);
* *
* @event the event to send * @event the event to send
*/ */
void qemu_chr_fe_event(CharDriverState *s, int event); void qemu_chr_fe_event(CharBackend *be, int event);
/** /**
* @qemu_chr_fe_printf: * @qemu_chr_fe_printf:
@ -250,7 +250,7 @@ void qemu_chr_fe_event(CharDriverState *s, int event);
* *
* @fmt see #printf * @fmt see #printf
*/ */
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
GCC_FMT_ATTR(2, 3); GCC_FMT_ATTR(2, 3);
/** /**
@ -265,7 +265,7 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
* @func the function to call when the condition happens * @func the function to call when the condition happens
* @user_data the opaque pointer to pass to @func * @user_data the opaque pointer to pass to @func
*/ */
guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
GIOFunc func, void *user_data); GIOFunc func, void *user_data);
/** /**
@ -280,7 +280,7 @@ guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
* *
* Returns: the number of bytes consumed * Returns: the number of bytes consumed
*/ */
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
/** /**
* @qemu_chr_fe_write_all: * @qemu_chr_fe_write_all:
@ -295,7 +295,7 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
* *
* Returns: the number of bytes consumed * Returns: the number of bytes consumed
*/ */
int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len); int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
/** /**
* @qemu_chr_fe_read_all: * @qemu_chr_fe_read_all:
@ -307,7 +307,7 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len);
* *
* Returns: the number of bytes read * Returns: the number of bytes read
*/ */
int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len); int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
/** /**
* @qemu_chr_fe_ioctl: * @qemu_chr_fe_ioctl:
@ -320,7 +320,7 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len);
* Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the
* return value depends on the semantics of @cmd * return value depends on the semantics of @cmd
*/ */
int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg); int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg);
/** /**
* @qemu_chr_fe_get_msgfd: * @qemu_chr_fe_get_msgfd:
@ -333,7 +333,7 @@ int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
* this function will return -1 until a client sends a new file * this function will return -1 until a client sends a new file
* descriptor. * descriptor.
*/ */
int qemu_chr_fe_get_msgfd(CharDriverState *s); int qemu_chr_fe_get_msgfd(CharBackend *be);
/** /**
* @qemu_chr_fe_get_msgfds: * @qemu_chr_fe_get_msgfds:
@ -346,7 +346,7 @@ int qemu_chr_fe_get_msgfd(CharDriverState *s);
* this function will return -1 until a client sends a new set of file * this function will return -1 until a client sends a new set of file
* descriptors. * descriptors.
*/ */
int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num); int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num);
/** /**
* @qemu_chr_fe_set_msgfds: * @qemu_chr_fe_set_msgfds:
@ -359,13 +359,13 @@ int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num);
* *
* Returns: -1 if fd passing isn't supported. * Returns: -1 if fd passing isn't supported.
*/ */
int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num); int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num);
/** /**
* @qemu_chr_fe_claim: * @qemu_chr_fe_claim:
* *
* Claim a backend before using it, should be called before calling * Claim a backend before using it, should be called before calling
* qemu_chr_add_handlers(). * qemu_chr_fe_set_handlers().
* *
* Returns: -1 if the backend is already in use by another frontend, 0 on * Returns: -1 if the backend is already in use by another frontend, 0 on
* success. * success.
@ -436,7 +436,8 @@ void qemu_chr_be_event(CharDriverState *s, int event);
/** /**
* @qemu_chr_fe_init: * @qemu_chr_fe_init:
* *
* Initializes a front end for the given CharBackend and CharDriver. * Initializes a front end for the given CharBackend and
* CharDriver.
* *
* Returns: false on error. * Returns: false on error.
*/ */
@ -475,22 +476,8 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
*/ */
void qemu_chr_fe_take_focus(CharBackend *b); void qemu_chr_fe_take_focus(CharBackend *b);
void qemu_chr_add_handlers(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque);
/* This API can make handler run in the context what you pass to. */
void qemu_chr_add_handlers_full(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque,
GMainContext *context);
void qemu_chr_be_generic_open(CharDriverState *s); void qemu_chr_be_generic_open(CharDriverState *s);
void qemu_chr_fe_accept_input(CharDriverState *s); void qemu_chr_fe_accept_input(CharBackend *be);
int qemu_chr_add_client(CharDriverState *s, int fd); int qemu_chr_add_client(CharDriverState *s, int fd);
CharDriverState *qemu_chr_find(const char *name); CharDriverState *qemu_chr_find(const char *name);
bool chr_is_ringbuf(const CharDriverState *chr); bool chr_is_ringbuf(const CharDriverState *chr);

View File

@ -297,7 +297,7 @@ static void monitor_flush_locked(Monitor *mon)
len = qstring_get_length(mon->outbuf); len = qstring_get_length(mon->outbuf);
if (len && !mon->mux_out) { if (len && !mon->mux_out) {
rc = qemu_chr_fe_write(mon->chr.chr, (const uint8_t *) buf, len); rc = qemu_chr_fe_write(&mon->chr, (const uint8_t *) buf, len);
if ((rc < 0 && errno != EAGAIN) || (rc == len)) { if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
/* all flushed or error */ /* all flushed or error */
QDECREF(mon->outbuf); QDECREF(mon->outbuf);
@ -312,7 +312,7 @@ static void monitor_flush_locked(Monitor *mon)
} }
if (mon->out_watch == 0) { if (mon->out_watch == 0) {
mon->out_watch = mon->out_watch =
qemu_chr_fe_add_watch(mon->chr.chr, G_IO_OUT | G_IO_HUP, qemu_chr_fe_add_watch(&mon->chr, G_IO_OUT | G_IO_HUP,
monitor_unblocked, mon); monitor_unblocked, mon);
} }
} }
@ -583,7 +583,7 @@ static void monitor_data_init(Monitor *mon)
static void monitor_data_destroy(Monitor *mon) static void monitor_data_destroy(Monitor *mon)
{ {
if (mon->chr.chr) { if (mon->chr.chr) {
qemu_chr_add_handlers(mon->chr.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&mon->chr, NULL, NULL, NULL, NULL, NULL);
} }
if (monitor_is_qmp(mon)) { if (monitor_is_qmp(mon)) {
json_message_parser_destroy(&mon->qmp.parser); json_message_parser_destroy(&mon->qmp.parser);
@ -1746,7 +1746,7 @@ void qmp_getfd(const char *fdname, Error **errp)
mon_fd_t *monfd; mon_fd_t *monfd;
int fd; int fd;
fd = qemu_chr_fe_get_msgfd(cur_mon->chr.chr); fd = qemu_chr_fe_get_msgfd(&cur_mon->chr);
if (fd == -1) { if (fd == -1) {
error_setg(errp, QERR_FD_NOT_SUPPLIED); error_setg(errp, QERR_FD_NOT_SUPPLIED);
return; return;
@ -1871,7 +1871,7 @@ AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque,
Monitor *mon = cur_mon; Monitor *mon = cur_mon;
AddfdInfo *fdinfo; AddfdInfo *fdinfo;
fd = qemu_chr_fe_get_msgfd(mon->chr.chr); fd = qemu_chr_fe_get_msgfd(&mon->chr);
if (fd == -1) { if (fd == -1) {
error_setg(errp, QERR_FD_NOT_SUPPLIED); error_setg(errp, QERR_FD_NOT_SUPPLIED);
goto error; goto error;
@ -3989,13 +3989,13 @@ void monitor_init(CharDriverState *chr, int flags)
} }
if (monitor_is_qmp(mon)) { if (monitor_is_qmp(mon)) {
qemu_chr_add_handlers(chr, monitor_can_read, monitor_qmp_read, qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_qmp_read,
monitor_qmp_event, mon); monitor_qmp_event, mon, NULL);
qemu_chr_fe_set_echo(chr, true); qemu_chr_fe_set_echo(&mon->chr, true);
json_message_parser_init(&mon->qmp.parser, handle_qmp_command); json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
} else { } else {
qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_read,
monitor_event, mon); monitor_event, mon, NULL);
} }
qemu_mutex_lock(&monitor_lock); qemu_mutex_lock(&monitor_lock);

View File

@ -101,7 +101,7 @@ enum {
SECONDARY_IN, SECONDARY_IN,
}; };
static int compare_chr_send(CharDriverState *out, static int compare_chr_send(CharBackend *out,
const uint8_t *buf, const uint8_t *buf,
uint32_t size); uint32_t size);
@ -385,7 +385,7 @@ static void colo_compare_connection(void *opaque, void *user_data)
} }
if (result) { if (result) {
ret = compare_chr_send(s->chr_out.chr, pkt->data, pkt->size); ret = compare_chr_send(&s->chr_out, pkt->data, pkt->size);
if (ret < 0) { if (ret < 0) {
error_report("colo_send_primary_packet failed"); error_report("colo_send_primary_packet failed");
} }
@ -408,7 +408,7 @@ static void colo_compare_connection(void *opaque, void *user_data)
} }
} }
static int compare_chr_send(CharDriverState *out, static int compare_chr_send(CharBackend *out,
const uint8_t *buf, const uint8_t *buf,
uint32_t size) uint32_t size)
{ {
@ -451,7 +451,7 @@ static void compare_pri_chr_in(void *opaque, const uint8_t *buf, int size)
ret = net_fill_rstate(&s->pri_rs, buf, size); ret = net_fill_rstate(&s->pri_rs, buf, size);
if (ret == -1) { if (ret == -1) {
qemu_chr_add_handlers(s->chr_pri_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_pri_in, NULL, NULL, NULL, NULL, NULL);
error_report("colo-compare primary_in error"); error_report("colo-compare primary_in error");
} }
} }
@ -467,7 +467,7 @@ static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
ret = net_fill_rstate(&s->sec_rs, buf, size); ret = net_fill_rstate(&s->sec_rs, buf, size);
if (ret == -1) { if (ret == -1) {
qemu_chr_add_handlers(s->chr_sec_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_sec_in, NULL, NULL, NULL, NULL, NULL);
error_report("colo-compare secondary_in error"); error_report("colo-compare secondary_in error");
} }
} }
@ -480,10 +480,10 @@ static void *colo_compare_thread(void *opaque)
worker_context = g_main_context_new(); worker_context = g_main_context_new();
qemu_chr_add_handlers_full(s->chr_pri_in.chr, compare_chr_can_read, qemu_chr_fe_set_handlers(&s->chr_pri_in, compare_chr_can_read,
compare_pri_chr_in, NULL, s, worker_context); compare_pri_chr_in, NULL, s, worker_context);
qemu_chr_add_handlers_full(s->chr_sec_in.chr, compare_chr_can_read, qemu_chr_fe_set_handlers(&s->chr_sec_in, compare_chr_can_read,
compare_sec_chr_in, NULL, s, worker_context); compare_sec_chr_in, NULL, s, worker_context);
compare_loop = g_main_loop_new(worker_context, FALSE); compare_loop = g_main_loop_new(worker_context, FALSE);
@ -545,7 +545,7 @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
if (packet_enqueue(s, PRIMARY_IN)) { if (packet_enqueue(s, PRIMARY_IN)) {
trace_colo_compare_main("primary: unsupported packet in"); trace_colo_compare_main("primary: unsupported packet in");
compare_chr_send(s->chr_out.chr, pri_rs->buf, pri_rs->packet_len); compare_chr_send(&s->chr_out, pri_rs->buf, pri_rs->packet_len);
} else { } else {
/* compare connection */ /* compare connection */
g_queue_foreach(&s->conn_list, colo_compare_connection, s); g_queue_foreach(&s->conn_list, colo_compare_connection, s);
@ -626,6 +626,7 @@ static void check_old_packet_regular(void *opaque)
static void colo_compare_complete(UserCreatable *uc, Error **errp) static void colo_compare_complete(UserCreatable *uc, Error **errp)
{ {
CompareState *s = COLO_COMPARE(uc); CompareState *s = COLO_COMPARE(uc);
CharDriverState *chr;
char thread_name[64]; char thread_name[64];
static int compare_id; static int compare_id;
@ -641,15 +642,18 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
return; return;
} }
if (find_and_check_chardev(&s->chr_pri_in.chr, s->pri_indev, errp)) { if (find_and_check_chardev(&chr, s->pri_indev, errp) ||
!qemu_chr_fe_init(&s->chr_pri_in, chr, errp)) {
return; return;
} }
if (find_and_check_chardev(&s->chr_sec_in.chr, s->sec_indev, errp)) { if (find_and_check_chardev(&chr, s->sec_indev, errp) ||
!qemu_chr_fe_init(&s->chr_sec_in, chr, errp)) {
return; return;
} }
if (find_and_check_chardev(&s->chr_out.chr, s->outdev, errp)) { if (find_and_check_chardev(&chr, s->outdev, errp) ||
!qemu_chr_fe_init(&s->chr_out, chr, errp)) {
return; return;
} }
@ -704,11 +708,11 @@ static void colo_compare_finalize(Object *obj)
CompareState *s = COLO_COMPARE(obj); CompareState *s = COLO_COMPARE(obj);
if (s->chr_pri_in.chr) { if (s->chr_pri_in.chr) {
qemu_chr_add_handlers(s->chr_pri_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_pri_in, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(s->chr_pri_in.chr); qemu_chr_fe_release(s->chr_pri_in.chr);
} }
if (s->chr_sec_in.chr) { if (s->chr_sec_in.chr) {
qemu_chr_add_handlers(s->chr_sec_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_sec_in, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(s->chr_sec_in.chr); qemu_chr_fe_release(s->chr_sec_in.chr);
} }
if (s->chr_out.chr) { if (s->chr_out.chr) {

View File

@ -43,7 +43,7 @@ typedef struct MirrorState {
SocketReadState rs; SocketReadState rs;
} MirrorState; } MirrorState;
static int filter_mirror_send(CharDriverState *chr_out, static int filter_mirror_send(CharBackend *chr_out,
const struct iovec *iov, const struct iovec *iov,
int iovcnt) int iovcnt)
{ {
@ -110,7 +110,7 @@ static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
ret = net_fill_rstate(&s->rs, buf, size); ret = net_fill_rstate(&s->rs, buf, size);
if (ret == -1) { if (ret == -1) {
qemu_chr_add_handlers(s->chr_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL, NULL, NULL);
} }
} }
@ -121,7 +121,7 @@ static void redirector_chr_event(void *opaque, int event)
switch (event) { switch (event) {
case CHR_EVENT_CLOSED: case CHR_EVENT_CLOSED:
qemu_chr_add_handlers(s->chr_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL, NULL, NULL);
break; break;
default: default:
break; break;
@ -138,7 +138,7 @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
MirrorState *s = FILTER_MIRROR(nf); MirrorState *s = FILTER_MIRROR(nf);
int ret; int ret;
ret = filter_mirror_send(s->chr_out.chr, iov, iovcnt); ret = filter_mirror_send(&s->chr_out, iov, iovcnt);
if (ret) { if (ret) {
error_report("filter_mirror_send failed(%s)", strerror(-ret)); error_report("filter_mirror_send failed(%s)", strerror(-ret));
} }
@ -160,8 +160,8 @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
MirrorState *s = FILTER_REDIRECTOR(nf); MirrorState *s = FILTER_REDIRECTOR(nf);
int ret; int ret;
if (s->chr_out.chr) { if (qemu_chr_fe_get_driver(&s->chr_out)) {
ret = filter_mirror_send(s->chr_out.chr, iov, iovcnt); ret = filter_mirror_send(&s->chr_out, iov, iovcnt);
if (ret) { if (ret) {
error_report("filter_mirror_send failed(%s)", strerror(-ret)); error_report("filter_mirror_send failed(%s)", strerror(-ret));
} }
@ -185,7 +185,7 @@ static void filter_redirector_cleanup(NetFilterState *nf)
MirrorState *s = FILTER_REDIRECTOR(nf); MirrorState *s = FILTER_REDIRECTOR(nf);
if (s->chr_in.chr) { if (s->chr_in.chr) {
qemu_chr_add_handlers(s->chr_in.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(s->chr_in.chr); qemu_chr_fe_release(s->chr_in.chr);
} }
if (s->chr_out.chr) { if (s->chr_out.chr) {
@ -258,8 +258,10 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) { if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) {
return; return;
} }
qemu_chr_add_handlers(s->chr_in.chr, redirector_chr_can_read,
redirector_chr_read, redirector_chr_event, nf); qemu_chr_fe_set_handlers(&s->chr_in, redirector_chr_can_read,
redirector_chr_read, redirector_chr_event,
nf, NULL);
} }
if (s->outdev) { if (s->outdev) {

View File

@ -763,7 +763,8 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
return -1; return -1;
} }
if (slirp_add_exec(s->slirp, 3, fwd->hd.chr, &server, port) < 0) { if (slirp_add_exec(s->slirp, 3, qemu_chr_fe_get_driver(&fwd->hd),
&server, port) < 0) {
error_report("conflicting/invalid host:port in guest forwarding " error_report("conflicting/invalid host:port in guest forwarding "
"rule '%s'", config_str); "rule '%s'", config_str);
g_free(fwd); g_free(fwd);
@ -774,8 +775,8 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
fwd->slirp = s->slirp; fwd->slirp = s->slirp;
qemu_chr_fe_claim_no_fail(fwd->hd.chr); qemu_chr_fe_claim_no_fail(fwd->hd.chr);
qemu_chr_add_handlers(fwd->hd.chr, guestfwd_can_read, guestfwd_read, qemu_chr_fe_set_handlers(&fwd->hd, guestfwd_can_read, guestfwd_read,
NULL, fwd); NULL, fwd, NULL);
} }
return 0; return 0;

View File

@ -78,7 +78,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[])
s = DO_UPCAST(VhostUserState, nc, ncs[i]); s = DO_UPCAST(VhostUserState, nc, ncs[i]);
options.net_backend = ncs[i]; options.net_backend = ncs[i];
options.opaque = s->chr.chr; options.opaque = &s->chr;
options.busyloop_timeout = 0; options.busyloop_timeout = 0;
net = vhost_net_init(&options); net = vhost_net_init(&options);
if (!net) { if (!net) {
@ -151,7 +151,7 @@ static void vhost_user_cleanup(NetClientState *nc)
s->vhost_net = NULL; s->vhost_net = NULL;
} }
if (s->chr.chr) { if (s->chr.chr) {
qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, NULL); qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL);
qemu_chr_fe_release(s->chr.chr); qemu_chr_fe_release(s->chr.chr);
s->chr.chr = NULL; s->chr.chr = NULL;
} }
@ -187,7 +187,7 @@ static gboolean net_vhost_user_watch(GIOChannel *chan, GIOCondition cond,
{ {
VhostUserState *s = opaque; VhostUserState *s = opaque;
qemu_chr_fe_disconnect(s->chr.chr); qemu_chr_fe_disconnect(&s->chr);
return FALSE; return FALSE;
} }
@ -197,6 +197,7 @@ static void net_vhost_user_event(void *opaque, int event)
const char *name = opaque; const char *name = opaque;
NetClientState *ncs[MAX_QUEUE_NUM]; NetClientState *ncs[MAX_QUEUE_NUM];
VhostUserState *s; VhostUserState *s;
CharDriverState *chr;
Error *err = NULL; Error *err = NULL;
int queues; int queues;
@ -206,13 +207,14 @@ static void net_vhost_user_event(void *opaque, int event)
assert(queues < MAX_QUEUE_NUM); assert(queues < MAX_QUEUE_NUM);
s = DO_UPCAST(VhostUserState, nc, ncs[0]); s = DO_UPCAST(VhostUserState, nc, ncs[0]);
trace_vhost_user_event(s->chr.chr->label, event); chr = qemu_chr_fe_get_driver(&s->chr);
trace_vhost_user_event(chr->label, event);
switch (event) { switch (event) {
case CHR_EVENT_OPENED: case CHR_EVENT_OPENED:
s->watch = qemu_chr_fe_add_watch(s->chr.chr, G_IO_HUP, s->watch = qemu_chr_fe_add_watch(&s->chr, G_IO_HUP,
net_vhost_user_watch, s); net_vhost_user_watch, s);
if (vhost_user_start(queues, ncs) < 0) { if (vhost_user_start(queues, ncs) < 0) {
qemu_chr_fe_disconnect(s->chr.chr); qemu_chr_fe_disconnect(&s->chr);
return; return;
} }
qmp_set_link(name, true, &err); qmp_set_link(name, true, &err);
@ -255,6 +257,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
nc->queue_index = i; nc->queue_index = i;
s = DO_UPCAST(VhostUserState, nc, nc); s = DO_UPCAST(VhostUserState, nc, nc);
if (!qemu_chr_fe_init(&s->chr, chr, &err)) { if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
error_report_err(err); error_report_err(err);
return -1; return -1;
@ -263,12 +266,12 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
s = DO_UPCAST(VhostUserState, nc, nc0); s = DO_UPCAST(VhostUserState, nc, nc0);
do { do {
if (qemu_chr_wait_connected(chr, &err) < 0) { if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
error_report_err(err); error_report_err(err);
return -1; return -1;
} }
qemu_chr_add_handlers(chr, NULL, NULL, qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
net_vhost_user_event, nc0->name); net_vhost_user_event, nc0->name, NULL);
} while (!s->started); } while (!s->started);
assert(s->vhost_net); assert(s->vhost_net);

View File

@ -268,8 +268,9 @@ static int qemu_chr_fe_write_buffer(CharDriverState *s, const uint8_t *buf, int
return res; return res;
} }
int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
{ {
CharDriverState *s = be->chr;
int ret; int ret;
if (s->replay && replay_mode == REPLAY_MODE_PLAY) { if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
@ -296,7 +297,7 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
return ret; return ret;
} }
int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) static int qemu_chr_write_all(CharDriverState *s, const uint8_t *buf, int len)
{ {
int offset; int offset;
int res; int res;
@ -320,8 +321,16 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len)
return offset; return offset;
} }
int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len) int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
{ {
CharDriverState *s = be->chr;
return qemu_chr_write_all(s, buf, len);
}
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
{
CharDriverState *s = be->chr;
int offset = 0, counter = 10; int offset = 0, counter = 10;
int res; int res;
@ -365,8 +374,9 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
return offset; return offset;
} }
int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg) int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
{ {
CharDriverState *s = be->chr;
int res; int res;
if (!s->chr_ioctl || s->replay) { if (!s->chr_ioctl || s->replay) {
res = -ENOTSUP; res = -ENOTSUP;
@ -403,10 +413,11 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
} }
} }
int qemu_chr_fe_get_msgfd(CharDriverState *s) int qemu_chr_fe_get_msgfd(CharBackend *be)
{ {
CharDriverState *s = be->chr;
int fd; int fd;
int res = (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1; int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1;
if (s->replay) { if (s->replay) {
fprintf(stderr, fprintf(stderr,
"Replay: get msgfd is not supported for serial devices yet\n"); "Replay: get msgfd is not supported for serial devices yet\n");
@ -415,13 +426,17 @@ int qemu_chr_fe_get_msgfd(CharDriverState *s)
return res; return res;
} }
int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len) int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
{ {
CharDriverState *s = be->chr;
return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1; return s->get_msgfds ? s->get_msgfds(s, fds, len) : -1;
} }
int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num) int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
{ {
CharDriverState *s = be->chr;
return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1; return s->set_msgfds ? s->set_msgfds(s, fds, num) : -1;
} }
@ -430,14 +445,16 @@ int qemu_chr_add_client(CharDriverState *s, int fd)
return s->chr_add_client ? s->chr_add_client(s, fd) : -1; return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
} }
void qemu_chr_fe_accept_input(CharDriverState *s) void qemu_chr_fe_accept_input(CharBackend *be)
{ {
CharDriverState *s = be->chr;
if (s->chr_accept_input) if (s->chr_accept_input)
s->chr_accept_input(s); s->chr_accept_input(s);
qemu_notify_event(); qemu_notify_event();
} }
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
{ {
char buf[READ_BUF_LEN]; char buf[READ_BUF_LEN];
va_list ap; va_list ap;
@ -445,21 +462,21 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
vsnprintf(buf, sizeof(buf), fmt, ap); vsnprintf(buf, sizeof(buf), fmt, ap);
/* 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, (uint8_t *)buf, strlen(buf)); qemu_chr_fe_write_all(be, (uint8_t *)buf, strlen(buf));
va_end(ap); va_end(ap);
} }
static void remove_fd_in_watch(CharDriverState *chr); static void remove_fd_in_watch(CharDriverState *chr);
static void static void
qemu_chr_set_handlers(CharDriverState *s, qemu_chr_set_handlers(CharBackend *be,
IOCanReadHandler *fd_can_read, IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read, IOReadHandler *fd_read,
IOEventHandler *fd_event, IOEventHandler *fd_event,
void *opaque, void *opaque,
GMainContext *context, GMainContext *context)
int tag)
{ {
CharDriverState *s = be->chr;
int fe_open; int fe_open;
if (!opaque && !fd_can_read && !fd_read && !fd_event) { if (!opaque && !fd_can_read && !fd_read && !fd_event) {
@ -473,17 +490,20 @@ qemu_chr_set_handlers(CharDriverState *s,
s->chr_event = fd_event; s->chr_event = fd_event;
s->handler_opaque = opaque; s->handler_opaque = opaque;
if (s->chr_update_read_handler) { if (s->chr_update_read_handler) {
s->chr_update_read_handler(s, context, tag); s->chr_update_read_handler(s, context, be->tag);
} }
if (!s->explicit_fe_open) { if (!s->explicit_fe_open) {
qemu_chr_fe_set_open(s, fe_open); qemu_chr_fe_set_open(be, fe_open);
} }
/* We're connecting to an already opened device, so let's make sure we /* We're connecting to an already opened device, so let's make sure we
also get the open event */ also get the open event */
if (fe_open && s->be_open) { if (fe_open) {
qemu_chr_be_generic_open(s); qemu_chr_fe_take_focus(be);
if (s->be_open) {
qemu_chr_be_generic_open(s);
}
} }
} }
@ -491,38 +511,6 @@ static int mux_chr_new_handler_tag(CharDriverState *chr, Error **errp);
static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context); static void mux_chr_set_handlers(CharDriverState *chr, GMainContext *context);
static void mux_set_focus(MuxDriver *d, int focus); static void mux_set_focus(MuxDriver *d, int focus);
void qemu_chr_add_handlers_full(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque,
GMainContext *context)
{
int tag = 0;
if (s->is_mux) {
tag = mux_chr_new_handler_tag(s, &error_abort);
mux_chr_set_handlers(s, context);
}
qemu_chr_set_handlers(s, fd_can_read, fd_read,
fd_event, opaque, context, tag);
if (s->is_mux) {
mux_set_focus(s->opaque, tag);
}
}
void qemu_chr_add_handlers(CharDriverState *s,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque)
{
qemu_chr_add_handlers_full(s, fd_can_read, fd_read,
fd_event, opaque, NULL);
}
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{ {
return len; return len;
@ -554,7 +542,6 @@ struct MuxDriver {
IOReadHandler *chr_read[MAX_MUX]; IOReadHandler *chr_read[MAX_MUX];
IOEventHandler *chr_event[MAX_MUX]; IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX]; void *ext_opaque[MAX_MUX];
CharDriverState *drv;
CharBackend chr; CharBackend chr;
int focus; int focus;
int mux_cnt; int mux_cnt;
@ -579,7 +566,7 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
MuxDriver *d = chr->opaque; MuxDriver *d = chr->opaque;
int ret; int ret;
if (!d->timestamps) { if (!d->timestamps) {
ret = qemu_chr_fe_write(d->drv, buf, len); ret = qemu_chr_fe_write(&d->chr, buf, len);
} else { } else {
int i; int i;
@ -603,10 +590,11 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
(int)(ti % 1000)); (int)(ti % 1000));
/* 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(d->drv, (uint8_t *)buf1, strlen(buf1)); qemu_chr_fe_write_all(&d->chr,
(uint8_t *)buf1, strlen(buf1));
d->linestart = 0; d->linestart = 0;
} }
ret += qemu_chr_fe_write(d->drv, buf+i, 1); ret += qemu_chr_fe_write(&d->chr, buf + i, 1);
if (buf[i] == '\n') { if (buf[i] == '\n') {
d->linestart = 1; d->linestart = 1;
} }
@ -643,13 +631,13 @@ static void mux_print_help(CharDriverState *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(chr, (uint8_t *)cbuf, strlen(cbuf)); qemu_chr_write_all(chr, (uint8_t *)cbuf, strlen(cbuf));
for (i = 0; mux_help[i] != NULL; i++) { for (i = 0; mux_help[i] != NULL; i++) {
for (j=0; mux_help[i][j] != '\0'; j++) { for (j=0; mux_help[i][j] != '\0'; j++) {
if (mux_help[i][j] == '%') if (mux_help[i][j] == '%')
qemu_chr_fe_write_all(chr, (uint8_t *)ebuf, strlen(ebuf)); qemu_chr_write_all(chr, (uint8_t *)ebuf, strlen(ebuf));
else else
qemu_chr_fe_write_all(chr, (uint8_t *)&mux_help[i][j], 1); qemu_chr_write_all(chr, (uint8_t *)&mux_help[i][j], 1);
} }
} }
} }
@ -674,7 +662,7 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
case 'x': case 'x':
{ {
const char *term = "QEMU: Terminated\n\r"; const char *term = "QEMU: Terminated\n\r";
qemu_chr_fe_write_all(chr, (uint8_t *)term, strlen(term)); qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));
exit(0); exit(0);
break; break;
} }
@ -819,7 +807,9 @@ static Notifier muxes_realize_notify = {
static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond)
{ {
MuxDriver *d = s->opaque; MuxDriver *d = s->opaque;
return d->drv->chr_add_watch(d->drv, cond); CharDriverState *chr = qemu_chr_fe_get_driver(&d->chr);
return chr->chr_add_watch(chr, cond);
} }
static void mux_chr_close(struct CharDriverState *chr) static void mux_chr_close(struct CharDriverState *chr)
@ -889,7 +879,6 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
d = g_new0(MuxDriver, 1); d = g_new0(MuxDriver, 1);
chr->opaque = d; chr->opaque = d;
d->drv = drv;
d->focus = -1; d->focus = -1;
chr->chr_close = mux_chr_close; chr->chr_close = mux_chr_close;
chr->chr_write = mux_chr_write; chr->chr_write = mux_chr_write;
@ -905,7 +894,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
*/ */
chr->explicit_be_open = muxes_realized ? 0 : 1; chr->explicit_be_open = muxes_realized ? 0 : 1;
chr->is_mux = 1; chr->is_mux = 1;
if (!qemu_chr_fe_init(&d->chr, d->drv, errp)) { if (!qemu_chr_fe_init(&d->chr, drv, errp)) {
qemu_chr_free(chr); qemu_chr_free(chr);
return NULL; return NULL;
} }
@ -946,8 +935,8 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
return; return;
} }
qemu_chr_set_handlers(b->chr, fd_can_read, fd_read, qemu_chr_set_handlers(b, fd_can_read, fd_read,
fd_event, opaque, context, b->tag); fd_event, opaque, context);
if (b->chr->is_mux) { if (b->chr->is_mux) {
mux_chr_set_handlers(b->chr, context); mux_chr_set_handlers(b->chr, context);
@ -1364,7 +1353,7 @@ static CharDriverState *qemu_chr_open_stdio(const char *id,
if (opts->has_signal) { if (opts->has_signal) {
stdio_allow_signal = opts->signal; stdio_allow_signal = opts->signal;
} }
qemu_chr_fe_set_echo(chr, false); qemu_chr_set_echo_stdio(chr, false);
return chr; return chr;
} }
@ -2612,7 +2601,7 @@ static CharDriverState *qemu_chr_open_stdio(const char *id,
SetConsoleMode(stdio->hStdIn, dwMode); SetConsoleMode(stdio->hStdIn, dwMode);
chr->chr_set_echo = qemu_chr_set_echo_win_stdio; chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
qemu_chr_fe_set_echo(chr, false); qemu_chr_set_echo_win_stdio(chr, false);
return chr; return chr;
@ -2627,7 +2616,6 @@ err1:
} }
#endif /* !_WIN32 */ #endif /* !_WIN32 */
/***********************************************************/ /***********************************************************/
/* UDP Net console */ /* UDP Net console */
@ -3348,7 +3336,7 @@ static int tcp_chr_wait_connected(CharDriverState *chr, Error **errp)
return 0; return 0;
} }
int qemu_chr_wait_connected(CharDriverState *chr, Error **errp) static int qemu_chr_wait_connected(CharDriverState *chr, Error **errp)
{ {
if (chr->chr_wait_connected) { if (chr->chr_wait_connected) {
return chr->chr_wait_connected(chr, errp); return chr->chr_wait_connected(chr, errp);
@ -3357,6 +3345,11 @@ int qemu_chr_wait_connected(CharDriverState *chr, Error **errp)
return 0; return 0;
} }
int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp)
{
return qemu_chr_wait_connected(be->chr, errp);
}
static void tcp_chr_close(CharDriverState *chr) static void tcp_chr_close(CharDriverState *chr)
{ {
TCPCharDriver *s = chr->opaque; TCPCharDriver *s = chr->opaque;
@ -4155,15 +4148,19 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename)
return chr; return chr;
} }
void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo) void qemu_chr_fe_set_echo(CharBackend *be, bool echo)
{ {
CharDriverState *chr = be->chr;
if (chr->chr_set_echo) { if (chr->chr_set_echo) {
chr->chr_set_echo(chr, echo); chr->chr_set_echo(chr, echo);
} }
} }
void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open) void qemu_chr_fe_set_open(CharBackend *be, int fe_open)
{ {
CharDriverState *chr = be->chr;
if (chr->fe_open == fe_open) { if (chr->fe_open == fe_open) {
return; return;
} }
@ -4173,16 +4170,19 @@ void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open)
} }
} }
void qemu_chr_fe_event(struct CharDriverState *chr, int event) void qemu_chr_fe_event(CharBackend *be, int event)
{ {
CharDriverState *chr = be->chr;
if (chr->chr_fe_event) { if (chr->chr_fe_event) {
chr->chr_fe_event(chr, event); chr->chr_fe_event(chr, event);
} }
} }
guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
GIOFunc func, void *user_data) GIOFunc func, void *user_data)
{ {
CharDriverState *s = be->chr;
GSource *src; GSource *src;
guint tag; guint tag;
@ -4225,8 +4225,10 @@ void qemu_chr_fe_release(CharDriverState *s)
s->avail_connections++; s->avail_connections++;
} }
void qemu_chr_fe_disconnect(CharDriverState *chr) void qemu_chr_fe_disconnect(CharBackend *be)
{ {
CharDriverState *chr = be->chr;
if (chr->chr_disconnect) { if (chr->chr_disconnect) {
chr->chr_disconnect(chr); chr->chr_disconnect(chr);
} }

23
qtest.c
View File

@ -190,7 +190,7 @@ static void qtest_get_time(qemu_timeval *tv)
} }
} }
static void qtest_send_prefix(CharDriverState *chr) static void qtest_send_prefix(CharBackend *chr)
{ {
qemu_timeval tv; qemu_timeval tv;
@ -218,7 +218,7 @@ static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char *fmt, ...)
va_end(ap); va_end(ap);
} }
static void do_qtest_send(CharDriverState *chr, const char *str, size_t len) static void do_qtest_send(CharBackend *chr, const char *str, size_t len)
{ {
qemu_chr_fe_write_all(chr, (uint8_t *)str, len); qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
if (qtest_log_fp && qtest_opened) { if (qtest_log_fp && qtest_opened) {
@ -226,12 +226,12 @@ static void do_qtest_send(CharDriverState *chr, const char *str, size_t len)
} }
} }
static void qtest_send(CharDriverState *chr, const char *str) static void qtest_send(CharBackend *chr, const char *str)
{ {
do_qtest_send(chr, str, strlen(str)); do_qtest_send(chr, str, strlen(str));
} }
static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharDriverState *chr, static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -249,7 +249,7 @@ static void qtest_irq_handler(void *opaque, int n, int level)
qemu_set_irq(old_irq, level); qemu_set_irq(old_irq, level);
if (irq_levels[n] != level) { if (irq_levels[n] != level) {
CharDriverState *chr = qtest_chr.chr; CharBackend *chr = &qtest_chr;
irq_levels[n] = level; irq_levels[n] = level;
qtest_send_prefix(chr); qtest_send_prefix(chr);
qtest_sendf(chr, "IRQ %s %d\n", qtest_sendf(chr, "IRQ %s %d\n",
@ -257,7 +257,7 @@ static void qtest_irq_handler(void *opaque, int n, int level)
} }
} }
static void qtest_process_command(CharDriverState *chr, gchar **words) static void qtest_process_command(CharBackend *chr, gchar **words)
{ {
const gchar *command; const gchar *command;
@ -585,7 +585,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
} }
} }
static void qtest_process_inbuf(CharDriverState *chr, GString *inbuf) static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
{ {
char *end; char *end;
@ -609,7 +609,7 @@ static void qtest_process_inbuf(CharDriverState *chr, GString *inbuf)
static void qtest_read(void *opaque, const uint8_t *buf, int size) static void qtest_read(void *opaque, const uint8_t *buf, int size)
{ {
CharDriverState *chr = opaque; CharBackend *chr = opaque;
g_string_append_len(inbuf, (const gchar *)buf, size); g_string_append_len(inbuf, (const gchar *)buf, size);
qtest_process_inbuf(chr, inbuf); qtest_process_inbuf(chr, inbuf);
@ -686,11 +686,12 @@ void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
qtest_log_fp = stderr; qtest_log_fp = stderr;
} }
qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr); qemu_chr_fe_init(&qtest_chr, chr, errp);
qemu_chr_fe_set_echo(chr, true); qemu_chr_fe_set_handlers(&qtest_chr, qtest_can_read, qtest_read,
qtest_event, &qtest_chr, NULL);
qemu_chr_fe_set_echo(&qtest_chr, true);
inbuf = g_string_new(""); inbuf = g_string_new("");
qemu_chr_fe_init(&qtest_chr, chr, errp);
} }
bool qtest_driver(void) bool qtest_driver(void)

View File

@ -11,6 +11,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "libqtest.h" #include "libqtest.h"
#include "qapi/error.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/range.h" #include "qemu/range.h"
#include "qemu/sockets.h" #include "qemu/sockets.h"
@ -268,7 +269,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
int fd; int fd;
if (s->test_fail) { if (s->test_fail) {
qemu_chr_fe_disconnect(chr->chr); qemu_chr_fe_disconnect(chr);
/* now switch to non-failure */ /* now switch to non-failure */
s->test_fail = false; s->test_fail = false;
} }
@ -283,7 +284,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
if (msg.size) { if (msg.size) {
p += VHOST_USER_HDR_SIZE; p += VHOST_USER_HDR_SIZE;
size = qemu_chr_fe_read_all(chr->chr, p, msg.size); size = qemu_chr_fe_read_all(chr, p, msg.size);
if (size != msg.size) { if (size != msg.size) {
g_test_message("Wrong message size received %d != %d\n", g_test_message("Wrong message size received %d != %d\n",
size, msg.size); size, msg.size);
@ -306,14 +307,14 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
s->test_flags = TEST_FLAGS_END; s->test_flags = TEST_FLAGS_END;
} }
p = (uint8_t *) &msg; p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break; break;
case VHOST_USER_SET_FEATURES: case VHOST_USER_SET_FEATURES:
g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES), g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES),
!=, 0ULL); !=, 0ULL);
if (s->test_flags == TEST_FLAGS_DISCONNECT) { if (s->test_flags == TEST_FLAGS_DISCONNECT) {
qemu_chr_fe_disconnect(chr->chr); qemu_chr_fe_disconnect(chr);
s->test_flags = TEST_FLAGS_BAD; s->test_flags = TEST_FLAGS_BAD;
} }
break; break;
@ -327,7 +328,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ; msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ;
} }
p = (uint8_t *) &msg; p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break; break;
case VHOST_USER_GET_VRING_BASE: case VHOST_USER_GET_VRING_BASE:
@ -336,7 +337,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
msg.size = sizeof(m.payload.state); msg.size = sizeof(m.payload.state);
msg.payload.state.num = 0; msg.payload.state.num = 0;
p = (uint8_t *) &msg; p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
assert(msg.payload.state.index < s->queues * 2); assert(msg.payload.state.index < s->queues * 2);
s->rings &= ~(0x1ULL << msg.payload.state.index); s->rings &= ~(0x1ULL << msg.payload.state.index);
@ -345,7 +346,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
case VHOST_USER_SET_MEM_TABLE: case VHOST_USER_SET_MEM_TABLE:
/* received the mem table */ /* received the mem table */
memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory)); memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory));
s->fds_num = qemu_chr_fe_get_msgfds(chr->chr, s->fds, s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds,
G_N_ELEMENTS(s->fds)); G_N_ELEMENTS(s->fds));
/* signal the test that it can continue */ /* signal the test that it can continue */
@ -355,7 +356,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
case VHOST_USER_SET_VRING_KICK: case VHOST_USER_SET_VRING_KICK:
case VHOST_USER_SET_VRING_CALL: case VHOST_USER_SET_VRING_CALL:
/* consume the fd */ /* consume the fd */
qemu_chr_fe_get_msgfds(chr->chr, &fd, 1); qemu_chr_fe_get_msgfds(chr, &fd, 1);
/* /*
* This is a non-blocking eventfd. * This is a non-blocking eventfd.
* The receive function forces it to be blocking, * The receive function forces it to be blocking,
@ -369,11 +370,11 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
close(s->log_fd); close(s->log_fd);
s->log_fd = -1; s->log_fd = -1;
} }
qemu_chr_fe_get_msgfds(chr->chr, &s->log_fd, 1); qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1);
msg.flags |= VHOST_USER_REPLY_MASK; msg.flags |= VHOST_USER_REPLY_MASK;
msg.size = 0; msg.size = 0;
p = (uint8_t *) &msg; p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE); qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE);
g_cond_signal(&s->data_cond); g_cond_signal(&s->data_cond);
break; break;
@ -388,7 +389,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
msg.size = sizeof(m.payload.u64); msg.size = sizeof(m.payload.u64);
msg.payload.u64 = s->queues; msg.payload.u64 = s->queues;
p = (uint8_t *) &msg; p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr->chr, p, VHOST_USER_HDR_SIZE + msg.size); qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break; break;
default: default:
@ -456,13 +457,14 @@ static void test_server_create_chr(TestServer *server, const gchar *opt)
{ {
gchar *chr_path; gchar *chr_path;
CharDriverState *chr; CharDriverState *chr;
chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt); chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
chr = qemu_chr_new(server->chr_name, chr_path); chr = qemu_chr_new(server->chr_name, chr_path);
qemu_chr_fe_init(&server->chr, chr, &error_abort);
g_free(chr_path); g_free(chr_path);
qemu_chr_add_handlers(server->chr.chr, chr_can_read, chr_read, qemu_chr_fe_init(&server->chr, chr, &error_abort);
chr_event, server); qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
chr_event, server, NULL);
} }
static void test_server_listen(TestServer *server) static void test_server_listen(TestServer *server)
@ -486,8 +488,9 @@ static inline void test_server_connect(TestServer *server)
static gboolean _test_server_free(TestServer *server) static gboolean _test_server_free(TestServer *server)
{ {
int i; int i;
CharDriverState *chr = qemu_chr_fe_get_driver(&server->chr);
qemu_chr_delete(server->chr.chr); qemu_chr_delete(chr);
for (i = 0; i < server->fds_num; i++) { for (i = 0; i < server->fds_num; i++) {
close(server->fds[i]); close(server->fds[i]);
@ -724,7 +727,7 @@ reconnect_cb(gpointer user_data)
{ {
TestServer *s = user_data; TestServer *s = user_data;
qemu_chr_fe_disconnect(s->chr.chr); qemu_chr_fe_disconnect(&s->chr);
return FALSE; return FALSE;
} }