From 028e687474d9ecb8c180241efe8b0fe3e9c831a7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 4 Mar 2012 11:57:51 +0100 Subject: [PATCH 29/35] usb-ehci: Fix cerr tracking RH-Author: Hans de Goede Message-id: <1330862278-22314-15-git-send-email-hdegoede@redhat.com> Patchwork-id: 37929 O-Subject: [PATCH 14/21] usb-ehci: Fix cerr tracking Bugzilla: 758104 RH-Acked-by: Hans de Goede RH-Acked-by: Gerd Hoffmann RH-Acked-by: Alon Levy RH-Acked-by: Markus Armbruster cerr should only be decremented on errors which cause XactErr to be set, and when that happens the failing transaction should be retried until cerr reaches 0 and only then should USBSTS_ERRINT be set (and inactive cleared and USBSTS_INT set if requested). Since we don't have any hardware level errors (and in case of redirection the real hardware has already retried), re-trying makes no sense, so immediately set cerr to 0 on errors which set XactErr. Signed-off-by: Hans de Goede Upstream commit: dd54cfe0bcf30d1f3a34e9c397f619d423fe0c5b Upstream: http://patchwork.ozlabs.org/patch/144364/ (waiting for next usb pull request) --- hw/usb-ehci.c | 19 ++++++------------- 1 files changed, 6 insertions(+), 13 deletions(-) Signed-off-by: Michal Novotny --- hw/usb-ehci.c | 19 ++++++------------- 1 files changed, 6 insertions(+), 13 deletions(-) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index ecd6a70..47975c1 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -1258,7 +1258,7 @@ static void ehci_async_complete_packet(USBPort *port, USBPacket *packet) static void ehci_execute_complete(EHCIQueue *q) { - int c_err, reload; + int reload; assert(q->async != EHCI_ASYNC_INFLIGHT); q->async = EHCI_ASYNC_NONE; @@ -1267,15 +1267,10 @@ static void ehci_execute_complete(EHCIQueue *q) q->qhaddr, q->qh.next, q->qtdaddr, q->usb_status); if (q->usb_status < 0) { -err: - /* TO-DO: put this is in a function that can be invoked below as well */ - c_err = get_field(q->qh.token, QTD_TOKEN_CERR); - c_err--; - set_field(&q->qh.token, c_err, QTD_TOKEN_CERR); - switch(q->usb_status) { case USB_RET_NODEV: q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_XACTERR); + set_field(&q->qh.token, 0, QTD_TOKEN_CERR); ehci_record_interrupt(q->ehci, USBSTS_ERRINT); break; case USB_RET_STALL: @@ -1303,15 +1298,13 @@ err: assert(0); break; } + } else if ((q->usb_status > q->tbytes) && (q->pid == USB_TOKEN_IN)) { + q->usb_status = USB_RET_BABBLE; + q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE); + ehci_record_interrupt(q->ehci, USBSTS_ERRINT); } else { - // DPRINTF("Short packet condition\n"); // TODO check 4.12 for splits - if ((q->usb_status > q->tbytes) && (q->pid == USB_TOKEN_IN)) { - q->usb_status = USB_RET_BABBLE; - goto err; - } - if (q->tbytes && q->pid == USB_TOKEN_IN) { if (ehci_buffer_rw(q, q->usb_status, 1) != 0) { q->usb_status = USB_RET_PROCERR; -- 1.7.7.6