Blame 0134-ehci-Properly-report-completed-but-not-yet-processed.patch

5544c1
From c7251f2557d09ce4b8466eeccd0f3264c297c515 Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede c8dfc6
Date: Thu, 30 Aug 2012 15:18:24 +0200
5544c1
Subject: [PATCH] ehci: Properly report completed but not yet processed
5544c1
 packets to the guest
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Reported packets which have completed before being cancelled as such to the
Hans de Goede c8dfc6
host. Note that the new code path this patch adds is untested since it I've
Hans de Goede c8dfc6
been unable to actually trigger the race which needs this code path.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
5544c1
(cherry picked from commit 4b63a0df3bda8a2c278e45d9d94d9ba6d5791d8d)
5544c1
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Hans de Goede c8dfc6
---
Hans de Goede c8dfc6
 hw/usb/hcd-ehci.c | 13 +++++++++++++
Hans de Goede c8dfc6
 1 file changed, 13 insertions(+)
Hans de Goede c8dfc6
Hans de Goede c8dfc6
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
index 4fe85c8..0a6c9ef 100644
Hans de Goede c8dfc6
--- a/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
+++ b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
@@ -489,6 +489,9 @@ static const char *ehci_mmio_names[] = {
Hans de Goede c8dfc6
     [CONFIGFLAG]        = "CONFIGFLAG",
Hans de Goede c8dfc6
 };
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
+static int ehci_state_executing(EHCIQueue *q);
Hans de Goede c8dfc6
+static int ehci_state_writeback(EHCIQueue *q);
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
 static const char *nr2str(const char **n, size_t len, uint32_t nr)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     if (nr < len && n[nr] != NULL) {
Hans de Goede c8dfc6
@@ -750,6 +753,16 @@ static void ehci_free_packet(EHCIPacket *p)
Hans de Goede c8dfc6
         usb_packet_unmap(&p->packet, &p->sgl);
Hans de Goede c8dfc6
         qemu_sglist_destroy(&p->sgl);
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
+    if (p->async == EHCI_ASYNC_FINISHED) {
Hans de Goede c8dfc6
+        int state = ehci_get_state(p->queue->ehci, p->queue->async);
Hans de Goede c8dfc6
+        /* This is a normal, but rare condition (cancel racing completion) */
Hans de Goede c8dfc6
+        fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
Hans de Goede c8dfc6
+        ehci_state_executing(p->queue);
Hans de Goede c8dfc6
+        ehci_state_writeback(p->queue);
Hans de Goede c8dfc6
+        ehci_set_state(p->queue->ehci, p->queue->async, state);
Hans de Goede c8dfc6
+        /* state_writeback recurses into us with async == EHCI_ASYNC_NONE!! */
Hans de Goede c8dfc6
+        return;
Hans de Goede c8dfc6
+    }
Hans de Goede c8dfc6
     QTAILQ_REMOVE(&p->queue->packets, p, next);
Hans de Goede c8dfc6
     usb_packet_cleanup(&p->packet);
Hans de Goede c8dfc6
     g_free(p);
Hans de Goede c8dfc6
-- 
5544c1
1.7.12.1
Hans de Goede c8dfc6