qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Hans de Goede <hdegoede@redhat.com>, Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 18/54] usb-redir: Don't delay handling of open events to a bottom half
Date: Thu,  6 Sep 2012 09:12:19 +0200	[thread overview]
Message-ID: <1346915575-12369-19-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1346915575-12369-1-git-send-email-kraxel@redhat.com>

From: Hans de Goede <hdegoede@redhat.com>

There is no need for this, and doing so means that a backend trying to
write immediately after an open event will see qemu_chr_be_can_write
returning 0, which not all backends handle well as there is no wakeup
mechanism to detect when the frontend does become writable.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/redirect.c |  100 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 53 insertions(+), 47 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 7f3719b..5cc3334 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -79,8 +79,8 @@ struct USBRedirDevice {
     /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
     const uint8_t *read_buf;
     int read_buf_size;
-    /* For async handling of open/close */
-    QEMUBH *open_close_bh;
+    /* For async handling of close */
+    QEMUBH *chardev_close_bh;
     /* To delay the usb attach in case of quick chardev close + open */
     QEMUTimer *attach_timer;
     int64_t next_attach_time;
@@ -784,18 +784,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
  * from within the USBDevice data / control packet callbacks and doing a
  * usb_detach from within these callbacks is not a good idea.
  *
- * So we use a bh handler to take care of close events. We also handle
- * open events from this callback to make sure that a close directly followed
- * by an open gets handled in the right order.
+ * So we use a bh handler to take care of close events.
  */
-static void usbredir_open_close_bh(void *opaque)
+static void usbredir_chardev_close_bh(void *opaque)
 {
     USBRedirDevice *dev = opaque;
-    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
-    char version[32];
-
-    strcpy(version, "qemu usb-redir guest ");
-    pstrcat(version, sizeof(version), qemu_get_version());
 
     usbredir_device_disconnect(dev);
 
@@ -803,36 +796,47 @@ static void usbredir_open_close_bh(void *opaque)
         usbredirparser_destroy(dev->parser);
         dev->parser = NULL;
     }
+}
 
-    if (dev->cs->opened) {
-        dev->parser = qemu_oom_check(usbredirparser_create());
-        dev->parser->priv = dev;
-        dev->parser->log_func = usbredir_log;
-        dev->parser->read_func = usbredir_read;
-        dev->parser->write_func = usbredir_write;
-        dev->parser->hello_func = usbredir_hello;
-        dev->parser->device_connect_func = usbredir_device_connect;
-        dev->parser->device_disconnect_func = usbredir_device_disconnect;
-        dev->parser->interface_info_func = usbredir_interface_info;
-        dev->parser->ep_info_func = usbredir_ep_info;
-        dev->parser->configuration_status_func = usbredir_configuration_status;
-        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
-        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
-        dev->parser->interrupt_receiving_status_func =
-            usbredir_interrupt_receiving_status;
-        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
-        dev->parser->control_packet_func = usbredir_control_packet;
-        dev->parser->bulk_packet_func = usbredir_bulk_packet;
-        dev->parser->iso_packet_func = usbredir_iso_packet;
-        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
-        dev->read_buf = NULL;
-        dev->read_buf_size = 0;
+static void usbredir_chardev_open(USBRedirDevice *dev)
+{
+    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
+    char version[32];
 
-        usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
-        usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
-        usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
-        usbredirparser_do_write(dev->parser);
-    }
+    /* Make sure any pending closes are handled (no-op if none pending) */
+    usbredir_chardev_close_bh(dev);
+    qemu_bh_cancel(dev->chardev_close_bh);
+
+    strcpy(version, "qemu usb-redir guest ");
+    pstrcat(version, sizeof(version), qemu_get_version());
+
+    dev->parser = qemu_oom_check(usbredirparser_create());
+    dev->parser->priv = dev;
+    dev->parser->log_func = usbredir_log;
+    dev->parser->read_func = usbredir_read;
+    dev->parser->write_func = usbredir_write;
+    dev->parser->hello_func = usbredir_hello;
+    dev->parser->device_connect_func = usbredir_device_connect;
+    dev->parser->device_disconnect_func = usbredir_device_disconnect;
+    dev->parser->interface_info_func = usbredir_interface_info;
+    dev->parser->ep_info_func = usbredir_ep_info;
+    dev->parser->configuration_status_func = usbredir_configuration_status;
+    dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
+    dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
+    dev->parser->interrupt_receiving_status_func =
+        usbredir_interrupt_receiving_status;
+    dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
+    dev->parser->control_packet_func = usbredir_control_packet;
+    dev->parser->bulk_packet_func = usbredir_bulk_packet;
+    dev->parser->iso_packet_func = usbredir_iso_packet;
+    dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
+    dev->read_buf = NULL;
+    dev->read_buf_size = 0;
+
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
+    usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
+    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
+    usbredirparser_do_write(dev->parser);
 }
 
 static void usbredir_do_attach(void *opaque)
