summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-07-24 12:06:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-08-06 20:52:14 -0700
commitab96dcd3d043f6169c6c309012b8a6aa28b83e18 (patch)
tree67a51be9f2d04d0b6638fd4413362c7abe4aa892
parent1e1f0476535c248fb65ac11e1ae4adee221a2fc3 (diff)
UHCI: Fix handling of short last packet
This patch (as753) fixes the way uhci-hcd handles a short packet when it is the last packet of an URB. Right now the driver handles short packets the same no matter when they occur. However, the controller stops transferring packets when the short packet is not the last one (otherwise it would be reading beyond the end of the device's data) and needs to be restarted, whereas no such need occurs when the short packet is the last one. The result of the bug is that USB endpoint queues experience intermittent hangs, a regression in 2.6.17 with respect to earlier kernels. The bug was raised in Bugzilla #6752 and this patch fixed it. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/uhci-q.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index a06d84c19e13..27909bcf7a1d 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -896,12 +896,14 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
/*
* This URB stopped short of its end. We have to
* fix up the toggles of the following URBs on the
- * queue and restart the queue.
+ * queue and restart the queue. But only if this
+ * TD isn't the last one in the URB.
*
* Do this only the first time we encounter the
* short URB.
*/
- if (!urbp->short_transfer) {
+ if (!urbp->short_transfer &&
+ &td->list != urbp->td_list.prev) {
urbp->short_transfer = 1;
urbp->qh->initial_toggle =
uhci_toggle(td_token(td)) ^ 1;