aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2017-06-08 09:41:22 +0200
committerMichael Roth <mdroth@linux.vnet.ibm.com>2017-09-01 18:10:36 -0500
commitf9c313f70f3c269e301a04c6ba1dd9a813589d7a (patch)
tree9100802624257d258d472de37d03faa7985fccf5
parent53206753ba1e0eb1e2b508c2608962a194d0df25 (diff)
downloadqemu-f9c313f70f3c269e301a04c6ba1dd9a813589d7a.zip
qemu-f9c313f70f3c269e301a04c6ba1dd9a813589d7a.tar.gz
qemu-f9c313f70f3c269e301a04c6ba1dd9a813589d7a.tar.bz2
xhci: only update dequeue ptr on completed transfers
The dequeue pointer should only be updated in case the transfer is actually completed. If we update it for inflight transfers we will not pick them up again after migration, which easily triggers with HID devices as they typically have a pending transfer, waiting for user input to happen. Fixes: 243afe858b95765b98d16a1f0dd50dca262858ad Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451631 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Tested-by: Laurent Vivier <lvivier@redhat.com> Message-id: 20170608074122.32099-1-kraxel@redhat.com (cherry picked from commit d54fddea989ba4aa2912d49583d86ce01c0d27ea) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r--hw/usb/hcd-xhci.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index a2d3143..ed0f13f 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2119,6 +2119,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
}
assert(!xfer->running_retry);
if (xfer->complete) {
+ /* update ring dequeue ptr */
+ xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
xhci_ep_free_xfer(epctx->retry);
}
epctx->retry = NULL;
@@ -2169,6 +2171,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
xhci_fire_transfer(xhci, xfer, epctx);
}
if (xfer->complete) {
+ /* update ring dequeue ptr */
+ xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
xhci_ep_free_xfer(xfer);
xfer = NULL;
}
@@ -2186,8 +2190,6 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
break;
}
}
- /* update ring dequeue ptr */
- xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
epctx->kick_active--;
ep = xhci_epid_to_usbep(epctx);