@@ -856,13 +860,13 @@ static int usbredir_chardev_can_read(void *opaque)
 {
     USBRedirDevice *dev = opaque;
 
-    if (dev->parser) {
-        /* usbredir_parser_do_read will consume *all* data we give it */
-        return 1024 * 1024;
-    } else {
-        /* usbredir_open_close_bh hasn't handled the open event yet */
+    if (!dev->parser) {
+        WARNING("chardev_can_read called on non open chardev!\n");
         return 0;
     }
+
+    /* usbredir_parser_do_read will consume *all* data we give it */
+    return 1024 * 1024;
 }
 
 static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
@@ -886,8 +890,10 @@ static void usbredir_chardev_event(void *opaque, int event)
 
     switch (event) {
     case CHR_EVENT_OPENED:
+        usbredir_chardev_open(dev);
+        break;
     case CHR_EVENT_CLOSED:
-        qemu_bh_schedule(dev->open_close_bh);
+        qemu_bh_schedule(dev->chardev_close_bh);
         break;
     }
 }
@@ -917,7 +923,7 @@ static int usbredir_initfn(USBDevice *udev)
         }
     }
 
-    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
+    dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
     dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
 
     QTAILQ_INIT(&dev->asyncq);
@@ -957,7 +963,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
     qemu_chr_fe_close(dev->cs);
     qemu_chr_delete(dev->cs);
     /* Note must be done after qemu_chr_close, as that causes a close event */
-    qemu_bh_delete(dev->open_close_bh);
+    qemu_bh_delete(dev->chardev_close_bh);
 
     qemu_del_timer(dev->attach_timer);
     qemu_free_timer(dev->attach_timer);
-- 
1.7.1

  parent reply	other threads:[~2012-09-06  7:13 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-06  7:12 [Qemu-devel] [PULL 00/54] usb patch queue Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 01/54] usb: controllers do not need to check for babble themselves Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 02/54] usb-core: Don't set packet state to complete on a nak Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 03/54] usb-core: Add a usb_ep_find_packet_by_id() helper function Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 04/54] usb-core: Allow the first packet of a pipelined ep to complete immediately Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 05/54] Revert "ehci: don't flush cache on doorbell rings." Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 06/54] ehci: Validate qh is not changed unexpectedly by the guest Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 07/54] ehci: Update copyright headers to reflect recent work Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 08/54] ehci: Properly cleanup packets on cancel Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 09/54] ehci: Properly report completed but not yet processed packets to the guest Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 10/54] ehci: check for EHCI_ASYNC_FINISHED first in ehci_free_packet Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 11/54] ehci: trace guest bugs Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 12/54] ehci: add doorbell trace events Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 13/54] ehci: Add some additional ehci_trace_guest_bug() calls Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 14/54] ehci: Fix memory leak in handling of NAK-ed packets Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 15/54] ehci: Handle USB_RET_PROCERR in ehci_fill_queue Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 16/54] ehci: Correct a comment in fetchqtd packet processing Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 17/54] usb-redir: Never return USB_RET_NAK for async handled packets Gerd Hoffmann
2012-09-06  7:12 ` Gerd Hoffmann [this message]
2012-09-06  7:12 ` [Qemu-devel] [PATCH 19/54] usb-redir: Get rid of async-struct get member Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 20/54] usb-redir: Get rid of local shadow copy of packet headers Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 21/54] usb-redir: Get rid of unused async-struct dev member Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 22/54] usb-redir: Move to core packet id and queue handling Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 23/54] usb-redir: Return babble when getting more bulk data then requested Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 24/54] usb-redir: Convert to new libusbredirparser 0.5 API Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 25/54] usb-redir: Set ep max_packet_size if available Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 26/54] usb-redir: Add a usbredir_reject_device helper function Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 27/54] usb-redir: Ensure our peer has the necessary caps when redirecting to XHCI Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 28/54] usb-redir: Enable pipelining for bulk endpoints Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 29/54] Better name usb braille device Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 30/54] usb-audio: fix usb version Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 31/54] xhci: rip out background transfer code Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 32/54] xhci: drop buffering Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 33/54] xhci: move device lookup into xhci_setup_packet Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 34/54] xhci: implement mfindex Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 35/54] xhci: iso xfer support Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 36/54] xhci: trace cc codes in cleartext Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 37/54] xhci: add trace_usb_xhci_ep_set_dequeue Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 38/54] xhci: fix runtime write tracepoint Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 39/54] xhci: update register layout Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 40/54] xhci: update port handling Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 41/54] usb3: superspeed descriptors Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 42/54] usb3: superspeed endpoint companion Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 43/54] usb3: bos decriptor Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 44/54] usb-storage: usb3 support Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 45/54] xhci: fix & cleanup msi Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 46/54] xhci: rework interrupt handling Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 47/54] xhci: add msix support Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 48/54] xhci: move register update into xhci_intr_raise Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 49/54] xhci: add XHCIInterrupter Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 50/54] xhci: prepare xhci_runtime_{read, write} for multiple interrupters Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 51/54] xhci: pick target interrupter Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 52/54] xhci: support multiple interrupters Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 53/54] xhci: kill xhci_mem_{read, write} dispatcher functions Gerd Hoffmann
2012-09-06  7:12 ` [Qemu-devel] [PATCH 54/54] xhci: allow bytewise capability register reads Gerd Hoffmann
2012-09-10 13:23 ` [Qemu-devel] [PULL 00/54] usb patch queue Aurelien Jarno
2012-09-10 13:37   ` Gerd Hoffmann
2012-09-10 15:08     ` Andreas Färber
2012-09-10 17:49       ` Anthony Liguori
2012-09-11  5:46         ` Gerd Hoffmann
2012-09-11 17:22           ` Aurelien Jarno

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1346915575-12369-19-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=hdegoede@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).