aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ohci-q.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 177a213790d..7482cfbe8c5 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -1128,6 +1128,25 @@ dl_done_list (struct ohci_hcd *ohci)
1128 1128
1129 while (td) { 1129 while (td) {
1130 struct td *td_next = td->next_dl_td; 1130 struct td *td_next = td->next_dl_td;
1131 struct ed *ed = td->ed;
1132
1133 /*
1134 * Some OHCI controllers (NVIDIA for sure, maybe others)
1135 * occasionally forget to add TDs to the done queue. Since
1136 * TDs for a given endpoint are always processed in order,
1137 * if we find a TD on the donelist then all of its
1138 * predecessors must be finished as well.
1139 */
1140 for (;;) {
1141 struct td *td2;
1142
1143 td2 = list_first_entry(&ed->td_list, struct td,
1144 td_list);
1145 if (td2 == td)
1146 break;
1147 takeback_td(ohci, td2);
1148 }
1149
1131 takeback_td(ohci, td); 1150 takeback_td(ohci, td);
1132 td = td_next; 1151 td = td_next;
1133 } 1152 }