Blame 0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch

5544c1
From b89a0cc1ec9dbe30cbe002f12d487a52950da166 Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede c8dfc6
Date: Thu, 23 Aug 2012 16:37:19 +0200
5544c1
Subject: [PATCH] usb-redir: Don't delay handling of open events to a bottom
5544c1
 half
Hans de Goede c8dfc6
Hans de Goede c8dfc6
There is no need for this, and doing so means that a backend trying to
Hans de Goede c8dfc6
write immediately after an open event will see qemu_chr_be_can_write
Hans de Goede c8dfc6
returning 0, which not all backends handle well as there is no wakeup
Hans de Goede c8dfc6
mechanism to detect when the frontend does become writable.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede c8dfc6
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
5544c1
(cherry picked from commit ed9873bfbf145c084d039baab08c63b9d67e7bd3)
5544c1
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Hans de Goede c8dfc6
---
Hans de Goede c8dfc6
 hw/usb/redirect.c | 100 +++++++++++++++++++++++++++++-------------------------
Hans de Goede c8dfc6
 1 file changed, 53 insertions(+), 47 deletions(-)
Hans de Goede c8dfc6
Hans de Goede c8dfc6
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
5544c1
index 7f3719b..5cc3334 100644
Hans de Goede c8dfc6
--- a/hw/usb/redirect.c
Hans de Goede c8dfc6
+++ b/hw/usb/redirect.c
Hans de Goede c8dfc6
@@ -79,8 +79,8 @@ struct USBRedirDevice {
Hans de Goede c8dfc6
     /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
Hans de Goede c8dfc6
     const uint8_t *read_buf;
Hans de Goede c8dfc6
     int read_buf_size;
Hans de Goede c8dfc6
-    /* For async handling of open/close */
Hans de Goede c8dfc6
-    QEMUBH *open_close_bh;
Hans de Goede c8dfc6
+    /* For async handling of close */
Hans de Goede c8dfc6
+    QEMUBH *chardev_close_bh;
Hans de Goede c8dfc6
     /* To delay the usb attach in case of quick chardev close + open */
Hans de Goede c8dfc6
     QEMUTimer *attach_timer;
Hans de Goede c8dfc6
     int64_t next_attach_time;
5544c1
@@ -784,18 +784,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
Hans de Goede c8dfc6
  * from within the USBDevice data / control packet callbacks and doing a
Hans de Goede c8dfc6
  * usb_detach from within these callbacks is not a good idea.
Hans de Goede c8dfc6
  *
Hans de Goede c8dfc6
- * So we use a bh handler to take care of close events. We also handle
Hans de Goede c8dfc6
- * open events from this callback to make sure that a close directly followed
Hans de Goede c8dfc6
- * by an open gets handled in the right order.
Hans de Goede c8dfc6
+ * So we use a bh handler to take care of close events.
Hans de Goede c8dfc6
  */
Hans de Goede c8dfc6
-static void usbredir_open_close_bh(void *opaque)
Hans de Goede c8dfc6
+static void usbredir_chardev_close_bh(void *opaque)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     USBRedirDevice *dev = opaque;
Hans de Goede c8dfc6
-    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
Hans de Goede c8dfc6
-    char version[32];
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    strcpy(version, "qemu usb-redir guest ");
Hans de Goede c8dfc6
-    pstrcat(version, sizeof(version), qemu_get_version());
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     usbredir_device_disconnect(dev);
Hans de Goede c8dfc6
 
5544c1
@@ -803,36 +796,47 @@ static void usbredir_open_close_bh(void *opaque)
Hans de Goede c8dfc6
         usbredirparser_destroy(dev->parser);
Hans de Goede c8dfc6
         dev->parser = NULL;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
+}
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    if (dev->cs->opened) {
Hans de Goede c8dfc6
-        dev->parser = qemu_oom_check(usbredirparser_create());
Hans de Goede c8dfc6
-        dev->parser->priv = dev;
Hans de Goede c8dfc6
-        dev->parser->log_func = usbredir_log;
Hans de Goede c8dfc6
-        dev->parser->read_func = usbredir_read;
Hans de Goede c8dfc6
-        dev->parser->write_func = usbredir_write;
Hans de Goede c8dfc6
-        dev->parser->hello_func = usbredir_hello;
Hans de Goede c8dfc6
-        dev->parser->device_connect_func = usbredir_device_connect;
Hans de Goede c8dfc6
-        dev->parser->device_disconnect_func = usbredir_device_disconnect;
Hans de Goede c8dfc6
-        dev->parser->interface_info_func = usbredir_interface_info;
Hans de Goede c8dfc6
-        dev->parser->ep_info_func = usbredir_ep_info;
Hans de Goede c8dfc6
-        dev->parser->configuration_status_func = usbredir_configuration_status;
Hans de Goede c8dfc6
-        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
Hans de Goede c8dfc6
-        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
Hans de Goede c8dfc6
-        dev->parser->interrupt_receiving_status_func =
Hans de Goede c8dfc6
-            usbredir_interrupt_receiving_status;
Hans de Goede c8dfc6
-        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
Hans de Goede c8dfc6
-        dev->parser->control_packet_func = usbredir_control_packet;
Hans de Goede c8dfc6
-        dev->parser->bulk_packet_func = usbredir_bulk_packet;
Hans de Goede c8dfc6
-        dev->parser->iso_packet_func = usbredir_iso_packet;
Hans de Goede c8dfc6
-        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
Hans de Goede c8dfc6
-        dev->read_buf = NULL;
Hans de Goede c8dfc6
-        dev->read_buf_size = 0;
Hans de Goede c8dfc6
+static void usbredir_chardev_open(USBRedirDevice *dev)
Hans de Goede c8dfc6
+{
Hans de Goede c8dfc6
+    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
Hans de Goede c8dfc6
+    char version[32];
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-        usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
Hans de Goede c8dfc6
-        usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
Hans de Goede c8dfc6
-        usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
Hans de Goede c8dfc6
-        usbredirparser_do_write(dev->parser);
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
+    /* Make sure any pending closes are handled (no-op if none pending) */
Hans de Goede c8dfc6
+    usbredir_chardev_close_bh(dev);
Hans de Goede c8dfc6
+    qemu_bh_cancel(dev->chardev_close_bh);
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    strcpy(version, "qemu usb-redir guest ");
Hans de Goede c8dfc6
+    pstrcat(version, sizeof(version), qemu_get_version());
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    dev->parser = qemu_oom_check(usbredirparser_create());
Hans de Goede c8dfc6
+    dev->parser->priv = dev;
Hans de Goede c8dfc6
+    dev->parser->log_func = usbredir_log;
Hans de Goede c8dfc6
+    dev->parser->read_func = usbredir_read;
Hans de Goede c8dfc6
+    dev->parser->write_func = usbredir_write;
Hans de Goede c8dfc6
+    dev->parser->hello_func = usbredir_hello;
Hans de Goede c8dfc6
+    dev->parser->device_connect_func = usbredir_device_connect;
Hans de Goede c8dfc6
+    dev->parser->device_disconnect_func = usbredir_device_disconnect;
Hans de Goede c8dfc6
+    dev->parser->interface_info_func = usbredir_interface_info;
Hans de Goede c8dfc6
+    dev->parser->ep_info_func = usbredir_ep_info;
Hans de Goede c8dfc6
+    dev->parser->configuration_status_func = usbredir_configuration_status;
Hans de Goede c8dfc6
+    dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
Hans de Goede c8dfc6
+    dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
Hans de Goede c8dfc6
+    dev->parser->interrupt_receiving_status_func =
Hans de Goede c8dfc6
+        usbredir_interrupt_receiving_status;
Hans de Goede c8dfc6
+    dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
Hans de Goede c8dfc6
+    dev->parser->control_packet_func = usbredir_control_packet;
Hans de Goede c8dfc6
+    dev->parser->bulk_packet_func = usbredir_bulk_packet;
Hans de Goede c8dfc6
+    dev->parser->iso_packet_func = usbredir_iso_packet;
Hans de Goede c8dfc6
+    dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
Hans de Goede c8dfc6
+    dev->read_buf = NULL;
Hans de Goede c8dfc6
+    dev->read_buf_size = 0;
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
Hans de Goede c8dfc6
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
Hans de Goede c8dfc6
+    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
Hans de Goede c8dfc6
+    usbredirparser_do_write(dev->parser);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static void usbredir_do_attach(void *opaque)
5544c1
@@ -856,13 +860,13 @@ static int usbredir_chardev_can_read(void *opaque)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     USBRedirDevice *dev = opaque;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    if (dev->parser) {
Hans de Goede c8dfc6
-        /* usbredir_parser_do_read will consume *all* data we give it */
Hans de Goede c8dfc6
-        return 1024 * 1024;
Hans de Goede c8dfc6
-    } else {
Hans de Goede c8dfc6
-        /* usbredir_open_close_bh hasn't handled the open event yet */
Hans de Goede c8dfc6
+    if (!dev->parser) {
Hans de Goede c8dfc6
+        WARNING("chardev_can_read called on non open chardev!\n");
Hans de Goede c8dfc6
         return 0;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    /* usbredir_parser_do_read will consume *all* data we give it */
Hans de Goede c8dfc6
+    return 1024 * 1024;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
5544c1
@@ -886,8 +890,10 @@ static void usbredir_chardev_event(void *opaque, int event)
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     switch (event) {
Hans de Goede c8dfc6
     case CHR_EVENT_OPENED:
Hans de Goede c8dfc6
+        usbredir_chardev_open(dev);
Hans de Goede c8dfc6
+        break;
Hans de Goede c8dfc6
     case CHR_EVENT_CLOSED:
Hans de Goede c8dfc6
-        qemu_bh_schedule(dev->open_close_bh);
Hans de Goede c8dfc6
+        qemu_bh_schedule(dev->chardev_close_bh);
Hans de Goede c8dfc6
         break;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 }
5544c1
@@ -917,7 +923,7 @@ static int usbredir_initfn(USBDevice *udev)
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
Hans de Goede c8dfc6
+    dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
Hans de Goede c8dfc6
     dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     QTAILQ_INIT(&dev->asyncq);
5544c1
@@ -957,7 +963,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
Hans de Goede c8dfc6
     qemu_chr_fe_close(dev->cs);
Hans de Goede c8dfc6
     qemu_chr_delete(dev->cs);
Hans de Goede c8dfc6
     /* Note must be done after qemu_chr_close, as that causes a close event */
Hans de Goede c8dfc6
-    qemu_bh_delete(dev->open_close_bh);
Hans de Goede c8dfc6
+    qemu_bh_delete(dev->chardev_close_bh);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     qemu_del_timer(dev->attach_timer);
Hans de Goede c8dfc6
     qemu_free_timer(dev->attach_timer);
Hans de Goede c8dfc6
-- 
5544c1
1.7.12.1
Hans de Goede c8dfc6