Always notify consumers of char devices if they're open

When using virtio-console on s390, the input doesn't work.

The root of the problem is rather simple. What happens is the following:

 1) create character device for stdio
 2) char device is done creating, sends OPENED event
 3) virtio-console adds handlers
 4) no event comes because the char device is open already
 5) virtio-console doesn't accept input because it didn't
    receive an OPENED event

To make that sure virtio-console gets notified that the character device
is open even when it's been open from the beginning, this patch introduces
a variable that keeps track of the opened state. If the device is open when
the event handlers get installed, we just notify the handler.

This fixes input with virtio-console on s390.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Alexander Graf 2010-04-01 18:42:39 +02:00 committed by Aurelien Jarno
parent 01c0bef162
commit 73cdf3f2c9
2 changed files with 21 additions and 0 deletions

View File

@ -109,6 +109,16 @@ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
static void qemu_chr_event(CharDriverState *s, int event) static void qemu_chr_event(CharDriverState *s, int event)
{ {
/* Keep track if the char device is open */
switch (event) {
case CHR_EVENT_OPENED:
s->opened = 1;
break;
case CHR_EVENT_CLOSED:
s->opened = 0;
break;
}
if (!s->chr_event) if (!s->chr_event)
return; return;
s->chr_event(s->handler_opaque, event); s->chr_event(s->handler_opaque, event);
@ -193,6 +203,12 @@ void qemu_chr_add_handlers(CharDriverState *s,
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); s->chr_update_read_handler(s);
/* We're connecting to an already opened device, so let's make sure we
also get the open event */
if (s->opened) {
qemu_chr_generic_open(s);
}
} }
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)
@ -465,6 +481,10 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
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; chr->chr_accept_input = mux_chr_accept_input;
/* Muxes are always open on creation */
qemu_chr_generic_open(chr);
return chr; return chr;
} }

View File

@ -67,6 +67,7 @@ struct CharDriverState {
QEMUBH *bh; QEMUBH *bh;
char *label; char *label;
char *filename; char *filename;
int opened;
QTAILQ_ENTRY(CharDriverState) next; QTAILQ_ENTRY(CharDriverState) next;
}; };