From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:42348) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T9WGy-0004lu-JJ for qemu-devel@nongnu.org; Thu, 06 Sep 2012 03:13:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T9WGp-0006Mw-SV for qemu-devel@nongnu.org; Thu, 06 Sep 2012 03:13:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39662) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T9WGp-0006M4-KB for qemu-devel@nongnu.org; Thu, 06 Sep 2012 03:12:59 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q867CxQO032159 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 6 Sep 2012 03:12:59 -0400 From: Gerd Hoffmann Date: Thu, 6 Sep 2012 09:12:06 +0200 Message-Id: <1346915575-12369-6-git-send-email-kraxel@redhat.com> In-Reply-To: <1346915575-12369-1-git-send-email-kraxel@redhat.com> References: <1346915575-12369-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 05/54] Revert "ehci: don't flush cache on doorbell rings." List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Hans de Goede From: Hans de Goede This reverts commit 9bc3a3a216e2689bfcdd36c3e079333bbdbf3ba0, which got added to fix an issue where the real, underlying cause was not stopping the ep queue on an error. Now that the underlying cause is fixed by the "usb: Halt ep queue and cancel pending packets on a packet error" patch, the "don't flush" fix is no longer needed. Not only is it not needed, it causes us to see cancellations (unlinks) done by the Linux EHCI driver too late, which in combination with the new usb-core packet-id generation where qtd addresses are used as ids, causes duplicate ids for in flight packets. Signed-off-by: Hans de Goede --- hw/usb/hcd-ehci.c | 35 ++++++----------------------------- 1 files changed, 6 insertions(+), 29 deletions(-) diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 9523247..e7c36f4 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -365,7 +365,6 @@ struct EHCIQueue { uint32_t seen; uint64_t ts; int async; - int revalidate; /* cached data from guest - needs to be flushed * when guest removes an entry (doorbell, handshake sequence) @@ -805,18 +804,7 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr, return NULL; } -static void ehci_queues_tag_unused_async(EHCIState *ehci) -{ - EHCIQueue *q; - - QTAILQ_FOREACH(q, &ehci->aqueues, next) { - if (!q->seen) { - q->revalidate = 1; - } - } -} - -static void ehci_queues_rip_unused(EHCIState *ehci, int async) +static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush) { EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues; uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4; @@ -828,7 +816,7 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async) q->ts = ehci->last_run_ns; continue; } - if (ehci->last_run_ns < q->ts + maxage) { + if (!flush && ehci->last_run_ns < q->ts + maxage) { continue; } ehci_free_queue(q); @@ -1684,7 +1672,7 @@ static int ehci_state_waitlisthead(EHCIState *ehci, int async) ehci_set_usbsts(ehci, USBSTS_REC); } - ehci_queues_rip_unused(ehci, async); + ehci_queues_rip_unused(ehci, async, 0); /* Find the head of the list (4.9.1.1) */ for(i = 0; i < MAX_QH; i++) { @@ -1769,7 +1757,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) EHCIPacket *p; uint32_t entry, devaddr; EHCIQueue *q; - EHCIqh qh; entry = ehci_get_fetch_addr(ehci, async); q = ehci_find_queue_by_qh(ehci, entry, async); @@ -1787,17 +1774,7 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) } get_dwords(ehci, NLPTR_GET(q->qhaddr), - (uint32_t *) &qh, sizeof(EHCIqh) >> 2); - if (q->revalidate && (q->qh.epchar != qh.epchar || - q->qh.epcap != qh.epcap || - q->qh.current_qtd != qh.current_qtd)) { - ehci_free_queue(q); - q = ehci_alloc_queue(ehci, entry, async); - q->seen++; - p = NULL; - } - q->qh = qh; - q->revalidate = 0; + (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2); ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh); devaddr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR); @@ -2306,7 +2283,7 @@ static void ehci_advance_async_state(EHCIState *ehci) */ if (ehci->usbcmd & USBCMD_IAAD) { /* Remove all unseen qhs from the async qhs queue */ - ehci_queues_tag_unused_async(ehci); + ehci_queues_rip_unused(ehci, async, 1); DPRINTF("ASYNC: doorbell request acknowledged\n"); ehci->usbcmd &= ~USBCMD_IAAD; ehci_raise_irq(ehci, USBSTS_IAA); @@ -2359,7 +2336,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci) ehci_set_fetch_addr(ehci, async,entry); ehci_set_state(ehci, async, EST_FETCHENTRY); ehci_advance_state(ehci, async); - ehci_queues_rip_unused(ehci, async); + ehci_queues_rip_unused(ehci, async, 0); break; default: -- 1.7.1