summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-04-01 18:42:39 +0200
committerAurelien Jarno <aurelien@aurel32.net>2010-04-09 22:03:22 +0200
commit73cdf3f2c97703a89b026d3a42c1120ba05fe37d (patch)
tree8dbe009563fe5f9fe6455111618fa9b0b8f44651
parent01c0bef1625d8e5d6d5c6abaf413214d667615ad (diff)
downloadqemu-73cdf3f2c97703a89b026d3a42c1120ba05fe37d.tar.gz
qemu-73cdf3f2c97703a89b026d3a42c1120ba05fe37d.tar.bz2
qemu-73cdf3f2c97703a89b026d3a42c1120ba05fe37d.zip
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>
-rw-r--r--qemu-char.c20
-rw-r--r--qemu-char.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/qemu-char.c b/qemu-char.c
index c819863f50..05df971412 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -109,6 +109,16 @@ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
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)
return;
s->chr_event(s->handler_opaque, event);
@@ -193,6 +203,12 @@ void qemu_chr_add_handlers(CharDriverState *s,
s->handler_opaque = opaque;
if (s->chr_update_read_handler)
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)
@@ -465,6 +481,10 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
chr->chr_write = mux_chr_write;
chr->chr_update_read_handler = mux_chr_update_read_handler;
chr->chr_accept_input = mux_chr_accept_input;
+
+ /* Muxes are always open on creation */
+ qemu_chr_generic_open(chr);
+
return chr;
}
diff --git a/qemu-char.h b/qemu-char.h
index 3a9427be67..e3a07838a4 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -67,6 +67,7 @@ struct CharDriverState {
QEMUBH *bh;
char *label;
char *filename;
+ int opened;
QTAILQ_ENTRY(CharDriverState) next;
};