[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/5] qemu-ga: win32: add isa-serial support
From: |
Luiz Capitulino |
Subject: |
[Qemu-devel] [PATCH 5/5] qemu-ga: win32: add isa-serial support |
Date: |
Wed, 31 Oct 2012 15:45:20 -0200 |
It's implemented by opening the serial port in "non-blocking" mode
and using the GSourceFuncs API in the following way:
o prepare(): issue a read request. If something has been read, it's
stored in rs->buf and rs->pending will store the number
of bytes read. If there wasn't any bytes available, we
set the timeout to 500 ms and return
o check(): returns true if prepare() was able to read anything,
otherwise return false
o finalize(): does nothing
At dispatch() time we simply copy the bytes read to the buffer passed
to ga_channel_read().
Signed-off-by: Luiz Capitulino <address@hidden>
---
qga/channel-win32.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index c173270..887fe5f 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -179,6 +179,46 @@ static gboolean ga_channel_dispatch_ov(GSource *source,
GSourceFunc unused,
return success;
}
+static gboolean ga_channel_prepare(GSource *source, gint *timeout_ms)
+{
+ GAWatch *watch = (GAWatch *)source;
+ GAChannel *c = (GAChannel *)watch->channel;
+ GAChannelReadState *rs = &c->rstate;
+ DWORD count_read = 0;
+ bool success;
+
+ success = ReadFile(c->handle, rs->buf, rs->buf_size, &count_read, NULL);
+ if (success) {
+ if (count_read == 0) {
+ *timeout_ms = 500;
+ return false;
+ }
+ rs->pending = count_read;
+ return true;
+ }
+
+ return false;
+}
+
+static gboolean ga_channel_check(GSource *source)
+{
+ GAWatch *watch = (GAWatch *)source;
+ GAChannel *c = (GAChannel *)watch->channel;
+ GAChannelReadState *rs = &c->rstate;
+
+ return !!rs->pending;
+}
+
+static gboolean ga_channel_dispatch(GSource *source, GSourceFunc unused,
+ gpointer user_data)
+{
+ GAWatch *watch = (GAWatch *)source;
+ GAChannel *c = (GAChannel *)watch->channel;
+
+ g_assert(c->cb);
+ return c->cb(0, c->user_data);
+}
+
static void ga_channel_finalize_ov(GSource *source)
{
g_debug("finalize");
@@ -203,6 +243,30 @@ static GSource *ga_channel_create_watch_ov(GAChannel *c)
return source;
}
+static void ga_channel_finalize(GSource *source)
+{
+ g_debug("finalize");
+}
+
+GSourceFuncs ga_channel_watch_funcs = {
+ ga_channel_prepare,
+ ga_channel_check,
+ ga_channel_dispatch,
+ ga_channel_finalize
+};
+
+static GSource *ga_channel_create_watch(GAChannel *c)
+{
+ GSource *source = g_source_new(&ga_channel_watch_funcs, sizeof(GAWatch));
+ GAWatch *watch = (GAWatch *)source;
+
+ watch->channel = c;
+ watch->pollfd.fd = -1;
+ g_source_add_poll(source, &watch->pollfd);
+
+ return source;
+}
+
GIOStatus ga_channel_read(GAChannel *c, char *buf, size_t size, gsize *count)
{
GAChannelReadState *rs = &c->rstate;
@@ -225,6 +289,12 @@ GIOStatus ga_channel_read(GAChannel *c, char *buf, size_t
size, gsize *count)
status = G_IO_STATUS_AGAIN;
}
break;
+ case GA_CHANNEL_ISA_SERIAL:
+ memcpy(buf, rs->buf, rs->pending);
+ *count = rs->pending;
+ rs->pending = 0;
+ status = G_IO_STATUS_NORMAL;
+ break;
default:
abort(); /* impossible */
}
@@ -303,6 +373,7 @@ GAChannel *ga_channel_new(GAChannelMethod method, const
gchar *path,
{
GAChannel *c = g_malloc0(sizeof(GAChannel));
SECURITY_ATTRIBUTES sec_attrs;
+ COMMTIMEOUTS timeouts;
switch (method) {
case GA_CHANNEL_VIRTIO_SERIAL:
@@ -322,6 +393,22 @@ GAChannel *ga_channel_new(GAChannelMethod method, const
gchar *path,
c->source = ga_channel_create_watch_ov(c);
break;
+ case GA_CHANNEL_ISA_SERIAL:
+ if (!ga_channel_open(c, path, 0)) {
+ g_critical("error opening channel (path: %s)", path);
+ goto out_err;
+ }
+
+ /* non-blocking I/O */
+ memset(&timeouts, 0, sizeof(timeouts));
+ timeouts.ReadIntervalTimeout = MAXDWORD;
+ if (!SetCommTimeouts(c->handle, &timeouts)) {
+ CloseHandle(c->handle);
+ goto out_err;
+ }
+
+ c->source = ga_channel_create_watch(c);
+ break;
default:
g_critical("unsupported communication method");
goto out_err;
--
1.7.12.315.g682ce8b