Blame 0133-usb-ehci-Fix-cerr-tracking.patch

1b1995
From 6e6bfa88ae3867afd8258b43e3c05cba2585ee37 Mon Sep 17 00:00:00 2001
1b1995
From: Hans de Goede <hdegoede@redhat.com>
1b1995
Date: Thu, 1 Mar 2012 21:43:56 +0100
1b1995
Subject: [PATCH 133/140] usb-ehci: Fix cerr tracking
1b1995
1b1995
cerr should only be decremented on errors which cause XactErr to be set, and
1b1995
when that happens the failing transaction should be retried until cerr reaches
1b1995
0 and only then should USBSTS_ERRINT be set (and inactive cleared and
1b1995
USBSTS_INT set if requested).
1b1995
1b1995
Since we don't have any hardware level errors (and in case of redirection
1b1995
the real hardware has already retried), re-trying makes no sense, so
1b1995
immediately set cerr to 0 on errors which set XactErr.
1b1995
1b1995
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1b1995
---
1b1995
 hw/usb-ehci.c |   19 ++++++-------------
1b1995
 1 file changed, 6 insertions(+), 13 deletions(-)
1b1995
1b1995
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
1b1995
index bc5f591..a3d5c11 100644
1b1995
--- a/hw/usb-ehci.c
1b1995
+++ b/hw/usb-ehci.c
1b1995
@@ -1269,7 +1269,7 @@ static void ehci_async_complete_packet(USBPort *port, USBPacket *packet)
1b1995
 
1b1995
 static void ehci_execute_complete(EHCIQueue *q)
1b1995
 {
1b1995
-    int c_err, reload;
1b1995
+    int reload;
1b1995
 
1b1995
     assert(q->async != EHCI_ASYNC_INFLIGHT);
1b1995
     q->async = EHCI_ASYNC_NONE;
1b1995
@@ -1278,15 +1278,10 @@ static void ehci_execute_complete(EHCIQueue *q)
1b1995
             q->qhaddr, q->qh.next, q->qtdaddr, q->usb_status);
1b1995
 
1b1995
     if (q->usb_status < 0) {
1b1995
-err:
1b1995
-        /* TO-DO: put this is in a function that can be invoked below as well */
1b1995
-        c_err = get_field(q->qh.token, QTD_TOKEN_CERR);
1b1995
-        c_err--;
1b1995
-        set_field(&q->qh.token, c_err, QTD_TOKEN_CERR);
1b1995
-
1b1995
         switch(q->usb_status) {
1b1995
         case USB_RET_NODEV:
1b1995
             q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_XACTERR);
1b1995
+            set_field(&q->qh.token, 0, QTD_TOKEN_CERR);
1b1995
             ehci_record_interrupt(q->ehci, USBSTS_ERRINT);
1b1995
             break;
1b1995
         case USB_RET_STALL:
1b1995
@@ -1314,15 +1309,13 @@ err:
1b1995
             assert(0);
1b1995
             break;
1b1995
         }
1b1995
+    } else if ((q->usb_status > q->tbytes) && (q->pid == USB_TOKEN_IN)) {
1b1995
+        q->usb_status = USB_RET_BABBLE;
1b1995
+        q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE);
1b1995
+        ehci_record_interrupt(q->ehci, USBSTS_ERRINT);
1b1995
     } else {
1b1995
-        // DPRINTF("Short packet condition\n");
1b1995
         // TODO check 4.12 for splits
1b1995
 
1b1995
-        if ((q->usb_status > q->tbytes) && (q->pid == USB_TOKEN_IN)) {
1b1995
-            q->usb_status = USB_RET_BABBLE;
1b1995
-            goto err;
1b1995
-        }
1b1995
-
1b1995
         if (q->tbytes && q->pid == USB_TOKEN_IN) {
1b1995
             q->tbytes -= q->usb_status;
1b1995
         } else {
1b1995
-- 
1b1995
1.7.9.3
1b1995