qemu/0719-ehci-Fixup-q-qtdaddr-a...

47 lines
1.8 KiB
Diff

From ddeba1cfd2ea6560d529b25b4229a3341b355ed6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 14 Nov 2012 16:21:37 +0000
Subject: [PATCH] ehci: Fixup q->qtdaddr after cancelling an already completed
packet
This avoids the q->qtdaddr == p->qtdaddr asserts we have triggering, when
a queue contains multiple completed packages when we cancel the queue.
I triggered this with windows7 + async interrupt endpoint handling (*)
+ not detecting circles in ehci_fill_queue() properly, which makes the qtd
validation in ehci_fill_queue fail, causing cancellation of the queue on every
mouse event ...
*) Which is not going upstream as it will cause loss of interrupt events on
migration.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from ff80ce599e0465cc6109a38bd3a8ca1890e88891)
---
hw/usb/hcd-ehci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 4229061..6be11c5 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -488,6 +488,7 @@ static const char *ehci_mmio_names[] = {
static int ehci_state_executing(EHCIQueue *q);
static int ehci_state_writeback(EHCIQueue *q);
+static int ehci_state_advqueue(EHCIQueue *q);
static const char *nr2str(const char **n, size_t len, uint32_t nr)
{
@@ -758,6 +759,9 @@ static void ehci_free_packet(EHCIPacket *p)
fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
ehci_state_executing(q);
ehci_state_writeback(q);
+ if (!(q->qh.token & QTD_TOKEN_HALT)) {
+ ehci_state_advqueue(q);
+ }
ehci_set_state(q->ehci, q->async, state);
/* state_writeback recurses into us with async == EHCI_ASYNC_NONE!! */
return;