|
|
5544c1 |
From 4547897358a12c0f31d688da9922236984742242 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
|
|
|
5544c1 |
Subject: [PATCH] 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>
|
|
|
5544c1 |
(cherry picked from commit 66f092d25697e11847b61d761c38ddebedaed8d1)
|
|
|
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 | 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 |
--
|
|
|
5544c1 |
1.7.12.1
|
|
Hans de Goede |
c8dfc6 |
|