qemu_irq rx_dma;
qemu_irq tx_dma;
uint32_t enable;
- CharDriverState *chr;
+ CharBackend chr;
uint8_t control[3];
uint8_t status[2];
pxa2xx_fir_update(s);
break;
case ICDR:
- if (s->control[2] & (1 << 2)) /* TXP */
+ if (s->control[2] & (1 << 2)) { /* TXP */
ch = value;
- else
+ } else {
ch = ~value;
- if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */
+ }
+ if (s->chr.chr && s->enable && (s->control[0] & (1 << 3))) { /* TXE */
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
+ }
break;
case ICSR0:
s->status[0] &= ~(value & 0x66);
{
PXA2xxFIrState *s = PXA2XX_FIR(dev);
- if (s->chr) {
- qemu_chr_fe_claim_no_fail(s->chr);
- qemu_chr_add_handlers(s->chr, pxa2xx_fir_is_empty,
+ if (s->chr.chr) {
+ qemu_chr_fe_claim_no_fail(s->chr.chr);
+ qemu_chr_add_handlers(s->chr.chr, pxa2xx_fir_is_empty,
pxa2xx_fir_rx, pxa2xx_fir_event, s);
}
}
SysBusDevice parent_obj;
MemoryRegion iomem;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint8_t utcr0;
ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits;
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
- if (s->chr) {
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+ if (s->chr.chr) {
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
}
DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
- } else if (s->chr) {
+ } else if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &s->tx_fifo[s->tx_start], 1);
+ qemu_chr_fe_write_all(s->chr.chr, &s->tx_fifo[s->tx_start], 1);
}
s->tx_start = (s->tx_start + 1) % 8;
s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr,
strongarm_uart_can_receive,
strongarm_uart_receive,
strongarm_uart_event,
s->read_pos = 0;
}
}
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
bcm2835_aux_update(s);
return c;
case AUX_MU_IO_REG:
/* "DLAB bit set means access baudrate register" is NYI */
ch = value;
- if (s->chr) {
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
break;
{
BCM2835AuxState *s = BCM2835_AUX(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, bcm2835_aux_can_receive,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, bcm2835_aux_can_receive,
bcm2835_aux_receive, NULL, s);
}
}
{
s->rx_wpos = 0;
s->rx_count = 0;
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
}
{
int break_enabled = 1;
- if (s->chr) {
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
+ if (s->chr.chr) {
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_BREAK,
&break_enabled);
}
}
packet_size += ssp.data_bits + ssp.stop_bits;
s->char_tx_time = (NANOSECONDS_PER_SECOND / ssp.speed) * packet_size;
- if (s->chr) {
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+ if (s->chr.chr) {
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
}
}
int ret;
/* instant drain the fifo when there's no back-end */
- if (!s->chr) {
+ if (!s->chr.chr) {
s->tx_count = 0;
return FALSE;
}
return FALSE;
}
- ret = qemu_chr_fe_write(s->chr, s->tx_fifo, s->tx_count);
+ ret = qemu_chr_fe_write(s->chr.chr, s->tx_fifo, s->tx_count);
if (ret >= 0) {
s->tx_count -= ret;
}
if (s->tx_count) {
- guint r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
+ guint r = qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP,
cadence_uart_xmit, s);
if (!r) {
s->tx_count = 0;
*c = s->rx_fifo[rx_rpos];
s->rx_count--;
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
} else {
*c = 0;
s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
fifo_trigger_update, s);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, uart_can_receive, uart_receive,
uart_event, s);
}
}
typedef struct DebugconState {
MemoryRegion io;
- CharDriverState *chr;
+ CharBackend chr;
uint32_t readback;
} DebugconState;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
static void debugcon_realize_core(DebugconState *s, Error **errp)
{
- if (!s->chr) {
+ if (!s->chr.chr) {
error_setg(errp, "Can't create debugcon device, empty char device");
return;
}
- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
+ qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, s);
}
static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
switch (addr) {
case R_TX:
- if (s->chr) {
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
break;
{
DigicUartState *s = DIGIC_UART(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
}
}
uint32_t reg;
uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
SERIOQueue queue;
- CharDriverState *chr;
+ CharBackend chr;
int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
int disabled;
int clock;
int speed, parity, data_bits, stop_bits;
QEMUSerialSetParams ssp;
- if (!s->chr || s->type != ser)
+ if (!s->chr.chr || s->type != ser)
return;
if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits;
trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
}
static void escc_mem_write(void *opaque, hwaddr addr,
trace_escc_mem_writeb_data(CHN_C(s), val);
s->tx = val;
if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
- if (s->chr)
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &s->tx, 1);
- else if (s->type == kbd && !s->disabled) {
+ qemu_chr_fe_write_all(s->chr.chr, &s->tx, 1);
+ } else if (s->type == kbd && !s->disabled) {
handle_kbd_command(s, val);
}
}
else
ret = s->rx;
trace_escc_mem_readb_data(CHN_C(s), ret);
- if (s->chr)
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
+ }
return ret;
default:
break;
ESCC_SIZE << s->it_shift);
for (i = 0; i < 2; i++) {
- if (s->chn[i].chr) {
+ if (s->chn[i].chr.chr) {
s->chn[i].clock = s->frequency / 2;
- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
+ qemu_chr_add_handlers(s->chn[i].chr.chr, serial_can_receive,
serial_receive1, serial_event, &s->chn[i]);
}
}
SysBusDevice parent_obj;
MemoryRegion mmio;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
int pending_tx;
case RW_DOUT:
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
s->regs[R_INTR] |= 3;
s->pending_tx = 1;
s->regs[addr] = value;
{
ETRAXSerial *s = ETRAX_SERIAL(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr,
serial_can_receive, serial_receive,
serial_event, s);
}
Exynos4210UartFIFO rx;
Exynos4210UartFIFO tx;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint32_t channel;
ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits;
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n",
s->channel, speed, parity, data_bits, stop_bits);
break;
case UTXH:
- if (s->chr) {
+ if (s->chr.chr) {
s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY |
UTRSTAT_Tx_BUFFER_EMPTY);
ch = (uint8_t)val;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
#if DEBUG_Tx_DATA
fprintf(stderr, "%c", ch);
#endif
sysbus_init_irq(dev, &s->irq);
- qemu_chr_add_handlers(s->chr, exynos4210_uart_can_receive,
+ qemu_chr_add_handlers(s->chr.chr, exynos4210_uart_can_receive,
exynos4210_uart_receive, exynos4210_uart_event, s);
return 0;
MemoryRegion iomem;
qemu_irq irq;
- CharDriverState *chr;
+ CharBackend chr;
/* registers */
uint32_t status;
case DATA_OFFSET:
case DATA_OFFSET + 3: /* When only one byte write */
/* Transmit when character device available and transmitter enabled */
- if ((uart->chr) && (uart->control & UART_TRANSMIT_ENABLE)) {
+ if (uart->chr.chr && (uart->control & UART_TRANSMIT_ENABLE)) {
c = value & 0xFF;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(uart->chr, &c, 1);
+ qemu_chr_fe_write_all(uart->chr.chr, &c, 1);
/* Generate interrupt */
if (uart->control & UART_TRANSMIT_INTERRUPT) {
qemu_irq_pulse(uart->irq);
{
UART *uart = GRLIB_APB_UART(dev);
- qemu_chr_add_handlers(uart->chr,
+ qemu_chr_add_handlers(uart->chr.chr,
grlib_apbuart_can_receive,
grlib_apbuart_receive,
grlib_apbuart_event,
s->usr2 &= ~USR2_RDR;
s->uts1 |= UTS1_RXEMPTY;
imx_update(s);
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
}
return c;
unsigned char ch;
DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n",
- offset, (unsigned int)value, s->chr ? s->chr->label : "NODEV");
+ offset, (unsigned int)value,
+ s->chr.chr ? s->chr.chr->label : "NODEV");
switch (offset >> 2) {
case 0x10: /* UTXD */
ch = value;
if (s->ucr2 & UCR2_TXEN) {
- if (s->chr) {
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
s->usr1 &= ~USR1_TRDY;
imx_update(s);
}
if (value & UCR2_RXEN) {
if (!(s->ucr2 & UCR2_RXEN)) {
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
}
}
{
IMXSerialState *s = IMX_SERIAL(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, imx_can_receive, imx_receive,
imx_event, s);
} else {
DPRINTF("No char dev for uart\n");
struct SCC2698Channel {
IPOctalState *ipoctal;
- CharDriverState *dev;
+ CharBackend dev;
bool rx_enabled;
uint8_t mr[2];
uint8_t mr_idx;
if (ch->rx_pending == 0) {
ch->sr &= ~SR_RXRDY;
blk->isr &= ~ISR_RXRDY(channel);
- if (ch->dev) {
- qemu_chr_accept_input(ch->dev);
+ if (ch->dev.chr) {
+ qemu_chr_accept_input(ch->dev.chr);
}
} else {
ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE;
case REG_THRb:
if (ch->sr & SR_TXRDY) {
DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg);
- if (ch->dev) {
+ if (ch->dev.chr) {
uint8_t thr = reg;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(ch->dev, &thr, 1);
+ qemu_chr_fe_write_all(ch->dev.chr, &thr, 1);
}
} else {
DPRINTF("Write THR%c (0x%x), Tx disabled\n", channel + 'a', reg);
ch->ipoctal = s;
/* Redirect IP-Octal channels to host character devices */
- if (ch->dev) {
- qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
+ if (ch->dev.chr) {
+ qemu_chr_add_handlers(ch->dev.chr, hostdev_can_receive,
hostdev_receive, hostdev_event, ch);
DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
} else {
struct LM32JuartState {
SysBusDevice parent_obj;
- CharDriverState *chr;
+ CharBackend chr;
uint32_t jtx;
uint32_t jrx;
trace_lm32_juart_set_jtx(s->jtx);
s->jtx = jtx;
- if (s->chr) {
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
}
{
LM32JuartState *s = LM32_JUART(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, juart_can_rx,
+ juart_rx, juart_event, s);
}
}
SysBusDevice parent_obj;
MemoryRegion iomem;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint32_t regs[R_MAX];
r = s->regs[R_RXTX];
s->regs[R_LSR] &= ~LSR_DR;
uart_update_irq(s);
- qemu_chr_accept_input(s->chr);
+ qemu_chr_accept_input(s->chr.chr);
break;
case R_IIR:
case R_LSR:
addr >>= 2;
switch (addr) {
case R_RXTX:
- if (s->chr) {
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
break;
case R_IER:
{
LM32UartState *s = LM32_UART(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
}
}
SysBusDevice parent_obj;
MemoryRegion regs_region;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint32_t regs[R_MAX];
addr >>= 2;
switch (addr) {
case R_RXTX:
- if (s->chr) {
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ if (s->chr.chr) {
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
s->regs[R_STAT] |= STAT_TX_EVT;
break;
case R_STAT:
/* write one to clear bits */
s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT));
- qemu_chr_accept_input(s->chr);
+ qemu_chr_accept_input(s->chr.chr);
break;
default:
{
MilkymistUartState *s = MILKYMIST_UART(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
}
}
uint8_t control;
qemu_irq irq;
int irq_pending;
- CharDriverState *chr;
+ CharBackend chr;
int hw_driver;
int epp_timeout;
uint32_t last_read_offset; /* For debugging */
if ((s->control & PARA_CTR_STROBE) == 0)
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &s->dataw, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &s->dataw, 1);
} else {
if (s->control & PARA_CTR_INTEN) {
s->irq_pending = 1;
if (s->dataw == val)
return;
pdebug("wd%02x\n", val);
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
s->dataw = val;
break;
case PARA_REG_STS:
} else {
dir = 0;
}
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_DATA_DIR, &dir);
parm &= ~PARA_CTR_DIR;
}
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
s->control = val;
break;
case PARA_REG_EPP_ADDR:
pdebug("wa%02x s\n", val);
else {
struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
- if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
+ if (qemu_chr_fe_ioctl(s->chr.chr,
+ CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
s->epp_timeout = 1;
pdebug("wa%02x t\n", val);
}
pdebug("we%02x s\n", val);
else {
struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
- if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
+ if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
s->epp_timeout = 1;
pdebug("we%02x t\n", val);
}
pdebug("we%04x s\n", val);
return;
}
- err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
+ err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
if (err) {
s->epp_timeout = 1;
pdebug("we%04x t\n", val);
pdebug("we%08x s\n", val);
return;
}
- err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
+ err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
if (err) {
s->epp_timeout = 1;
pdebug("we%08x t\n", val);
addr &= 7;
switch(addr) {
case PARA_REG_DATA:
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_DATA, &ret);
if (s->last_read_offset != addr || s->datar != ret)
pdebug("rd%02x\n", ret);
s->datar = ret;
break;
case PARA_REG_STS:
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_STATUS, &ret);
ret &= ~PARA_STS_TMOUT;
if (s->epp_timeout)
ret |= PARA_STS_TMOUT;
/* s->control has some bits fixed to 1. It is zero only when
it has not been yet written to. */
if (s->control == 0) {
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
if (s->last_read_offset != addr)
pdebug("rc%02x\n", ret);
s->control = ret;
}
break;
case PARA_REG_EPP_ADDR:
- if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
+ if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
+ (PARA_CTR_DIR | PARA_CTR_INIT))
/* Controls not correct for EPP addr cycle, so do nothing */
pdebug("ra%02x s\n", ret);
else {
struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
- if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
+ if (qemu_chr_fe_ioctl(s->chr.chr,
+ CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
s->epp_timeout = 1;
pdebug("ra%02x t\n", ret);
}
}
break;
case PARA_REG_EPP_DATA:
- if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
+ if ((s->control & (PARA_CTR_DIR | PARA_CTR_SIGNAL)) !=
+ (PARA_CTR_DIR | PARA_CTR_INIT))
/* Controls not correct for EPP data cycle, so do nothing */
pdebug("re%02x s\n", ret);
else {
struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
- if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
+ if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
s->epp_timeout = 1;
pdebug("re%02x t\n", ret);
}
pdebug("re%04x s\n", eppdata);
return eppdata;
}
- err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
+ err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
ret = le16_to_cpu(eppdata);
if (err) {
pdebug("re%08x s\n", eppdata);
return eppdata;
}
- err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
+ err = qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
ret = le32_to_cpu(eppdata);
if (err) {
int base;
uint8_t dummy;
- if (!s->chr) {
+ if (!s->chr.chr) {
error_setg(errp, "Can't create parallel device, empty char device");
return;
}
isa_init_irq(isadev, &s->irq, isa->isairq);
qemu_register_reset(parallel_reset, s);
- if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
+ if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
s->hw_driver = 1;
s->status = dummy;
}
s = g_malloc0(sizeof(ParallelState));
s->irq = irq;
- s->chr = chr;
+ qemu_chr_fe_init(&s->chr, chr, &error_abort);
s->it_shift = it_shift;
qemu_register_reset(parallel_reset, s);
int read_pos;
int read_count;
int read_trigger;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
const unsigned char *id;
} PL011State;
trace_pl011_read_fifo(s->read_count);
s->rsr = c >> 8;
pl011_update(s);
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
r = c;
break;
case 0: /* UARTDR */
/* ??? Check if transmitter is enabled. */
ch = value;
- if (s->chr)
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
+ }
s->int_level |= PL011_INT_TX;
pl011_update(s);
break;
{
PL011State *s = PL011(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, pl011_can_receive, pl011_receive,
pl011_event, s);
}
}
typedef struct SCLPConsoleLM {
SCLPEvent event;
- CharDriverState *chr;
+ CharBackend chr;
bool echo; /* immediate echo of input if true */
uint32_t write_errors; /* errors writing to char layer */
uint32_t length; /* length of byte stream in buffer */
if (scon->echo) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(scon->chr, buf, size);
+ qemu_chr_fe_write_all(scon->chr.chr, buf, size);
}
}
{
SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);
- if (!scon->chr) {
+ if (!scon->chr.chr) {
/* If there's no backend, we can just say we consumed all data. */
return len;
}
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- return qemu_chr_fe_write_all(scon->chr, buf, len);
+ return qemu_chr_fe_write_all(scon->chr.chr, buf, len);
}
static int process_mdb(SCLPEvent *event, MDBO *mdbo)
}
console_available = true;
- if (scon->chr) {
- qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon);
+ if (scon->chr.chr) {
+ qemu_chr_add_handlers(scon->chr.chr, chr_can_read,
+ chr_read, NULL, scon);
}
return 0;
typedef struct SCLPConsole {
SCLPEvent event;
- CharDriverState *chr;
+ CharBackend chr;
uint8_t iov[SIZE_BUFFER_VT220];
uint32_t iov_sclp; /* offset in buf for SCLP read operation */
uint32_t iov_bs; /* offset in buf for char layer read operation */
{
SCLPConsole *scon = SCLP_CONSOLE(event);
- if (!scon->chr) {
+ if (!scon->chr.chr) {
/* If there's no backend, we can just say we consumed all data. */
return len;
}
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- return qemu_chr_fe_write_all(scon->chr, buf, len);
+ return qemu_chr_fe_write_all(scon->chr.chr, buf, len);
}
static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
return -1;
}
console_available = true;
- if (scon->chr) {
- qemu_chr_add_handlers(scon->chr, chr_can_read,
+ if (scon->chr.chr) {
+ qemu_chr_add_handlers(scon->chr.chr, chr_can_read,
chr_read, NULL, scon);
}
ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits;
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
DPRINTF("speed=%d parity=%c data=%d stop=%d\n",
speed, parity, data_bits, stop_bits);
timer_del(s->modem_status_poll);
- if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
+ if (qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_GET_TIOCM,
+ &flags) == -ENOTSUP) {
s->poll_msl = -1;
return;
}
if (s->mcr & UART_MCR_LOOP) {
/* in loopback mode, say that we just received a char */
serial_receive1(s, &s->tsr, 1);
- } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1 &&
+ } else if (qemu_chr_fe_write(s->chr.chr, &s->tsr, 1) != 1 &&
s->tsr_retry < MAX_XMIT_RETRY) {
assert(s->watch_tag == 0);
- s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
- serial_watch_cb, s);
+ s->watch_tag =
+ qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP,
+ serial_watch_cb, s);
if (s->watch_tag > 0) {
s->tsr_retry++;
return;
break_enable = (val >> 6) & 1;
if (break_enable != s->last_break_enable) {
s->last_break_enable = break_enable;
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
+ qemu_chr_fe_ioctl(s->chr.chr, CHR_IOCTL_SERIAL_SET_BREAK,
&break_enable);
}
}
if (s->poll_msl >= 0 && old_mcr != s->mcr) {
- qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
+ qemu_chr_fe_ioctl(s->chr.chr,
+ CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
if (val & UART_MCR_DTR)
flags |= CHR_TIOCM_DTR;
- qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
+ qemu_chr_fe_ioctl(s->chr.chr,
+ CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
/* Update the modem status after a one-character-send wait-time, since there may be a response
from the device/computer at the other end of the serial line */
timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time);
serial_update_irq(s);
if (!(s->mcr & UART_MCR_LOOP)) {
/* in loopback mode, don't receive any data */
- qemu_chr_accept_input(s->chr);
+ qemu_chr_accept_input(s->chr.chr);
}
}
break;
}
assert(s->watch_tag == 0);
- s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
+ s->watch_tag = qemu_chr_fe_add_watch(s->chr.chr, G_IO_OUT | G_IO_HUP,
serial_watch_cb, s);
} else {
/* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */
void serial_realize_core(SerialState *s, Error **errp)
{
- if (!s->chr) {
+ if (!s->chr.chr) {
error_setg(errp, "Can't create serial device, empty char device");
return;
}
s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) fifo_timeout_int, s);
qemu_register_reset(serial_reset, s);
- qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
+ qemu_chr_add_handlers(s->chr.chr, serial_can_receive1, serial_receive1,
serial_event, s);
fifo8_create(&s->recv_fifo, UART_FIFO_LENGTH);
fifo8_create(&s->xmit_fifo, UART_FIFO_LENGTH);
void serial_exit_core(SerialState *s)
{
- qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ qemu_chr_add_handlers(s->chr.chr, NULL, NULL, NULL, NULL);
qemu_unregister_reset(serial_reset, s);
}
s->irq = irq;
s->baudbase = baudbase;
- s->chr = chr;
+ qemu_chr_fe_init(&s->chr, chr, &error_abort);
serial_realize_core(s, &error_fatal);
vmstate_register(NULL, base, &vmstate_serial, s);
s->it_shift = it_shift;
s->irq = irq;
s->baudbase = baudbase;
- s->chr = chr;
+ qemu_chr_fe_init(&s->chr, chr, &error_abort);
serial_realize_core(s, &error_fatal);
vmstate_register(NULL, base, &vmstate_serial, s);
typedef struct VIOsPAPRVTYDevice {
VIOsPAPRDevice sdev;
- CharDriverState *chardev;
+ CharBackend chardev;
uint32_t in, out;
uint8_t buf[VTERM_BUFSIZE];
} VIOsPAPRVTYDevice;
buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
}
- qemu_chr_accept_input(dev->chardev);
+ qemu_chr_accept_input(dev->chardev.chr);
return n;
}
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(dev->chardev, buf, len);
+ qemu_chr_fe_write_all(dev->chardev.chr, buf, len);
}
static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
{
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
- if (!dev->chardev) {
+ if (!dev->chardev.chr) {
error_setg(errp, "chardev property not set");
return;
}
- qemu_chr_add_handlers(dev->chardev, vty_can_receive,
+ qemu_chr_add_handlers(dev->chardev.chr, vty_can_receive,
vty_receive, NULL, dev);
}
case USART_SR:
retvalue = s->usart_sr;
s->usart_sr &= ~USART_SR_TC;
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
return retvalue;
case USART_DR:
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
s->usart_sr |= USART_SR_TXE;
s->usart_sr &= ~USART_SR_RXNE;
- if (s->chr) {
- qemu_chr_accept_input(s->chr);
+ if (s->chr.chr) {
+ qemu_chr_accept_input(s->chr.chr);
}
qemu_set_irq(s->irq, 0);
return s->usart_dr & 0x3FF;
case USART_DR:
if (value < 0xF000) {
ch = value;
- if (s->chr) {
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
}
s->usart_sr |= USART_SR_TC;
s->usart_sr &= ~USART_SR_TXE;
{
STM32F2XXUsartState *s = STM32F2XX_USART(dev);
- if (s->chr) {
- qemu_chr_add_handlers(s->chr, stm32f2xx_usart_can_receive,
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, stm32f2xx_usart_can_receive,
stm32f2xx_usart_receive, NULL, s);
}
}
typedef struct VirtConsole {
VirtIOSerialPort parent_obj;
- CharDriverState *chr;
+ CharBackend chr;
guint watch;
} VirtConsole;
VirtConsole *vcon = VIRTIO_CONSOLE(port);
ssize_t ret;
- if (!vcon->chr) {
+ if (!vcon->chr.chr) {
/* If there's no backend, we can just say we consumed all data. */
return len;
}
- ret = qemu_chr_fe_write(vcon->chr, buf, len);
+ ret = qemu_chr_fe_write(vcon->chr.chr, buf, len);
trace_virtio_console_flush_buf(port->id, len, ret);
if (ret < len) {
if (!k->is_console) {
virtio_serial_throttle_port(port, true);
if (!vcon->watch) {
- vcon->watch = qemu_chr_fe_add_watch(vcon->chr,
- G_IO_OUT|G_IO_HUP,
+ vcon->watch = qemu_chr_fe_add_watch(vcon->chr.chr,
+ G_IO_OUT | G_IO_HUP,
chr_write_unblocked, vcon);
}
}
DeviceState *dev = DEVICE(port);
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
- if (vcon->chr && !k->is_console) {
- qemu_chr_fe_set_open(vcon->chr, guest_connected);
+ if (vcon->chr.chr && !k->is_console) {
+ qemu_chr_fe_set_open(vcon->chr.chr, guest_connected);
}
if (dev->id) {
{
VirtConsole *vcon = VIRTIO_CONSOLE(port);
- if (vcon->chr) {
- qemu_chr_accept_input(vcon->chr);
+ if (vcon->chr.chr) {
+ qemu_chr_accept_input(vcon->chr.chr);
}
}
return;
}
- if (vcon->chr) {
+ if (vcon->chr.chr) {
/*
* For consoles we don't block guest data transfer just
* because nothing is connected - we'll just let it go
* trigger open/close of the device
*/
if (k->is_console) {
- vcon->chr->explicit_fe_open = 0;
- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read,
+ vcon->chr.chr->explicit_fe_open = 0;
+ qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read,
NULL, vcon);
virtio_serial_open(port);
} else {
- vcon->chr->explicit_fe_open = 1;
- qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read,
+ vcon->chr.chr->explicit_fe_open = 1;
+ qemu_chr_add_handlers(vcon->chr.chr, chr_can_read, chr_read,
chr_event, vcon);
}
}
SysBusDevice parent_obj;
MemoryRegion mmio;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint8_t rx_fifo[8];
s->rx_fifo_len--;
uart_update_status(s);
uart_update_irq(s);
- qemu_chr_accept_input(s->chr);
+ qemu_chr_accept_input(s->chr.chr);
break;
default:
break;
case R_TX:
- if (s->chr)
+ if (s->chr.chr) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->chr, &ch, 1);
-
+ qemu_chr_fe_write_all(s->chr.chr, &ch, 1);
+ }
s->regs[addr] = value;
/* hax. */
{
XilinxUARTLite *s = XILINX_UARTLITE(dev);
- if (s->chr)
- qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+ if (s->chr.chr) {
+ qemu_chr_add_handlers(s->chr.chr, uart_can_rx, uart_rx, uart_event, s);
+ }
}
static void xilinx_uartlite_init(Object *obj)
/* --- character device --- */
-static void parse_chr(DeviceState *dev, const char *str, void **ptr,
- const char *propname, Error **errp)
+static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
{
- CharDriverState *chr = qemu_chr_find(str);
- if (chr == NULL) {
- error_setg(errp, "Property '%s.%s' can't find value '%s'",
- object_get_typename(OBJECT(dev)), propname, str);
- return;
- }
- if (qemu_chr_fe_claim(chr) != 0) {
- error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
- object_get_typename(OBJECT(dev)), propname, str);
- return;
- }
- *ptr = chr;
+ DeviceState *dev = DEVICE(obj);
+ CharBackend *be = qdev_get_prop_ptr(dev, opaque);
+ char *p;
+
+ p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
+ visit_type_str(v, name, &p, errp);
+ g_free(p);
}
-static void release_chr(Object *obj, const char *name, void *opaque)
+static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
{
DeviceState *dev = DEVICE(obj);
+ Error *local_err = NULL;
Property *prop = opaque;
- CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
- CharDriverState *chr = *ptr;
+ CharBackend *be = qdev_get_prop_ptr(dev, prop);
+ CharDriverState *s;
+ char *str;
- if (chr) {
- qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL);
- qemu_chr_fe_release(chr);
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
}
-}
+ visit_type_str(v, name, &str, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
-static char *print_chr(void *ptr)
-{
- CharDriverState *chr = ptr;
- const char *val = chr->label ? chr->label : "";
+ if (!*str) {
+ g_free(str);
+ be->chr = NULL;
+ return;
+ }
- return g_strdup(val);
-}
+ s = qemu_chr_find(str);
+ g_free(str);
+ if (s == NULL) {
+ error_setg(errp, "Property '%s.%s' can't find value '%s'",
+ object_get_typename(obj), prop->name, str);
+ return;
+ }
+ if (qemu_chr_fe_claim(s) != 0) {
+ error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
+ object_get_typename(obj), prop->name, str);
+ return;
+ }
-static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
-{
- get_pointer(obj, v, opaque, print_chr, name, errp);
+ qemu_chr_fe_init(be, s, errp);
}
-static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
+static void release_chr(Object *obj, const char *name, void *opaque)
{
- set_pointer(obj, v, opaque, parse_chr, name, errp);
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ CharBackend *be = qdev_get_prop_ptr(dev, prop);
+
+ if (be->chr) {
+ qemu_chr_fe_set_handlers(be, NULL, NULL, NULL, NULL, NULL);
+ qemu_chr_fe_release(be->chr);
+ }
}
PropertyInfo qdev_prop_chr = {
typedef struct IPMIBmcExtern {
IPMIBmc parent;
- CharDriverState *chr;
+ CharBackend chr;
bool connected;
goto check_reset;
}
send:
- ret = qemu_chr_fe_write(ibe->chr, ibe->outbuf + ibe->outpos,
+ ret = qemu_chr_fe_write(ibe->chr.chr, ibe->outbuf + ibe->outpos,
ibe->outlen - ibe->outpos);
if (ret > 0) {
ibe->outpos += ret;
{
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
- if (!ibe->chr) {
+ if (!ibe->chr.chr) {
error_setg(errp, "IPMI external bmc requires chardev attribute");
return;
}
- qemu_chr_add_handlers(ibe->chr, can_receive, receive, chr_event, ibe);
+ qemu_chr_add_handlers(ibe->chr.chr, can_receive, receive, chr_event, ibe);
}
static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)
/* exactly one of these two may be set */
HostMemoryBackend *hostmem; /* with interrupts */
- CharDriverState *server_chr; /* without interrupts */
+ CharBackend server_chr; /* without interrupts */
/* registers */
uint32_t intrmask;
msg = le64_to_cpu(s->msg_buf);
s->msg_buffered_bytes = 0;
- fd = qemu_chr_fe_get_msgfd(s->server_chr);
+ fd = qemu_chr_fe_get_msgfd(s->server_chr.chr);
process_msg(s, msg, fd, &err);
if (err) {
n = 0;
do {
- ret = qemu_chr_fe_read_all(s->server_chr, (uint8_t *)&msg + n,
+ ret = qemu_chr_fe_read_all(s->server_chr.chr, (uint8_t *)&msg + n,
sizeof(msg) - n);
if (ret < 0 && ret != -EINTR) {
error_setg_errno(errp, -ret, "read from server failed");
n += ret;
} while (n < sizeof(msg));
- *pfd = qemu_chr_fe_get_msgfd(s->server_chr);
+ *pfd = qemu_chr_fe_get_msgfd(s->server_chr.chr);
return msg;
}
s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem,
&error_abort);
} else {
- assert(s->server_chr);
+ assert(s->server_chr.chr);
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
- s->server_chr->filename);
+ s->server_chr.chr->filename);
/* we allocate enough space for 16 peers and grow as needed */
resize_peers(s, 16);
return;
}
- qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive,
+ qemu_chr_add_handlers(s->server_chr.chr, ivshmem_can_receive,
ivshmem_read, NULL, s);
if (ivshmem_setup_interrupts(s) < 0) {
{
IVShmemState *s = IVSHMEM_COMMON(dev);
- if (!s->server_chr) {
+ if (!s->server_chr.chr) {
error_setg(errp, "You must specify a 'chardev'");
return;
}
" or ivshmem-doorbell instead");
}
- if (!!s->server_chr + !!s->shmobj != 1) {
+ if (!!s->server_chr.chr + !!s->shmobj != 1) {
error_setg(errp, "You must specify either 'shm' or 'chardev'");
return;
}
struct PassthruState {
CCIDCardState base;
- CharDriverState *cs;
+ CharBackend cs;
uint8_t vscard_in_data[VSCARD_IN_SIZE];
uint32_t vscard_in_pos;
uint32_t vscard_in_hdr;
scr_msg_header.length = htonl(length);
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->cs, (uint8_t *)&scr_msg_header,
+ qemu_chr_fe_write_all(s->cs.chr, (uint8_t *)&scr_msg_header,
sizeof(VSCMsgHeader));
- qemu_chr_fe_write_all(s->cs, payload, length);
+ qemu_chr_fe_write_all(s->cs.chr, payload, length);
}
static void ccid_card_vscard_send_apdu(PassthruState *s,
static void ccid_card_vscard_drop_connection(PassthruState *card)
{
- qemu_chr_delete(card->cs);
+ qemu_chr_delete(card->cs.chr);
card->vscard_in_pos = card->vscard_in_hdr = 0;
}
{
PassthruState *card = PASSTHRU_CCID_CARD(base);
- if (!card->cs) {
+ if (!card->cs.chr) {
printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
return;
}
card->vscard_in_pos = 0;
card->vscard_in_hdr = 0;
- if (card->cs) {
+ if (card->cs.chr) {
DPRINTF(card, D_INFO, "initing chardev\n");
- qemu_chr_add_handlers(card->cs,
+ qemu_chr_add_handlers(card->cs.chr,
ccid_card_vscard_can_read,
ccid_card_vscard_read,
ccid_card_vscard_event, card);
uint8_t event_trigger;
QEMUSerialSetParams params;
int latency; /* ms */
- CharDriverState *cs;
+ CharBackend cs;
} USBSerialState;
#define TYPE_USB_SERIAL "usb-serial-dev"
int flags;
uint8_t ret;
- if (qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP)
+ if (qemu_chr_fe_ioctl(s->cs.chr,
+ CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
return FTDI_CTS|FTDI_DSR|FTDI_RLSD;
+ }
ret = 0;
if (flags & CHR_TIOCM_CTS)
case DeviceOutVendor | FTDI_SET_MDM_CTRL:
{
static int flags;
- qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
+ qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
if (value & FTDI_SET_RTS) {
if (value & FTDI_RTS)
flags |= CHR_TIOCM_RTS;
else
flags &= ~CHR_TIOCM_DTR;
}
- qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
+ qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
break;
}
case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
divisor = 1;
s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8);
- qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
+ qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
break;
}
case DeviceOutVendor | FTDI_SET_DATA:
DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
goto fail;
}
- qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
+ qemu_chr_fe_ioctl(s->cs.chr, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
/* TODO: TX ON/OFF */
break;
case DeviceInVendor | FTDI_GET_MDM_ST:
iov = p->iov.iov + i;
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(s->cs, iov->iov_base, iov->iov_len);
+ qemu_chr_fe_write_all(s->cs.chr, iov->iov_base, iov->iov_len);
}
p->actual_length = p->iov.size;
break;
usb_desc_init(dev);
dev->auto_attach = 0;
- if (!s->cs) {
+ if (!s->cs.chr) {
error_setg(errp, "Property chardev is required");
return;
}
return;
}
- qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
+ qemu_chr_add_handlers(s->cs.chr, usb_serial_can_read, usb_serial_read,
usb_serial_event, s);
usb_serial_handle_reset(dev);
- if (s->cs->be_open && !dev->attached) {
+ if (s->cs.chr->be_open && !dev->attached) {
usb_device_attach(dev, &error_abort);
}
}
struct USBRedirDevice {
USBDevice dev;
/* Properties */
- CharDriverState *cs;
+ CharBackend cs;
uint8_t debug;
char *filter_str;
int32_t bootindex;
USBRedirDevice *dev = priv;
int r;
- if (!dev->cs->be_open) {
+ if (!dev->cs.chr->be_open) {
return 0;
}
return 0;
}
- r = qemu_chr_fe_write(dev->cs, data, count);
+ r = qemu_chr_fe_write(dev->cs.chr, data, count);
if (r < count) {
if (!dev->watch) {
- dev->watch = qemu_chr_fe_add_watch(dev->cs, G_IO_OUT|G_IO_HUP,
+ dev->watch = qemu_chr_fe_add_watch(dev->cs.chr, G_IO_OUT | G_IO_HUP,
usbredir_write_unblocked, dev);
}
if (r < 0) {
USBRedirDevice *dev = USB_REDIRECT(udev);
int i;
- if (dev->cs == NULL) {
+ if (dev->cs.chr == NULL) {
error_setg(errp, QERR_MISSING_PARAMETER, "chardev");
return;
}
dev->compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH;
/* Let the backend know we are ready */
- qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
+ qemu_chr_add_handlers(dev->cs.chr, usbredir_chardev_can_read,
usbredir_chardev_read, usbredir_chardev_event, dev);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
{
USBRedirDevice *dev = USB_REDIRECT(udev);
- qemu_chr_delete(dev->cs);
- dev->cs = NULL;
+ qemu_chr_delete(dev->cs.chr);
+ dev->cs.chr = NULL;
/* Note must be done after qemu_chr_close, as that causes a close event */
qemu_bh_delete(dev->chardev_close_bh);
qemu_bh_delete(dev->device_reject_bh);
/*< public >*/
MemoryRegion iomem;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN];
uint32_t rx_count;
uint32_t tx_count;
uint64_t char_tx_time;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
QEMUTimer *fifo_trigger_handle;
} CadenceUARTState;
#define HW_CHAR_DIGIC_UART_H
#include "hw/sysbus.h"
+#include "sysemu/char.h"
#define TYPE_DIGIC_UART "digic-uart"
#define DIGIC_UART(obj) \
/*< public >*/
MemoryRegion regs_region;
- CharDriverState *chr;
+ CharBackend chr;
uint32_t reg_rx;
uint32_t reg_st;
#define IMX_SERIAL_H
#include "hw/sysbus.h"
+#include "sysemu/char.h"
#define TYPE_IMX_SERIAL "imx.serial"
#define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL)
uint32_t ucr3;
qemu_irq irq;
- CharDriverState *chr;
+ CharBackend chr;
} IMXSerialState;
#endif
#include "sysemu/sysemu.h"
#include "exec/memory.h"
#include "qemu/fifo8.h"
+#include "sysemu/char.h"
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
- CharDriverState *chr;
+ CharBackend chr;
int last_break_enable;
int it_shift;
int baudbase;
uint32_t usart_cr3;
uint32_t usart_gtpr;
- CharDriverState *chr;
+ CharBackend chr;
qemu_irq irq;
} STM32F2XXUsartState;
#endif /* HW_STM32F2XX_USART_H */
DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*)
#define DEFINE_PROP_CHR(_n, _s, _f) \
- DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
+ DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
#define DEFINE_PROP_STRING(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
#define DEFINE_PROP_NETDEV(_n, _s, _f) \