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

Hans de Goede c8dfc6
From 584606864261092041b46806030e4889b747ad41 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
Hans de Goede c8dfc6
Subject: [PATCH 309/366] ehci: Properly report completed but not yet
Hans de Goede c8dfc6
 processed 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>
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
-- 
Hans de Goede c8dfc6
1.7.12
Hans de Goede c8dfc6