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).
Please merge to Linus' latest, it's against your latest BK tree.
- Dave
--- 1.83/drivers/usb/host/ehci-hcd.c Tue Jun 10 11:19:37 2003 +++ edited/drivers/usb/host/ehci-hcd.c Sat Jun 14 08:15:27 2003 @@ -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" --- 1.77/drivers/usb/host/ehci-q.c Wed Jun 11 10:00:08 2003 +++ edited/drivers/usb/host/ehci-q.c Sat Jun 14 08:14:30 2003 @@ -360,11 +360,17 @@ 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;