Blob Blame History Raw
From 64237adfdb9ed77bba8b7e3b880b3e2b0bee9d83 Mon Sep 17 00:00:00 2001
From: Laurent Vivier <lvivier@redhat.com>
Date: Mon, 12 Jun 2017 16:08:07 +0200
Subject: [PATCH 12/13] xhci: only update dequeue ptr on completed transfers

RH-Author: Laurent Vivier <lvivier@redhat.com>
Message-id: <20170612160807.29491-1-lvivier@redhat.com>
Patchwork-id: 75594
O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH] xhci: only update dequeue ptr on completed transfers
Bugzilla: 1451631
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

From: Gerd Hoffmann <kraxel@redhat.com>

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>

BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=13406862
BZ:   https://bugzilla.redhat.com/show_bug.cgi?id=1451631
Upstream: not yet upstream, but in Gerd's tree
          git://git.kraxel.org/qemu work/xhci-hid-migration

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/usb/hcd-xhci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index da9ed15..7d31637 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2121,6 +2121,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;
@@ -2171,6 +2173,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;
         }
@@ -2188,8 +2192,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);
-- 
1.8.3.1