diff options
Diffstat (limited to 'drivers/usb/host/ohci-q.c')
-rw-r--r-- | drivers/usb/host/ohci-q.c | 187 |
1 files changed, 92 insertions, 95 deletions
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 830a3fe8615e..51817322232b 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -36,29 +36,15 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) | |||
36 | * PRECONDITION: ohci lock held, irqs blocked. | 36 | * PRECONDITION: ohci lock held, irqs blocked. |
37 | */ | 37 | */ |
38 | static void | 38 | static void |
39 | finish_urb (struct ohci_hcd *ohci, struct urb *urb) | 39 | finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status) |
40 | __releases(ohci->lock) | 40 | __releases(ohci->lock) |
41 | __acquires(ohci->lock) | 41 | __acquires(ohci->lock) |
42 | { | 42 | { |
43 | // ASSERT (urb->hcpriv != 0); | 43 | // ASSERT (urb->hcpriv != 0); |
44 | 44 | ||
45 | urb_free_priv (ohci, urb->hcpriv); | 45 | urb_free_priv (ohci, urb->hcpriv); |
46 | urb->hcpriv = NULL; | 46 | if (likely(status == -EINPROGRESS)) |
47 | 47 | status = 0; | |
48 | spin_lock (&urb->lock); | ||
49 | if (likely (urb->status == -EINPROGRESS)) | ||
50 | urb->status = 0; | ||
51 | /* report short control reads right even though the data TD always | ||
52 | * has TD_R set. (much simpler, but creates the 1-td limit.) | ||
53 | */ | ||
54 | if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK) | ||
55 | && unlikely (usb_pipecontrol (urb->pipe)) | ||
56 | && urb->actual_length < urb->transfer_buffer_length | ||
57 | && usb_pipein (urb->pipe) | ||
58 | && urb->status == 0) { | ||
59 | urb->status = -EREMOTEIO; | ||
60 | } | ||
61 | spin_unlock (&urb->lock); | ||
62 | 48 | ||
63 | switch (usb_pipetype (urb->pipe)) { | 49 | switch (usb_pipetype (urb->pipe)) { |
64 | case PIPE_ISOCHRONOUS: | 50 | case PIPE_ISOCHRONOUS: |
@@ -70,12 +56,13 @@ __acquires(ohci->lock) | |||
70 | } | 56 | } |
71 | 57 | ||
72 | #ifdef OHCI_VERBOSE_DEBUG | 58 | #ifdef OHCI_VERBOSE_DEBUG |
73 | urb_print (urb, "RET", usb_pipeout (urb->pipe)); | 59 | urb_print(urb, "RET", usb_pipeout (urb->pipe), status); |
74 | #endif | 60 | #endif |
75 | 61 | ||
76 | /* urb->complete() can reenter this HCD */ | 62 | /* urb->complete() can reenter this HCD */ |
63 | usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); | ||
77 | spin_unlock (&ohci->lock); | 64 | spin_unlock (&ohci->lock); |
78 | usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); | 65 | usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status); |
79 | spin_lock (&ohci->lock); | 66 | spin_lock (&ohci->lock); |
80 | 67 | ||
81 | /* stop periodic dma if it's not needed */ | 68 | /* stop periodic dma if it's not needed */ |
@@ -179,6 +166,10 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
179 | ed->ed_prev = NULL; | 166 | ed->ed_prev = NULL; |
180 | ed->ed_next = NULL; | 167 | ed->ed_next = NULL; |
181 | ed->hwNextED = 0; | 168 | ed->hwNextED = 0; |
169 | if (quirk_zfmicro(ohci) | ||
170 | && (ed->type == PIPE_INTERRUPT) | ||
171 | && !(ohci->eds_scheduled++)) | ||
172 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
182 | wmb (); | 173 | wmb (); |
183 | 174 | ||
184 | /* we care about rm_list when setting CLE/BLE in case the HC was at | 175 | /* we care about rm_list when setting CLE/BLE in case the HC was at |
@@ -708,19 +699,18 @@ static void td_submit_urb ( | |||
708 | * Done List handling functions | 699 | * Done List handling functions |
709 | *-------------------------------------------------------------------------*/ | 700 | *-------------------------------------------------------------------------*/ |
710 | 701 | ||
711 | /* calculate transfer length/status and update the urb | 702 | /* calculate transfer length/status and update the urb */ |
712 | * PRECONDITION: irqsafe (only for urb->status locking) | 703 | static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td) |
713 | */ | ||
714 | static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | ||
715 | { | 704 | { |
716 | u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO); | 705 | u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO); |
717 | int cc = 0; | 706 | int cc = 0; |
707 | int status = -EINPROGRESS; | ||
718 | 708 | ||
719 | list_del (&td->td_list); | 709 | list_del (&td->td_list); |
720 | 710 | ||
721 | /* ISO ... drivers see per-TD length/status */ | 711 | /* ISO ... drivers see per-TD length/status */ |
722 | if (tdINFO & TD_ISO) { | 712 | if (tdINFO & TD_ISO) { |
723 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); | 713 | u16 tdPSW = ohci_hwPSW(ohci, td, 0); |
724 | int dlen = 0; | 714 | int dlen = 0; |
725 | 715 | ||
726 | /* NOTE: assumes FC in tdINFO == 0, and that | 716 | /* NOTE: assumes FC in tdINFO == 0, and that |
@@ -729,7 +719,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
729 | 719 | ||
730 | cc = (tdPSW >> 12) & 0xF; | 720 | cc = (tdPSW >> 12) & 0xF; |
731 | if (tdINFO & TD_CC) /* hc didn't touch? */ | 721 | if (tdINFO & TD_CC) /* hc didn't touch? */ |
732 | return; | 722 | return status; |
733 | 723 | ||
734 | if (usb_pipeout (urb->pipe)) | 724 | if (usb_pipeout (urb->pipe)) |
735 | dlen = urb->iso_frame_desc [td->index].length; | 725 | dlen = urb->iso_frame_desc [td->index].length; |
@@ -762,12 +752,8 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
762 | if (cc == TD_DATAUNDERRUN | 752 | if (cc == TD_DATAUNDERRUN |
763 | && !(urb->transfer_flags & URB_SHORT_NOT_OK)) | 753 | && !(urb->transfer_flags & URB_SHORT_NOT_OK)) |
764 | cc = TD_CC_NOERROR; | 754 | cc = TD_CC_NOERROR; |
765 | if (cc != TD_CC_NOERROR && cc < 0x0E) { | 755 | if (cc != TD_CC_NOERROR && cc < 0x0E) |
766 | spin_lock (&urb->lock); | 756 | status = cc_to_error[cc]; |
767 | if (urb->status == -EINPROGRESS) | ||
768 | urb->status = cc_to_error [cc]; | ||
769 | spin_unlock (&urb->lock); | ||
770 | } | ||
771 | 757 | ||
772 | /* count all non-empty packets except control SETUP packet */ | 758 | /* count all non-empty packets except control SETUP packet */ |
773 | if ((type != PIPE_CONTROL || td->index != 0) && tdBE != 0) { | 759 | if ((type != PIPE_CONTROL || td->index != 0) && tdBE != 0) { |
@@ -786,14 +772,15 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
786 | urb->actual_length, | 772 | urb->actual_length, |
787 | urb->transfer_buffer_length); | 773 | urb->transfer_buffer_length); |
788 | } | 774 | } |
775 | return status; | ||
789 | } | 776 | } |
790 | 777 | ||
791 | /*-------------------------------------------------------------------------*/ | 778 | /*-------------------------------------------------------------------------*/ |
792 | 779 | ||
793 | static inline struct td * | 780 | static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc) |
794 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | ||
795 | { | 781 | { |
796 | struct urb *urb = td->urb; | 782 | struct urb *urb = td->urb; |
783 | urb_priv_t *urb_priv = urb->hcpriv; | ||
797 | struct ed *ed = td->ed; | 784 | struct ed *ed = td->ed; |
798 | struct list_head *tmp = td->td_list.next; | 785 | struct list_head *tmp = td->td_list.next; |
799 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); | 786 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); |
@@ -805,13 +792,12 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
805 | wmb (); | 792 | wmb (); |
806 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); | 793 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); |
807 | 794 | ||
808 | /* put any later tds from this urb onto the donelist, after 'td', | 795 | /* Get rid of all later tds from this urb. We don't have |
809 | * order won't matter here: no errors, and nothing was transferred. | 796 | * to be careful: no errors and nothing was transferred. |
810 | * also patch the ed so it looks as if those tds completed normally. | 797 | * Also patch the ed so it looks as if those tds completed normally. |
811 | */ | 798 | */ |
812 | while (tmp != &ed->td_list) { | 799 | while (tmp != &ed->td_list) { |
813 | struct td *next; | 800 | struct td *next; |
814 | __hc32 info; | ||
815 | 801 | ||
816 | next = list_entry (tmp, struct td, td_list); | 802 | next = list_entry (tmp, struct td, td_list); |
817 | tmp = next->td_list.next; | 803 | tmp = next->td_list.next; |
@@ -826,14 +812,9 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
826 | * then we need to leave the control STATUS packet queued | 812 | * then we need to leave the control STATUS packet queued |
827 | * and clear ED_SKIP. | 813 | * and clear ED_SKIP. |
828 | */ | 814 | */ |
829 | info = next->hwINFO; | ||
830 | info |= cpu_to_hc32 (ohci, TD_DONE); | ||
831 | info &= ~cpu_to_hc32 (ohci, TD_CC); | ||
832 | next->hwINFO = info; | ||
833 | |||
834 | next->next_dl_td = rev; | ||
835 | rev = next; | ||
836 | 815 | ||
816 | list_del(&next->td_list); | ||
817 | urb_priv->td_cnt++; | ||
837 | ed->hwHeadP = next->hwNextTD | toggle; | 818 | ed->hwHeadP = next->hwNextTD | toggle; |
838 | } | 819 | } |
839 | 820 | ||
@@ -859,8 +840,6 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
859 | hc32_to_cpu (ohci, td->hwINFO), | 840 | hc32_to_cpu (ohci, td->hwINFO), |
860 | cc, cc_to_error [cc]); | 841 | cc, cc_to_error [cc]); |
861 | } | 842 | } |
862 | |||
863 | return rev; | ||
864 | } | 843 | } |
865 | 844 | ||
866 | /* replies to the request have to be on a FIFO basis so | 845 | /* replies to the request have to be on a FIFO basis so |
@@ -897,7 +876,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
897 | */ | 876 | */ |
898 | if (cc != TD_CC_NOERROR | 877 | if (cc != TD_CC_NOERROR |
899 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) | 878 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) |
900 | td_rev = ed_halted (ohci, td, cc, td_rev); | 879 | ed_halted(ohci, td, cc); |
901 | 880 | ||
902 | td->next_dl_td = td_rev; | 881 | td->next_dl_td = td_rev; |
903 | td_rev = td; | 882 | td_rev = td; |
@@ -940,8 +919,12 @@ skip_ed: | |||
940 | TD_MASK; | 919 | TD_MASK; |
941 | 920 | ||
942 | /* INTR_WDH may need to clean up first */ | 921 | /* INTR_WDH may need to clean up first */ |
943 | if (td->td_dma != head) | 922 | if (td->td_dma != head) { |
944 | goto skip_ed; | 923 | if (ed == ohci->ed_to_check) |
924 | ohci->ed_to_check = NULL; | ||
925 | else | ||
926 | goto skip_ed; | ||
927 | } | ||
945 | } | 928 | } |
946 | } | 929 | } |
947 | 930 | ||
@@ -974,7 +957,7 @@ rescan_this: | |||
974 | urb = td->urb; | 957 | urb = td->urb; |
975 | urb_priv = td->urb->hcpriv; | 958 | urb_priv = td->urb->hcpriv; |
976 | 959 | ||
977 | if (urb->status == -EINPROGRESS) { | 960 | if (!urb->unlinked) { |
978 | prev = &td->hwNextTD; | 961 | prev = &td->hwNextTD; |
979 | continue; | 962 | continue; |
980 | } | 963 | } |
@@ -990,7 +973,7 @@ rescan_this: | |||
990 | /* if URB is done, clean up */ | 973 | /* if URB is done, clean up */ |
991 | if (urb_priv->td_cnt == urb_priv->length) { | 974 | if (urb_priv->td_cnt == urb_priv->length) { |
992 | modified = completed = 1; | 975 | modified = completed = 1; |
993 | finish_urb (ohci, urb); | 976 | finish_urb(ohci, urb, 0); |
994 | } | 977 | } |
995 | } | 978 | } |
996 | if (completed && !list_empty (&ed->td_list)) | 979 | if (completed && !list_empty (&ed->td_list)) |
@@ -998,6 +981,8 @@ rescan_this: | |||
998 | 981 | ||
999 | /* ED's now officially unlinked, hc doesn't see */ | 982 | /* ED's now officially unlinked, hc doesn't see */ |
1000 | ed->state = ED_IDLE; | 983 | ed->state = ED_IDLE; |
984 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
985 | ohci->eds_scheduled--; | ||
1001 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); | 986 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); |
1002 | ed->hwNextED = 0; | 987 | ed->hwNextED = 0; |
1003 | wmb (); | 988 | wmb (); |
@@ -1021,7 +1006,7 @@ rescan_this: | |||
1021 | 1006 | ||
1022 | if (ohci->ed_controltail) { | 1007 | if (ohci->ed_controltail) { |
1023 | command |= OHCI_CLF; | 1008 | command |= OHCI_CLF; |
1024 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1009 | if (quirk_zfmicro(ohci)) |
1025 | mdelay(1); | 1010 | mdelay(1); |
1026 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { | 1011 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { |
1027 | control |= OHCI_CTRL_CLE; | 1012 | control |= OHCI_CTRL_CLE; |
@@ -1031,7 +1016,7 @@ rescan_this: | |||
1031 | } | 1016 | } |
1032 | if (ohci->ed_bulktail) { | 1017 | if (ohci->ed_bulktail) { |
1033 | command |= OHCI_BLF; | 1018 | command |= OHCI_BLF; |
1034 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1019 | if (quirk_zfmicro(ohci)) |
1035 | mdelay(1); | 1020 | mdelay(1); |
1036 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { | 1021 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { |
1037 | control |= OHCI_CTRL_BLE; | 1022 | control |= OHCI_CTRL_BLE; |
@@ -1043,13 +1028,13 @@ rescan_this: | |||
1043 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ | 1028 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ |
1044 | if (control) { | 1029 | if (control) { |
1045 | ohci->hc_control |= control; | 1030 | ohci->hc_control |= control; |
1046 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1031 | if (quirk_zfmicro(ohci)) |
1047 | mdelay(1); | 1032 | mdelay(1); |
1048 | ohci_writel (ohci, ohci->hc_control, | 1033 | ohci_writel (ohci, ohci->hc_control, |
1049 | &ohci->regs->control); | 1034 | &ohci->regs->control); |
1050 | } | 1035 | } |
1051 | if (command) { | 1036 | if (command) { |
1052 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1037 | if (quirk_zfmicro(ohci)) |
1053 | mdelay(1); | 1038 | mdelay(1); |
1054 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); | 1039 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); |
1055 | } | 1040 | } |
@@ -1061,11 +1046,60 @@ rescan_this: | |||
1061 | /*-------------------------------------------------------------------------*/ | 1046 | /*-------------------------------------------------------------------------*/ |
1062 | 1047 | ||
1063 | /* | 1048 | /* |
1049 | * Used to take back a TD from the host controller. This would normally be | ||
1050 | * called from within dl_done_list, however it may be called directly if the | ||
1051 | * HC no longer sees the TD and it has not appeared on the donelist (after | ||
1052 | * two frames). This bug has been observed on ZF Micro systems. | ||
1053 | */ | ||
1054 | static void takeback_td(struct ohci_hcd *ohci, struct td *td) | ||
1055 | { | ||
1056 | struct urb *urb = td->urb; | ||
1057 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1058 | struct ed *ed = td->ed; | ||
1059 | int status; | ||
1060 | |||
1061 | /* update URB's length and status from TD */ | ||
1062 | status = td_done(ohci, urb, td); | ||
1063 | urb_priv->td_cnt++; | ||
1064 | |||
1065 | /* If all this urb's TDs are done, call complete() */ | ||
1066 | if (urb_priv->td_cnt == urb_priv->length) | ||
1067 | finish_urb(ohci, urb, status); | ||
1068 | |||
1069 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1070 | if (list_empty(&ed->td_list)) { | ||
1071 | if (ed->state == ED_OPER) | ||
1072 | start_ed_unlink(ohci, ed); | ||
1073 | |||
1074 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1075 | } else if ((ed->hwINFO & cpu_to_hc32(ohci, ED_SKIP | ED_DEQUEUE)) | ||
1076 | == cpu_to_hc32(ohci, ED_SKIP)) { | ||
1077 | td = list_entry(ed->td_list.next, struct td, td_list); | ||
1078 | if (!(td->hwINFO & cpu_to_hc32(ohci, TD_DONE))) { | ||
1079 | ed->hwINFO &= ~cpu_to_hc32(ohci, ED_SKIP); | ||
1080 | /* ... hc may need waking-up */ | ||
1081 | switch (ed->type) { | ||
1082 | case PIPE_CONTROL: | ||
1083 | ohci_writel(ohci, OHCI_CLF, | ||
1084 | &ohci->regs->cmdstatus); | ||
1085 | break; | ||
1086 | case PIPE_BULK: | ||
1087 | ohci_writel(ohci, OHCI_BLF, | ||
1088 | &ohci->regs->cmdstatus); | ||
1089 | break; | ||
1090 | } | ||
1091 | } | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | /* | ||
1064 | * Process normal completions (error or success) and clean the schedules. | 1096 | * Process normal completions (error or success) and clean the schedules. |
1065 | * | 1097 | * |
1066 | * This is the main path for handing urbs back to drivers. The only other | 1098 | * This is the main path for handing urbs back to drivers. The only other |
1067 | * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of | 1099 | * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, |
1068 | * scanning the (re-reversed) donelist as this does. | 1100 | * instead of scanning the (re-reversed) donelist as this does. There's |
1101 | * an abnormal path too, handling a quirk in some Compaq silicon: URBs | ||
1102 | * with TDs that appear to be orphaned are directly reclaimed. | ||
1069 | */ | 1103 | */ |
1070 | static void | 1104 | static void |
1071 | dl_done_list (struct ohci_hcd *ohci) | 1105 | dl_done_list (struct ohci_hcd *ohci) |
@@ -1074,44 +1108,7 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1074 | 1108 | ||
1075 | while (td) { | 1109 | while (td) { |
1076 | struct td *td_next = td->next_dl_td; | 1110 | struct td *td_next = td->next_dl_td; |
1077 | struct urb *urb = td->urb; | 1111 | takeback_td(ohci, td); |
1078 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1079 | struct ed *ed = td->ed; | ||
1080 | |||
1081 | /* update URB's length and status from TD */ | ||
1082 | td_done (ohci, urb, td); | ||
1083 | urb_priv->td_cnt++; | ||
1084 | |||
1085 | /* If all this urb's TDs are done, call complete() */ | ||
1086 | if (urb_priv->td_cnt == urb_priv->length) | ||
1087 | finish_urb (ohci, urb); | ||
1088 | |||
1089 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1090 | if (list_empty (&ed->td_list)) { | ||
1091 | if (ed->state == ED_OPER) | ||
1092 | start_ed_unlink (ohci, ed); | ||
1093 | |||
1094 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1095 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, | ||
1096 | ED_SKIP | ED_DEQUEUE)) | ||
1097 | == cpu_to_hc32 (ohci, ED_SKIP)) { | ||
1098 | td = list_entry (ed->td_list.next, struct td, td_list); | ||
1099 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { | ||
1100 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); | ||
1101 | /* ... hc may need waking-up */ | ||
1102 | switch (ed->type) { | ||
1103 | case PIPE_CONTROL: | ||
1104 | ohci_writel (ohci, OHCI_CLF, | ||
1105 | &ohci->regs->cmdstatus); | ||
1106 | break; | ||
1107 | case PIPE_BULK: | ||
1108 | ohci_writel (ohci, OHCI_BLF, | ||
1109 | &ohci->regs->cmdstatus); | ||
1110 | break; | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | td = td_next; | 1112 | td = td_next; |
1116 | } | 1113 | } |
1117 | } | 1114 | } |