X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fuhci-q.c;h=06115f22a4fac7420113b7b30d134b08cf3aa6b3;hb=baafe37c6a58d4ddb8c2c62cd0f20340b4c66b35;hp=c9d72ac0a1d775872ed78ed733980e40244749a0;hpb=55b4d6a52195a8f277ffddf755ddaff359878f41;p=linux-2.6-omap-h63xx.git diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index c9d72ac0a1d..06115f22a4f 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -372,7 +372,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) * need to change any toggles in this URB */ td = list_entry(urbp->td_list.next, struct uhci_td, list); if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) { - td = list_entry(urbp->td_list.next, struct uhci_td, + td = list_entry(urbp->td_list.prev, struct uhci_td, list); toggle = uhci_toggle(td_token(td)) ^ 1; @@ -943,7 +943,9 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) /* We received a short packet */ if (urb->transfer_flags & URB_SHORT_NOT_OK) ret = -EREMOTEIO; - else if (ctrlstat & TD_CTRL_SPD) + + /* Fixup needed only if this isn't the URB's last TD */ + else if (&td->list != urbp->td_list.prev) ret = 1; } @@ -1242,7 +1244,7 @@ done: * Finish unlinking an URB and give it back */ static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct urb *urb, struct pt_regs *regs) + struct urb *urb) __releases(uhci->lock) __acquires(uhci->lock) { @@ -1291,7 +1293,7 @@ __acquires(uhci->lock) } spin_unlock(&uhci->lock); - usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, regs); + usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); spin_lock(&uhci->lock); /* If the queue is now empty, we can unlink the QH and give up its @@ -1311,8 +1313,7 @@ __acquires(uhci->lock) (qh->state == QH_STATE_UNLINKING && \ uhci->frame_number + uhci->is_stopped != qh->unlink_frame) -static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct pt_regs *regs) +static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) { struct urb_priv *urbp; struct urb *urb; @@ -1345,8 +1346,8 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, return; } - uhci_giveback_urb(uhci, qh, urb, regs); - if (status < 0) + uhci_giveback_urb(uhci, qh, urb); + if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) break; } @@ -1370,7 +1371,7 @@ restart: qh->is_stopped = 0; return; } - uhci_giveback_urb(uhci, qh, urb, regs); + uhci_giveback_urb(uhci, qh, urb); goto restart; } } @@ -1485,7 +1486,7 @@ done: /* * Process events in the schedule, but only in one thread at a time */ -static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) +static void uhci_scan_schedule(struct uhci_hcd *uhci) { int i; struct uhci_qh *qh; @@ -1513,7 +1514,7 @@ rescan: struct uhci_qh, node); if (uhci_advance_check(uhci, qh)) { - uhci_scan_qh(uhci, qh, regs); + uhci_scan_qh(uhci, qh); if (qh->state == QH_STATE_ACTIVE) { uhci_urbp_wants_fsbr(uhci, list_entry(qh->queue.next, struct urb_priv, node));