Commit b47b914e authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: ehci, fix qh re-activation problem

This resolves a problem that appears when relinking
a bulk or control QH that has a partially completed
multi-packet qTD.  Some I/O could be repeated.

Such cases can happen when an empty QH starts to unlink,
but gets re-activated (by queueing the multi-packet qTD)
before the HC saw the unlink.  It's rarely an issue with
control traffic (transfers are so small) or when bulk
queues are active (the QH won't empty).
parent 6843246f
......@@ -91,7 +91,7 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4
*/
#define DRIVER_VERSION "2003-Jun-12"
#define DRIVER_VERSION "2003-Jun-13"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
......
......@@ -360,11 +360,17 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
if (unlikely (stopped != 0)
/* some EHCI 0.95 impls will overlay dummy qtds */
|| qh->hw_qtd_next == EHCI_LIST_END) {
qh_update (ehci, qh,
list_empty (&qh->qtd_list)
? qh->dummy
: list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list));
if (list_empty (&qh->qtd_list))
end = qh->dummy;
else {
end = list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list);
/* first qtd may already be partially processed */
if (cpu_to_le32 (end->qtd_dma) == qh->hw_current)
end = 0;
}
if (end)
qh_update (ehci, qh, end);
}
return count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment