[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/20] usb-ehci: Fix and simplify nakcnt handling
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 10/20] usb-ehci: Fix and simplify nakcnt handling |
Date: |
Wed, 7 Mar 2012 14:05:10 +0100 |
From: Hans de Goede <address@hidden>
The nakcnt code in ehci_execute_complete() marked transactions as finished
when a packet completed with a result of USB_RET_NAK, but USB_RET_NAK
means that the device cannot receive / send data at that time and that
the transaction should be retried later, which is also what the usb-uhci
and usb-ohci code does.
Note that there already was some special code in place to handle this
for interrupt endpoints in the form of doing a return from
ehci_execute_complete() when reload == 0, but that for bulk transactions
this was not handled correctly (where as for example the usb-ccid device does
return USB_RET_NAK for bulk packets).
Besides that the code in ehci_execute_complete() decrement nakcnt by 1
on a packet result of USB_RET_NAK, but
-since the transaction got marked as finished,
nakcnt would never be decremented again
-there is no code checking for nakcnt becoming 0
-there is no use in re-trying the transaction within the same usb frame /
usb-ehci frame-timer call, since the status of emulated devices won't change
as long as the usb-ehci frame-timer is running
So we should simply set the nakcnt to 0 when we get a USB_RET_NAK, thus
claiming that we've tried reload times (or as many times as possible if
reload is 0).
Besides the code in ehci_execute_complete() handling USB_RET_NAK there
was also code handling it in ehci_state_executing(), which calls
ehci_execute_complete(), and then does its own handling on top of the handling
in ehci_execute_complete(), this code would decrement nakcnt *again* (if not
already 0), or restore the reload value (which was never changed) on success.
Since the double decrement was wrong to begin with, and is no longer needed
now that we set nakcnt directly to 0 on USB_RET_NAK, and the restore of reload
is not needed either, this patch simply removes all nakcnt handling from
ehci_state_executing().
Signed-off-by: Hans de Goede <address@hidden>
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/usb-ehci.c | 32 ++++----------------------------
1 files changed, 4 insertions(+), 28 deletions(-)
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 07bcd1f..9197298 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -1291,8 +1291,6 @@ static void ehci_async_complete_packet(USBPort *port,
USBPacket *packet)
static void ehci_execute_complete(EHCIQueue *q)
{
- int reload;
-
assert(q->async != EHCI_ASYNC_INFLIGHT);
q->async = EHCI_ASYNC_NONE;
@@ -1311,16 +1309,8 @@ static void ehci_execute_complete(EHCIQueue *q)
ehci_record_interrupt(q->ehci, USBSTS_ERRINT);
break;
case USB_RET_NAK:
- /* 4.10.3 */
- reload = get_field(q->qh.epchar, QH_EPCHAR_RL);
- if ((q->pid == USB_TOKEN_IN) && reload) {
- int nakcnt = get_field(q->qh.altnext_qtd, QH_ALTNEXT_NAKCNT);
- nakcnt--;
- set_field(&q->qh.altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT);
- } else if (!reload) {
- return;
- }
- break;
+ set_field(&q->qh.altnext_qtd, 0, QH_ALTNEXT_NAKCNT);
+ return; /* We're not done yet with this transaction */
case USB_RET_BABBLE:
q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE);
ehci_record_interrupt(q->ehci, USBSTS_ERRINT);
@@ -1353,7 +1343,7 @@ static void ehci_execute_complete(EHCIQueue *q)
q->qh.token ^= QTD_TOKEN_DTOGGLE;
q->qh.token &= ~QTD_TOKEN_ACTIVE;
- if ((q->usb_status != USB_RET_NAK) && (q->qh.token & QTD_TOKEN_IOC)) {
+ if (q->qh.token & QTD_TOKEN_IOC) {
ehci_record_interrupt(q->ehci, USBSTS_INT);
}
}
@@ -1877,7 +1867,6 @@ out:
static int ehci_state_executing(EHCIQueue *q, int async)
{
int again = 0;
- int reload, nakcnt;
ehci_execute_complete(q);
if (q->usb_status == USB_RET_ASYNC) {
@@ -1897,21 +1886,8 @@ static int ehci_state_executing(EHCIQueue *q, int async)
// counter decrements to 0
}
- reload = get_field(q->qh.epchar, QH_EPCHAR_RL);
- if (reload) {
- nakcnt = get_field(q->qh.altnext_qtd, QH_ALTNEXT_NAKCNT);
- if (q->usb_status == USB_RET_NAK) {
- if (nakcnt) {
- nakcnt--;
- }
- } else {
- nakcnt = reload;
- }
- set_field(&q->qh.altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT);
- }
-
/* 4.10.5 */
- if ((q->usb_status == USB_RET_NAK) || (q->qh.token & QTD_TOKEN_ACTIVE)) {
+ if (q->usb_status == USB_RET_NAK) {
ehci_set_state(q->ehci, async, EST_HORIZONTALQH);
} else {
ehci_set_state(q->ehci, async, EST_WRITEBACK);
--
1.7.1
- [Qemu-devel] [PULL 00/20] usb patch queue, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 03/20] usb-ehci: split our qh queue into async and periodic queues, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 12/20] usb: return BABBLE rather then NAK when we receive too much data, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 05/20] usb-ehci: Drop cached qhs when the doorbell gets rung, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 13/20] usb: add USB_RET_IOERROR, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 04/20] usb-ehci: always call ehci_queues_rip_unused for period queues, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 08/20] usb-ehci: Fix cerr tracking, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 20/20] xhci: fix port status, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 10/20] usb-ehci: Fix and simplify nakcnt handling,
Gerd Hoffmann <=
- [Qemu-devel] [PATCH 14/20] uhci_fill_queue: zap debug printf, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 07/20] usb-ehci: Any packet completion except for NAK should set the interrupt, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 09/20] usb-ehci: Remove dead nakcnt code, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 17/20] usb-host: enable pipelineing for bulk endpoints., Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 02/20] usb-ehci: Never follow table entries with the T-bit set, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 11/20] usb-ehci: Cleanup itd error handling, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 18/20] usb: add shortcut for control transfers, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 16/20] usb: add pipelining option to usb endpoints, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 06/20] usb-ehci: Rip the queues when the async or period schedule is halted, Gerd Hoffmann, 2012/03/07
- [Qemu-devel] [PATCH 19/20] xhci: fix control xfers, Gerd Hoffmann, 2012/03/07