|
Hans de Goede |
1b1995 |
From 7a3acb928b617b33605c779e7df05c2c896844b1 Mon Sep 17 00:00:00 2001
|
|
Hans de Goede |
1b1995 |
From: Hans de Goede <hdegoede@redhat.com>
|
|
Hans de Goede |
1b1995 |
Date: Mon, 20 Feb 2012 16:27:47 +0100
|
|
Hans de Goede |
1b1995 |
Subject: [PATCH 126/140] usb-ehci: Handle ISO packets failing with an error
|
|
Hans de Goede |
1b1995 |
other then NAK
|
|
Hans de Goede |
1b1995 |
|
|
Hans de Goede |
1b1995 |
Before this patch the ehci code was not checking for any other errors other
|
|
Hans de Goede |
1b1995 |
then USB_RET_NAK. This causes 2 problems:
|
|
Hans de Goede |
1b1995 |
1) Other errors are not reported to the guest.
|
|
Hans de Goede |
1b1995 |
2) When transactions with the ITD_XACT_IOC bit set completing with another
|
|
Hans de Goede |
1b1995 |
error would not result in USBSTS_INT getting set.
|
|
Hans de Goede |
1b1995 |
|
|
Hans de Goede |
1b1995 |
I hit this problem when unplugging devices while iso data was streaming from
|
|
Hans de Goede |
1b1995 |
the device to the guest. When this happens it takes a while for the guest to
|
|
Hans de Goede |
1b1995 |
process the unplugging and remove ISO transactions from the ehci schedule, in
|
|
Hans de Goede |
1b1995 |
the mean time these transactions would complete with a result of USB_RET_NODEV,
|
|
Hans de Goede |
1b1995 |
which was not handled. This lead to the Linux guest's usb subsystem "hanging",
|
|
Hans de Goede |
1b1995 |
that is it would no longer see new usb devices getting plugged in and running
|
|
Hans de Goede |
1b1995 |
for example lsusb would lead to a stuck (D state) lsusb process. This patch
|
|
Hans de Goede |
1b1995 |
fixes this.
|
|
Hans de Goede |
1b1995 |
|
|
Hans de Goede |
1b1995 |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
Hans de Goede |
1b1995 |
---
|
|
Hans de Goede |
1b1995 |
hw/usb-ehci.c | 22 +++++++++++++++++++---
|
|
Hans de Goede |
1b1995 |
1 file changed, 19 insertions(+), 3 deletions(-)
|
|
Hans de Goede |
1b1995 |
|
|
Hans de Goede |
1b1995 |
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
|
|
Hans de Goede |
1b1995 |
index 69bcc4b..a6b6ae5 100644
|
|
Hans de Goede |
1b1995 |
--- a/hw/usb-ehci.c
|
|
Hans de Goede |
1b1995 |
+++ b/hw/usb-ehci.c
|
|
Hans de Goede |
1b1995 |
@@ -1512,11 +1512,27 @@ static int ehci_process_itd(EHCIState *ehci,
|
|
Hans de Goede |
1b1995 |
/* IN */
|
|
Hans de Goede |
1b1995 |
set_field(&itd->transact[i], ret, ITD_XACT_LENGTH);
|
|
Hans de Goede |
1b1995 |
}
|
|
Hans de Goede |
1b1995 |
-
|
|
Hans de Goede |
1b1995 |
- if (itd->transact[i] & ITD_XACT_IOC) {
|
|
Hans de Goede |
1b1995 |
- ehci_record_interrupt(ehci, USBSTS_INT);
|
|
Hans de Goede |
1b1995 |
+ } else {
|
|
Hans de Goede |
1b1995 |
+ switch (ret) {
|
|
Hans de Goede |
1b1995 |
+ default:
|
|
Hans de Goede |
1b1995 |
+ fprintf(stderr, "Unexpected iso usb result: %d\n", ret);
|
|
Hans de Goede |
1b1995 |
+ /* Fall through */
|
|
Hans de Goede |
1b1995 |
+ case USB_RET_NODEV:
|
|
Hans de Goede |
1b1995 |
+ /* 3.3.2: XACTERR is only allowed on IN transactions */
|
|
Hans de Goede |
1b1995 |
+ if (dir) {
|
|
Hans de Goede |
1b1995 |
+ itd->transact[i] |= ITD_XACT_XACTERR;
|
|
Hans de Goede |
1b1995 |
+ ehci_record_interrupt(ehci, USBSTS_ERRINT);
|
|
Hans de Goede |
1b1995 |
+ }
|
|
Hans de Goede |
1b1995 |
+ break;
|
|
Hans de Goede |
1b1995 |
+ case USB_RET_BABBLE:
|
|
Hans de Goede |
1b1995 |
+ itd->transact[i] |= ITD_XACT_BABBLE;
|
|
Hans de Goede |
1b1995 |
+ ehci_record_interrupt(ehci, USBSTS_ERRINT);
|
|
Hans de Goede |
1b1995 |
+ break;
|
|
Hans de Goede |
1b1995 |
}
|
|
Hans de Goede |
1b1995 |
}
|
|
Hans de Goede |
1b1995 |
+ if (itd->transact[i] & ITD_XACT_IOC) {
|
|
Hans de Goede |
1b1995 |
+ ehci_record_interrupt(ehci, USBSTS_INT);
|
|
Hans de Goede |
1b1995 |
+ }
|
|
Hans de Goede |
1b1995 |
itd->transact[i] &= ~ITD_XACT_ACTIVE;
|
|
Hans de Goede |
1b1995 |
}
|
|
Hans de Goede |
1b1995 |
}
|
|
Hans de Goede |
1b1995 |
--
|
|
Hans de Goede |
1b1995 |
1.7.9.3
|
|
Hans de Goede |
1b1995 |
|