aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-q.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-08-22 13:08:40 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:19 -0400
commit6e8fe43b26085a64327d1cbb751ab895f3ad3f5d (patch)
treecfc80d392d933788b13ca1fdf45afc8cfb9682c3 /drivers/usb/host/ohci-q.c
parent1f5a3d0f34fd5719081c6b8f3dbbcbe328d4da31 (diff)
USB: avoid the donelist after an error in ohci-hcd
This patch (as972) changes ohci-hcd so that after an error occurs, the remaining TDs for the URB will be skipped over entirely instead of going through the donelist. This enables the driver to give back the URB as soon as the error is detected, avoiding the need to store the error status in urb->status. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-q.c')
-rw-r--r--drivers/usb/host/ohci-q.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 3c793fad178d..860e55ff67a1 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -783,10 +783,10 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
783 783
784/*-------------------------------------------------------------------------*/ 784/*-------------------------------------------------------------------------*/
785 785
786static inline struct td * 786static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc)
787ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
788{ 787{
789 struct urb *urb = td->urb; 788 struct urb *urb = td->urb;
789 urb_priv_t *urb_priv = urb->hcpriv;
790 struct ed *ed = td->ed; 790 struct ed *ed = td->ed;
791 struct list_head *tmp = td->td_list.next; 791 struct list_head *tmp = td->td_list.next;
792 __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); 792 __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C);
@@ -798,13 +798,12 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
798 wmb (); 798 wmb ();
799 ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); 799 ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H);
800 800
801 /* put any later tds from this urb onto the donelist, after 'td', 801 /* Get rid of all later tds from this urb. We don't have
802 * order won't matter here: no errors, and nothing was transferred. 802 * to be careful: no errors and nothing was transferred.
803 * also patch the ed so it looks as if those tds completed normally. 803 * Also patch the ed so it looks as if those tds completed normally.
804 */ 804 */
805 while (tmp != &ed->td_list) { 805 while (tmp != &ed->td_list) {
806 struct td *next; 806 struct td *next;
807 __hc32 info;
808 807
809 next = list_entry (tmp, struct td, td_list); 808 next = list_entry (tmp, struct td, td_list);
810 tmp = next->td_list.next; 809 tmp = next->td_list.next;
@@ -819,14 +818,9 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
819 * then we need to leave the control STATUS packet queued 818 * then we need to leave the control STATUS packet queued
820 * and clear ED_SKIP. 819 * and clear ED_SKIP.
821 */ 820 */
822 info = next->hwINFO;
823 info |= cpu_to_hc32 (ohci, TD_DONE);
824 info &= ~cpu_to_hc32 (ohci, TD_CC);
825 next->hwINFO = info;
826
827 next->next_dl_td = rev;
828 rev = next;
829 821
822 list_del(&next->td_list);
823 urb_priv->td_cnt++;
830 ed->hwHeadP = next->hwNextTD | toggle; 824 ed->hwHeadP = next->hwNextTD | toggle;
831 } 825 }
832 826
@@ -852,8 +846,6 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
852 hc32_to_cpu (ohci, td->hwINFO), 846 hc32_to_cpu (ohci, td->hwINFO),
853 cc, cc_to_error [cc]); 847 cc, cc_to_error [cc]);
854 } 848 }
855
856 return rev;
857} 849}
858 850
859/* replies to the request have to be on a FIFO basis so 851/* replies to the request have to be on a FIFO basis so
@@ -890,7 +882,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
890 */ 882 */
891 if (cc != TD_CC_NOERROR 883 if (cc != TD_CC_NOERROR
892 && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) 884 && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H)))
893 td_rev = ed_halted (ohci, td, cc, td_rev); 885 ed_halted(ohci, td, cc);
894 886
895 td->next_dl_td = td_rev; 887 td->next_dl_td = td_rev;
896 td_rev = td; 888 td_rev = td;