dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

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,
Hans de Goede a2729a
     }
Hans de Goede a2729a
 
Hans de Goede a2729a
     if (ep & USB_DIR_IN) {
Hans de Goede a2729a
+        bool q_was_empty;
Hans de Goede a2729a
+
Hans de Goede a2729a
         if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
Hans de Goede a2729a
             DPRINTF("received int packet while not started ep %02X\n", ep);
Hans de Goede a2729a
             free(data);
Hans de Goede a2729a
             return;
Hans de Goede a2729a
         }
Hans de Goede a2729a
 
Hans de Goede a2729a
-        if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) {
Hans de Goede a2729a
-            usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
Hans de Goede a2729a
-        }
Hans de Goede a2729a
+        q_was_empty = QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq);
Hans de Goede a2729a
 
Hans de Goede a2729a
         /* bufp_alloc also adds the packet to the ep queue */
Hans de Goede a2729a
         bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data);
Hans de Goede a2729a
+
Hans de Goede a2729a
+        if (q_was_empty) {
Hans de Goede a2729a
+            usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
Hans de Goede a2729a
+        }
Hans de Goede a2729a
     } else {
Hans de Goede a2729a
         /*
Hans de Goede a2729a
          * We report output interrupt packets as completed directly upon