9ae3a8
From 83423f42cd68e8b3ee644f38686dc4eabba9ce37 Mon Sep 17 00:00:00 2001
9ae3a8
From: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Date: Fri, 11 Jul 2014 14:20:51 +0200
9ae3a8
Subject: [PATCH 17/43] usb-hcd-xhci: Update endpoint context dequeue pointer
9ae3a8
 for streams too
9ae3a8
9ae3a8
Message-id: <1405088470-24115-19-git-send-email-kraxel@redhat.com>
9ae3a8
Patchwork-id: 59838
9ae3a8
O-Subject: [RHEL-7.1 qemu-kvm PATCH 18/37] usb-hcd-xhci: Update endpoint context dequeue pointer for streams too
9ae3a8
Bugzilla: 980747
9ae3a8
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
9ae3a8
From: Hans de Goede <hdegoede@redhat.com>
9ae3a8
9ae3a8
With streams the endpoint context dequeue pointer should point to the
9ae3a8
dequeue value for the currently active stream.
9ae3a8
9ae3a8
At least Linux guests expect it to point to value set by an set_ep_dequeue
9ae3a8
upon completion of the set_ep_dequeue (before kicking the ep).
9ae3a8
9ae3a8
Otherwise the Linux kernel will complain (and things won't work):
9ae3a8
9ae3a8
xhci_hcd 0000:00:05.0: Mismatch between completed Set TR Deq Ptr command & xHCI internal state.
9ae3a8
xhci_hcd 0000:00:05.0: ep deq seg = ffff8800366f0880, deq ptr = ffff8800366ec010
9ae3a8
9ae3a8
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
9ae3a8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
(cherry picked from commit c90daa1c109348099088c1cc954c1e9f3392ae03)
9ae3a8
---
9ae3a8
 hw/usb/hcd-xhci.c | 10 ++++++++--
9ae3a8
 1 file changed, 8 insertions(+), 2 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/usb/hcd-xhci.c | 10 ++++++++--
9ae3a8
 1 file changed, 8 insertions(+), 2 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
9ae3a8
index fc3b330..ef0c073 100644
9ae3a8
--- a/hw/usb/hcd-xhci.c
9ae3a8
+++ b/hw/usb/hcd-xhci.c
9ae3a8
@@ -1189,6 +1189,7 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
9ae3a8
 static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
9ae3a8
                               XHCIStreamContext *sctx, uint32_t state)
9ae3a8
 {
9ae3a8
+    XHCIRing *ring = NULL;
9ae3a8
     uint32_t ctx[5];
9ae3a8
     uint32_t ctx2[2];
9ae3a8
 
9ae3a8
@@ -1199,6 +1200,7 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
9ae3a8
     /* update ring dequeue ptr */
9ae3a8
     if (epctx->nr_pstreams) {
9ae3a8
         if (sctx != NULL) {
9ae3a8
+            ring = &sctx->ring;
9ae3a8
             xhci_dma_read_u32s(xhci, sctx->pctx, ctx2, sizeof(ctx2));
9ae3a8
             ctx2[0] &= 0xe;
9ae3a8
             ctx2[0] |= sctx->ring.dequeue | sctx->ring.ccs;
9ae3a8
@@ -1206,8 +1208,12 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
9ae3a8
             xhci_dma_write_u32s(xhci, sctx->pctx, ctx2, sizeof(ctx2));
9ae3a8
         }
9ae3a8
     } else {
9ae3a8
-        ctx[2] = epctx->ring.dequeue | epctx->ring.ccs;
9ae3a8
-        ctx[3] = (epctx->ring.dequeue >> 16) >> 16;
9ae3a8
+        ring = &epctx->ring;
9ae3a8
+    }
9ae3a8
+    if (ring) {
9ae3a8
+        ctx[2] = ring->dequeue | ring->ccs;
9ae3a8
+        ctx[3] = (ring->dequeue >> 16) >> 16;
9ae3a8
+
9ae3a8
         DPRINTF("xhci: set epctx: " DMA_ADDR_FMT " state=%d dequeue=%08x%08x\n",
9ae3a8
                 epctx->pctx, state, ctx[3], ctx[2]);
9ae3a8
     }
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8