mvadkert / rpms / qemu

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