diff options
Diffstat (limited to 'qemu-char.c')
-rw-r--r-- | qemu-char.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/qemu-char.c b/qemu-char.c index 7cdeffd61e..1fd3aefe38 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -101,6 +101,10 @@ /***********************************************************/ /* character device */ +static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = + TAILQ_HEAD_INITIALIZER(chardevs); +static int initial_reset_issued; + static void qemu_chr_event(CharDriverState *s, int event) { if (!s->chr_event) @@ -118,12 +122,23 @@ static void qemu_chr_reset_bh(void *opaque) void qemu_chr_reset(CharDriverState *s) { - if (s->bh == NULL) { + if (s->bh == NULL && initial_reset_issued) { s->bh = qemu_bh_new(qemu_chr_reset_bh, s); qemu_bh_schedule(s->bh); } } +void qemu_chr_initial_reset(void) +{ + CharDriverState *chr; + + initial_reset_issued = 1; + + TAILQ_FOREACH(chr, &chardevs, next) { + qemu_chr_reset(chr); + } +} + int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len) { return s->chr_write(s, buf, len); @@ -210,12 +225,15 @@ typedef struct { IOEventHandler *chr_event[MAX_MUX]; void *ext_opaque[MAX_MUX]; CharDriverState *drv; - unsigned char buffer[MUX_BUFFER_SIZE]; - int prod; - int cons; int mux_cnt; int term_got_escape; int max_size; + /* Intermediate input buffer allows to catch escape sequences even if the + currently active device is not accepting any input - but only until it + is full as well. */ + unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE]; + int prod[MAX_MUX]; + int cons[MAX_MUX]; } MuxDriver; @@ -345,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr) int m = chr->focus; MuxDriver *d = chr->opaque; - while (d->prod != d->cons && + while (d->prod[m] != d->cons[m] && 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); + &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1); } } @@ -357,11 +375,12 @@ static int mux_chr_can_read(void *opaque) { CharDriverState *chr = opaque; MuxDriver *d = chr->opaque; + int m = chr->focus; - if ((d->prod - d->cons) < MUX_BUFFER_SIZE) + if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) return 1; - if (d->chr_can_read[chr->focus]) - return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]); + if (d->chr_can_read[m]) + return d->chr_can_read[m](d->ext_opaque[m]); return 0; } @@ -376,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size) for(i = 0; i < size; i++) if (mux_proc_byte(chr, d, buf[i])) { - if (d->prod == d->cons && + if (d->prod[m] == d->cons[m] && 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]; + d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i]; } } @@ -2076,9 +2095,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, return NULL; } -static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs -= TAILQ_HEAD_INITIALIZER(chardevs); - CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) { const char *p; |