aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-q.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r--drivers/usb/host/uhci-q.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 8639e9035931..693e92c1bd9e 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1148,8 +1148,9 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1148 1148
1149 /* If the new URB is the first and only one on this QH then either 1149 /* If the new URB is the first and only one on this QH then either
1150 * the QH is new and idle or else it's unlinked and waiting to 1150 * the QH is new and idle or else it's unlinked and waiting to
1151 * become idle, so we can activate it right away. */ 1151 * become idle, so we can activate it right away. But only if the
1152 if (qh->queue.next == &urbp->node) 1152 * queue isn't stopped. */
1153 if (qh->queue.next == &urbp->node && !qh->is_stopped)
1153 uhci_activate_qh(uhci, qh); 1154 uhci_activate_qh(uhci, qh);
1154 goto done; 1155 goto done;
1155 1156
@@ -1293,27 +1294,32 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
1293 if (urb->status == -EINPROGRESS) /* Not dequeued */ 1294 if (urb->status == -EINPROGRESS) /* Not dequeued */
1294 urb->status = status; 1295 urb->status = status;
1295 else 1296 else
1296 status = -ECONNRESET; 1297 status = ECONNRESET; /* Not -ECONNRESET */
1297 spin_unlock(&urb->lock); 1298 spin_unlock(&urb->lock);
1298 1299
1299 /* Dequeued but completed URBs can't be given back unless 1300 /* Dequeued but completed URBs can't be given back unless
1300 * the QH is stopped or has finished unlinking. */ 1301 * the QH is stopped or has finished unlinking. */
1301 if (status == -ECONNRESET && 1302 if (status == ECONNRESET) {
1302 !(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) 1303 if (QH_FINISHED_UNLINKING(qh))
1303 return; 1304 qh->is_stopped = 1;
1305 else if (!qh->is_stopped)
1306 return;
1307 }
1304 1308
1305 uhci_giveback_urb(uhci, qh, urb, regs); 1309 uhci_giveback_urb(uhci, qh, urb, regs);
1306 if (qh->is_stopped) 1310 if (status < 0)
1307 break; 1311 break;
1308 } 1312 }
1309 1313
1310 /* If the QH is neither stopped nor finished unlinking (normal case), 1314 /* If the QH is neither stopped nor finished unlinking (normal case),
1311 * our work here is done. */ 1315 * our work here is done. */
1312 restart: 1316 if (QH_FINISHED_UNLINKING(qh))
1313 if (!(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) 1317 qh->is_stopped = 1;
1318 else if (!qh->is_stopped)
1314 return; 1319 return;
1315 1320
1316 /* Otherwise give back each of the dequeued URBs */ 1321 /* Otherwise give back each of the dequeued URBs */
1322restart:
1317 list_for_each_entry(urbp, &qh->queue, node) { 1323 list_for_each_entry(urbp, &qh->queue, node) {
1318 urb = urbp->urb; 1324 urb = urbp->urb;
1319 if (urb->status != -EINPROGRESS) { 1325 if (urb->status != -EINPROGRESS) {