Blame 0305-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch

Hans de Goede c8dfc6
From eccc0da01324939a52a74c763ade93e4a38d7328 Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede c8dfc6
Date: Wed, 29 Aug 2012 10:12:52 +0200
Hans de Goede c8dfc6
Subject: [PATCH 305/366] Revert "ehci: don't flush cache on doorbell rings."
Hans de Goede c8dfc6
Hans de Goede c8dfc6
This reverts commit 9bc3a3a216e2689bfcdd36c3e079333bbdbf3ba0, which got
Hans de Goede c8dfc6
added to fix an issue where the real, underlying cause was not stopping
Hans de Goede c8dfc6
the ep queue on an error.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Now that the underlying cause is fixed by the "usb: Halt ep queue and
Hans de Goede c8dfc6
cancel pending packets on a packet error" patch, the "don't flush" fix
Hans de Goede c8dfc6
is no longer needed.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Not only is it not needed, it causes us to see cancellations (unlinks)
Hans de Goede c8dfc6
done by the Linux EHCI driver too late, which in combination with the new
Hans de Goede c8dfc6
usb-core packet-id generation where qtd addresses are used as ids, causes
Hans de Goede c8dfc6
duplicate ids for in flight packets.
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 | 35 ++++++-----------------------------
Hans de Goede c8dfc6
 1 file changed, 6 insertions(+), 29 deletions(-)
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 9523247..e7c36f4 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
@@ -365,7 +365,6 @@ struct EHCIQueue {
Hans de Goede c8dfc6
     uint32_t seen;
Hans de Goede c8dfc6
     uint64_t ts;
Hans de Goede c8dfc6
     int async;
Hans de Goede c8dfc6
-    int revalidate;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     /* cached data from guest - needs to be flushed
Hans de Goede c8dfc6
      * when guest removes an entry (doorbell, handshake sequence)
Hans de Goede c8dfc6
@@ -805,18 +804,7 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
Hans de Goede c8dfc6
     return NULL;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static void ehci_queues_tag_unused_async(EHCIState *ehci)
Hans de Goede c8dfc6
-{
Hans de Goede c8dfc6
-    EHCIQueue *q;
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    QTAILQ_FOREACH(q, &ehci->aqueues, next) {
Hans de Goede c8dfc6
-        if (!q->seen) {
Hans de Goede c8dfc6
-            q->revalidate = 1;
Hans de Goede c8dfc6
-        }
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-}
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-static void ehci_queues_rip_unused(EHCIState *ehci, int async)
Hans de Goede c8dfc6
+static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
Hans de Goede c8dfc6
     uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4;
Hans de Goede c8dfc6
@@ -828,7 +816,7 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async)
Hans de Goede c8dfc6
             q->ts = ehci->last_run_ns;
Hans de Goede c8dfc6
             continue;
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
-        if (ehci->last_run_ns < q->ts + maxage) {
Hans de Goede c8dfc6
+        if (!flush && ehci->last_run_ns < q->ts + maxage) {
Hans de Goede c8dfc6
             continue;
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
         ehci_free_queue(q);
Hans de Goede c8dfc6
@@ -1684,7 +1672,7 @@ static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
Hans de Goede c8dfc6
         ehci_set_usbsts(ehci, USBSTS_REC);
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    ehci_queues_rip_unused(ehci, async);
Hans de Goede c8dfc6
+    ehci_queues_rip_unused(ehci, async, 0);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     /*  Find the head of the list (4.9.1.1) */
Hans de Goede c8dfc6
     for(i = 0; i < MAX_QH; i++) {
Hans de Goede c8dfc6
@@ -1769,7 +1757,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
Hans de Goede c8dfc6
     EHCIPacket *p;
Hans de Goede c8dfc6
     uint32_t entry, devaddr;
Hans de Goede c8dfc6
     EHCIQueue *q;
Hans de Goede c8dfc6
-    EHCIqh qh;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     entry = ehci_get_fetch_addr(ehci, async);
Hans de Goede c8dfc6
     q = ehci_find_queue_by_qh(ehci, entry, async);
Hans de Goede c8dfc6
@@ -1787,17 +1774,7 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     get_dwords(ehci, NLPTR_GET(q->qhaddr),
Hans de Goede c8dfc6
-               (uint32_t *) &qh, sizeof(EHCIqh) >> 2);
Hans de Goede c8dfc6
-    if (q->revalidate && (q->qh.epchar      != qh.epchar ||
Hans de Goede c8dfc6
-                          q->qh.epcap       != qh.epcap  ||
Hans de Goede c8dfc6
-                          q->qh.current_qtd != qh.current_qtd)) {
Hans de Goede c8dfc6
-        ehci_free_queue(q);
Hans de Goede c8dfc6
-        q = ehci_alloc_queue(ehci, entry, async);
Hans de Goede c8dfc6
-        q->seen++;
Hans de Goede c8dfc6
-        p = NULL;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-    q->qh = qh;
Hans de Goede c8dfc6
-    q->revalidate = 0;
Hans de Goede c8dfc6
+               (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);
Hans de Goede c8dfc6
     ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     devaddr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR);
Hans de Goede c8dfc6
@@ -2306,7 +2283,7 @@ static void ehci_advance_async_state(EHCIState *ehci)
Hans de Goede c8dfc6
          */
Hans de Goede c8dfc6
         if (ehci->usbcmd & USBCMD_IAAD) {
Hans de Goede c8dfc6
             /* Remove all unseen qhs from the async qhs queue */
Hans de Goede c8dfc6
-            ehci_queues_tag_unused_async(ehci);
Hans de Goede c8dfc6
+            ehci_queues_rip_unused(ehci, async, 1);
Hans de Goede c8dfc6
             DPRINTF("ASYNC: doorbell request acknowledged\n");
Hans de Goede c8dfc6
             ehci->usbcmd &= ~USBCMD_IAAD;
Hans de Goede c8dfc6
             ehci_raise_irq(ehci, USBSTS_IAA);
Hans de Goede c8dfc6
@@ -2359,7 +2336,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
Hans de Goede c8dfc6
         ehci_set_fetch_addr(ehci, async,entry);
Hans de Goede c8dfc6
         ehci_set_state(ehci, async, EST_FETCHENTRY);
Hans de Goede c8dfc6
         ehci_advance_state(ehci, async);
Hans de Goede c8dfc6
-        ehci_queues_rip_unused(ehci, async);
Hans de Goede c8dfc6
+        ehci_queues_rip_unused(ehci, async, 0);
Hans de Goede c8dfc6
         break;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     default:
Hans de Goede c8dfc6
-- 
Hans de Goede c8dfc6
1.7.12
Hans de Goede c8dfc6