Add input buffer to mux chr (patch by Tristan Gingold).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3735 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
1fc678cc72
commit
bd9bdce694
|
@ -88,6 +88,7 @@ uint32_t mcf_uart_read(void *opaque, target_phys_addr_t 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_accept_input(s->chr);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
case 0x10:
|
case 0x10:
|
||||||
|
|
|
@ -78,6 +78,7 @@ static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
|
||||||
if (s->read_count == s->read_trigger - 1)
|
if (s->read_count == s->read_trigger - 1)
|
||||||
s->int_level &= ~ PL011_INT_RX;
|
s->int_level &= ~ PL011_INT_RX;
|
||||||
pl011_update(s);
|
pl011_update(s);
|
||||||
|
qemu_chr_accept_input(s->chr);
|
||||||
return c;
|
return c;
|
||||||
case 1: /* UARTCR */
|
case 1: /* UARTCR */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -223,6 +223,7 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
|
||||||
ret = s->rbr;
|
ret = s->rbr;
|
||||||
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
|
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
|
||||||
serial_update_irq(s);
|
serial_update_irq(s);
|
||||||
|
qemu_chr_accept_input(s->chr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -475,6 +475,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
|
||||||
else
|
else
|
||||||
ret = s->rx;
|
ret = s->rx;
|
||||||
SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
|
SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
|
||||||
|
qemu_chr_accept_input(s->chr);
|
||||||
return ret;
|
return ret;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct CharDriverState {
|
||||||
void *handler_opaque;
|
void *handler_opaque;
|
||||||
void (*chr_send_event)(struct CharDriverState *chr, int event);
|
void (*chr_send_event)(struct CharDriverState *chr, int event);
|
||||||
void (*chr_close)(struct CharDriverState *chr);
|
void (*chr_close)(struct CharDriverState *chr);
|
||||||
|
void (*chr_accept_input)(struct CharDriverState *chr);
|
||||||
void *opaque;
|
void *opaque;
|
||||||
int focus;
|
int focus;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
|
@ -59,6 +60,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
|
||||||
void qemu_chr_reset(CharDriverState *s);
|
void qemu_chr_reset(CharDriverState *s);
|
||||||
int qemu_chr_can_read(CharDriverState *s);
|
int qemu_chr_can_read(CharDriverState *s);
|
||||||
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
|
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
|
||||||
|
void qemu_chr_accept_input(CharDriverState *s);
|
||||||
|
|
||||||
/* async I/O support */
|
/* async I/O support */
|
||||||
|
|
||||||
|
|
43
vl.c
43
vl.c
|
@ -1594,6 +1594,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
|
||||||
s->chr_read(s->handler_opaque, buf, len);
|
s->chr_read(s->handler_opaque, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qemu_chr_accept_input(CharDriverState *s)
|
||||||
|
{
|
||||||
|
if (s->chr_accept_input)
|
||||||
|
s->chr_accept_input(s);
|
||||||
|
}
|
||||||
|
|
||||||
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
|
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -1645,12 +1650,17 @@ static CharDriverState *qemu_chr_open_null(void)
|
||||||
static int term_timestamps;
|
static int term_timestamps;
|
||||||
static int64_t term_timestamps_start;
|
static int64_t term_timestamps_start;
|
||||||
#define MAX_MUX 4
|
#define MAX_MUX 4
|
||||||
|
#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
|
||||||
|
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IOCanRWHandler *chr_can_read[MAX_MUX];
|
IOCanRWHandler *chr_can_read[MAX_MUX];
|
||||||
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;
|
CharDriverState *drv;
|
||||||
|
unsigned char buffer[MUX_BUFFER_SIZE];
|
||||||
|
int prod;
|
||||||
|
int cons;
|
||||||
int mux_cnt;
|
int mux_cnt;
|
||||||
int term_got_escape;
|
int term_got_escape;
|
||||||
int max_size;
|
int max_size;
|
||||||
|
@ -1779,12 +1789,28 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mux_chr_accept_input(CharDriverState *chr)
|
||||||
|
{
|
||||||
|
int m = chr->focus;
|
||||||
|
MuxDriver *d = chr->opaque;
|
||||||
|
|
||||||
|
while (d->prod != d->cons &&
|
||||||
|
d->chr_can_read[m] &&
|
||||||
|
d->chr_can_read[m](d->ext_opaque[m])) {
|
||||||
|
d->chr_read[m](d->ext_opaque[m],
|
||||||
|
&d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int mux_chr_can_read(void *opaque)
|
static int mux_chr_can_read(void *opaque)
|
||||||
{
|
{
|
||||||
CharDriverState *chr = opaque;
|
CharDriverState *chr = opaque;
|
||||||
MuxDriver *d = chr->opaque;
|
MuxDriver *d = chr->opaque;
|
||||||
|
|
||||||
|
if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
|
||||||
|
return 1;
|
||||||
if (d->chr_can_read[chr->focus])
|
if (d->chr_can_read[chr->focus])
|
||||||
return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
|
return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1792,10 +1818,20 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
CharDriverState *chr = opaque;
|
CharDriverState *chr = opaque;
|
||||||
MuxDriver *d = chr->opaque;
|
MuxDriver *d = chr->opaque;
|
||||||
|
int m = chr->focus;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
mux_chr_accept_input (opaque);
|
||||||
|
|
||||||
for(i = 0; i < size; i++)
|
for(i = 0; i < size; i++)
|
||||||
if (mux_proc_byte(chr, d, buf[i]))
|
if (mux_proc_byte(chr, d, buf[i])) {
|
||||||
d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
|
if (d->prod == d->cons &&
|
||||||
|
d->chr_can_read[m] &&
|
||||||
|
d->chr_can_read[m](d->ext_opaque[m]))
|
||||||
|
d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
|
||||||
|
else
|
||||||
|
d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mux_chr_event(void *opaque, int event)
|
static void mux_chr_event(void *opaque, int event)
|
||||||
|
@ -1850,6 +1886,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
|
||||||
chr->focus = -1;
|
chr->focus = -1;
|
||||||
chr->chr_write = mux_chr_write;
|
chr->chr_write = mux_chr_write;
|
||||||
chr->chr_update_read_handler = mux_chr_update_read_handler;
|
chr->chr_update_read_handler = mux_chr_update_read_handler;
|
||||||
|
chr->chr_accept_input = mux_chr_accept_input;
|
||||||
return chr;
|
return chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue