Blame 0013-usb-redir-allocate-buffers-before-waking-up-the-host.patch

3a13dd
From: Hans de Goede <hdegoede@redhat.com>
3a13dd
Date: Mon, 10 Oct 2016 12:45:13 +0200
3a13dd
Subject: [PATCH] usb-redir: allocate buffers before waking up the host adapter
3a13dd
3a13dd
Needed to make sure usb redirection is prepared to actually handle the
3a13dd
callback from the usb host adapter.  Without this interrupt endpoints
3a13dd
don't work on xhci.
3a13dd
3a13dd
Note: On ehci the usb_wakeup() call only schedules a BH for the actual
3a13dd
work, which hides this bug because the allocation happens before ehci
3a13dd
calls back even without this patch.
3a13dd
3a13dd
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
3a13dd
Message-id: 1476096313-7730-1-git-send-email-kraxel@redhat.com
3a13dd
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
3a13dd
(cherry picked from commit d5c42857d6b0c35028897df8dfc3749eba6f6de3)
3a13dd
---
3a13dd
 hw/usb/redirect.c | 10 +++++++---
3a13dd
 1 file changed, 7 insertions(+), 3 deletions(-)
3a13dd
3a13dd
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
3a13dd
index 444672a..d4ca026 100644
3a13dd
--- a/hw/usb/redirect.c
3a13dd
+++ b/hw/usb/redirect.c
3a13dd
@@ -2036,18 +2036,22 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
a2729a
     }
a2729a
 
a2729a
     if (ep & USB_DIR_IN) {
a2729a
+        bool q_was_empty;
a2729a
+
a2729a
         if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
a2729a
             DPRINTF("received int packet while not started ep %02X\n", ep);
a2729a
             free(data);
a2729a
             return;
a2729a
         }
a2729a
 
a2729a
-        if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) {
a2729a
-            usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
a2729a
-        }
a2729a
+        q_was_empty = QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq);
a2729a
 
a2729a
         /* bufp_alloc also adds the packet to the ep queue */
a2729a
         bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data);
a2729a
+
a2729a
+        if (q_was_empty) {
a2729a
+            usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
a2729a
+        }
a2729a
     } else {
a2729a
         /*
a2729a
          * We report output interrupt packets as completed directly upon