[Qemu-devel] [PATCH 7/7] usb-hcd-xhci: Update endpoint context dequeue pointer for streams too

2013-10-24 Thread Gerd Hoffmann
From: Hans de Goede hdego...@redhat.com

With streams the endpoint context dequeue pointer should point to the
dequeue value for the currently active stream.

At least Linux guests expect it to point to value set by an set_ep_dequeue
upon completion of the set_ep_dequeue (before kicking the ep).

Otherwise the Linux kernel will complain (and things won't work):

xhci_hcd :00:05.0: Mismatch between completed Set TR Deq Ptr command  xHCI 
internal state.
xhci_hcd :00:05.0: ep deq seg = 8800366f0880, deq ptr = 8800366ec010

Signed-off-by: Hans de Goede hdego...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb/hcd-xhci.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 0131151..fa27299 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1187,6 +1187,7 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext 
*epctx,
 static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
   XHCIStreamContext *sctx, uint32_t state)
 {
+XHCIRing *ring = NULL;
 uint32_t ctx[5];
 uint32_t ctx2[2];
 
@@ -1197,6 +1198,7 @@ static void xhci_set_ep_state(XHCIState *xhci, 
XHCIEPContext *epctx,
 /* update ring dequeue ptr */
 if (epctx-nr_pstreams) {
 if (sctx != NULL) {
+ring = sctx-ring;
 xhci_dma_read_u32s(xhci, sctx-pctx, ctx2, sizeof(ctx2));
 ctx2[0] = 0xe;
 ctx2[0] |= sctx-ring.dequeue | sctx-ring.ccs;
@@ -1204,8 +1206,12 @@ static void xhci_set_ep_state(XHCIState *xhci, 
XHCIEPContext *epctx,
 xhci_dma_write_u32s(xhci, sctx-pctx, ctx2, sizeof(ctx2));
 }
 } else {
-ctx[2] = epctx-ring.dequeue | epctx-ring.ccs;
-ctx[3] = (epctx-ring.dequeue  16)  16;
+ring = epctx-ring;
+}
+if (ring) {
+ctx[2] = ring-dequeue | ring-ccs;
+ctx[3] = (ring-dequeue  16)  16;
+
 DPRINTF(xhci: set epctx:  DMA_ADDR_FMT  state=%d 
dequeue=%08x%08x\n,
 epctx-pctx, state, ctx[3], ctx[2]);
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH 7/7] usb-hcd-xhci: Update endpoint context dequeue pointer for streams too

2013-09-23 Thread Hans de Goede
With streams the endpoint context dequeue pointer should point to the
dequeue value for the currently active stream.

At least Linux guests expect it to point to value set by an set_ep_dequeue
upon completion of the set_ep_dequeue (before kicking the ep).

Otherwise the Linux kernel will complain (and things won't work):

xhci_hcd :00:05.0: Mismatch between completed Set TR Deq Ptr command  xHCI 
internal state.
xhci_hcd :00:05.0: ep deq seg = 8800366f0880, deq ptr = 8800366ec010

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-xhci.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 4890344..0bbf296 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1216,6 +1216,7 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext 
*epctx,
 static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
   XHCIStreamContext *sctx, uint32_t state)
 {
+XHCIRing *ring = NULL;
 uint32_t ctx[5];
 uint32_t ctx2[2];
 
@@ -1226,6 +1227,7 @@ static void xhci_set_ep_state(XHCIState *xhci, 
XHCIEPContext *epctx,
 /* update ring dequeue ptr */
 if (epctx-nr_pstreams) {
 if (sctx != NULL) {
+ring = sctx-ring;
 xhci_dma_read_u32s(xhci, sctx-pctx, ctx2, sizeof(ctx2));
 ctx2[0] = 0xe;
 ctx2[0] |= sctx-ring.dequeue | sctx-ring.ccs;
@@ -1233,8 +1235,12 @@ static void xhci_set_ep_state(XHCIState *xhci, 
XHCIEPContext *epctx,
 xhci_dma_write_u32s(xhci, sctx-pctx, ctx2, sizeof(ctx2));
 }
 } else {
-ctx[2] = epctx-ring.dequeue | epctx-ring.ccs;
-ctx[3] = (epctx-ring.dequeue  16)  16;
+ring = epctx-ring;
+}
+if (ring) {
+ctx[2] = ring-dequeue | ring-ccs;
+ctx[3] = (ring-dequeue  16)  16;
+
 DPRINTF(xhci: set epctx:  DMA_ADDR_FMT  state=%d 
dequeue=%08x%08x\n,
 epctx-pctx, state, ctx[3], ctx[2]);
 }
-- 
1.8.3.1