summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede2016-10-10 12:45:13 +0200
committerGerd Hoffmann2016-10-12 14:37:24 +0200
commitd5c42857d6b0c35028897df8dfc3749eba6f6de3 (patch)
tree48e38267471e72273fc8ee630636c20e8f08c6c8
parentusb: Fix incorrect default DMA offset. (diff)
downloadqemu-d5c42857d6b0c35028897df8dfc3749eba6f6de3.tar.gz
qemu-d5c42857d6b0c35028897df8dfc3749eba6f6de3.tar.xz
qemu-d5c42857d6b0c35028897df8dfc3749eba6f6de3.zip
usb-redir: allocate buffers before waking up the host adapter
Needed to make sure usb redirection is prepared to actually handle the callback from the usb host adapter. Without this interrupt endpoints don't work on xhci. Note: On ehci the usb_wakeup() call only schedules a BH for the actual work, which hides this bug because the allocation happens before ehci calls back even without this patch. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Message-id: 1476096313-7730-1-git-send-email-kraxel@redhat.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/usb/redirect.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 444672a000..d4ca026f00 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -2036,18 +2036,22 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
}
if (ep & USB_DIR_IN) {
+ bool q_was_empty;
+
if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
DPRINTF("received int packet while not started ep %02X\n", ep);
free(data);
return;
}
- if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) {
- usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
- }
+ q_was_empty = QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq);
/* bufp_alloc also adds the packet to the ep queue */
bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data);
+
+ if (q_was_empty) {
+ usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0);
+ }
} else {
/*
* We report output interrupt packets as completed directly upon