[adm5120] add 2.6.24 specific patchset for the usb driver
[openwrt/svn-archive/archive.git] / target / linux / adm5120 / patches-2.6.24 / 914-usb_reorganize_urb_status_use.patch
1 Index: linux-2.6.24/drivers/usb/host/adm5120-dbg.c
2 ===================================================================
3 --- linux-2.6.24.orig/drivers/usb/host/adm5120-dbg.c
4 +++ linux-2.6.24/drivers/usb/host/adm5120-dbg.c
5 @@ -82,7 +82,7 @@ static inline char *td_togglestring(u32
6 * small: 0) header + data packets 1) just header
7 */
8 static void __attribute__((unused))
9 -urb_print(struct admhcd *ahcd, struct urb *urb, char *str, int small)
10 +urb_print(struct admhcd *ahcd, struct urb *urb, char *str, int small, int status)
11 {
12 unsigned int pipe = urb->pipe;
13
14 @@ -92,7 +92,7 @@ urb_print(struct admhcd *ahcd, struct ur
15 }
16
17 #ifndef ADMHC_VERBOSE_DEBUG
18 - if (urb->status != 0)
19 + if (status != 0)
20 #endif
21 admhc_dbg(ahcd, "URB-%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d "
22 "stat=%d\n",
23 @@ -105,7 +105,7 @@ urb_print(struct admhcd *ahcd, struct ur
24 urb->transfer_flags,
25 urb->actual_length,
26 urb->transfer_buffer_length,
27 - urb->status);
28 + status);
29
30 #ifdef ADMHC_VERBOSE_DEBUG
31 if (!small) {
32 @@ -125,7 +125,7 @@ urb_print(struct admhcd *ahcd, struct ur
33 urb->transfer_buffer_length: urb->actual_length;
34 for (i = 0; i < 16 && i < len; i++)
35 printk(" %02x", ((__u8 *)urb->transfer_buffer)[i]);
36 - printk("%s stat:%d\n", i < len? "...": "", urb->status);
37 + printk("%s stat:%d\n", i < len? "...": "", status);
38 }
39 }
40 #endif /* ADMHC_VERBOSE_DEBUG */
41 Index: linux-2.6.24/drivers/usb/host/adm5120-hcd.c
42 ===================================================================
43 --- linux-2.6.24.orig/drivers/usb/host/adm5120-hcd.c
44 +++ linux-2.6.24/drivers/usb/host/adm5120-hcd.c
45 @@ -96,7 +96,7 @@ static int admhc_urb_enqueue(struct usb_
46
47 #ifdef ADMHC_VERBOSE_DEBUG
48 spin_lock_irqsave(&ahcd->lock, flags);
49 - urb_print(ahcd, urb, "ENQEUE", usb_pipein(pipe));
50 + urb_print(ahcd, urb, "ENQEUE", usb_pipein(pipe), -EINPROGRESS);
51 spin_unlock_irqrestore(&ahcd->lock, flags);
52 #endif
53
54 @@ -208,8 +208,8 @@ fail:
55 }
56
57 /*
58 - * decouple the URB from the HC queues (TDs, urb_priv); it's
59 - * already marked using urb->status. reporting is always done
60 + * decouple the URB from the HC queues (TDs, urb_priv);
61 + * reporting is always done
62 * asynchronously, and we might be dealing with an urb that's
63 * partially transferred, or an ED with other urbs being unlinked.
64 */
65 @@ -223,7 +223,7 @@ static int admhc_urb_dequeue(struct usb_
66 spin_lock_irqsave(&ahcd->lock, flags);
67
68 #ifdef ADMHC_VERBOSE_DEBUG
69 - urb_print(ahcd, urb, "DEQUEUE", 1);
70 + urb_print(ahcd, urb, "DEQUEUE", 1, status);
71 #endif
72 ret = usb_hcd_check_unlink_urb(hcd, urb, status);
73 if (ret) {
74 @@ -247,7 +247,7 @@ static int admhc_urb_dequeue(struct usb_
75 * any more ... just clean up every urb's memory.
76 */
77 if (urb->hcpriv)
78 - finish_urb(ahcd, urb);
79 + finish_urb(ahcd, urb, status);
80 }
81 spin_unlock_irqrestore(&ahcd->lock, flags);
82
83 Index: linux-2.6.24/drivers/usb/host/adm5120-pm.c
84 ===================================================================
85 --- linux-2.6.24.orig/drivers/usb/host/adm5120-pm.c
86 +++ linux-2.6.24/drivers/usb/host/adm5120-pm.c
87 @@ -383,9 +383,8 @@ static int admhc_restart(struct admhcd *
88 ed, ed->state);
89 }
90
91 - spin_lock(&urb->lock);
92 - urb->status = -ESHUTDOWN;
93 - spin_unlock(&urb->lock);
94 + if (!urb->unlinked)
95 + urb->unlinked = -ESHUTDOWN;
96 }
97 finish_unlinks(ahcd, 0);
98 spin_unlock_irq(&ahcd->lock);
99 Index: linux-2.6.24/drivers/usb/host/adm5120-q.c
100 ===================================================================
101 --- linux-2.6.24.orig/drivers/usb/host/adm5120-q.c
102 +++ linux-2.6.24/drivers/usb/host/adm5120-q.c
103 @@ -23,16 +23,14 @@
104 * PRECONDITION: ahcd lock held, irqs blocked.
105 */
106 static void
107 -finish_urb(struct admhcd *ahcd, struct urb *urb)
108 +finish_urb(struct admhcd *ahcd, struct urb *urb, int status)
109 __releases(ahcd->lock)
110 __acquires(ahcd->lock)
111 {
112 urb_priv_free(ahcd, urb->hcpriv);
113
114 - spin_lock(&urb->lock);
115 - if (likely(urb->status == -EINPROGRESS))
116 - urb->status = 0;
117 - spin_unlock(&urb->lock);
118 + if (likely(status == -EINPROGRESS))
119 + status = 0;
120
121 switch (usb_pipetype(urb->pipe)) {
122 case PIPE_ISOCHRONOUS:
123 @@ -44,12 +42,13 @@ __acquires(ahcd->lock)
124 }
125
126 #ifdef ADMHC_VERBOSE_DEBUG
127 - urb_print(ahcd, urb, "RET", usb_pipeout (urb->pipe));
128 + urb_print(ahcd, urb, "RET", usb_pipeout (urb->pipe), status);
129 #endif
130
131 /* urb->complete() can reenter this HCD */
132 usb_hcd_unlink_urb_from_ep(admhcd_to_hcd(ahcd), urb);
133 spin_unlock(&ahcd->lock);
134 + urb->status = status;
135 usb_hcd_giveback_urb(admhcd_to_hcd(ahcd), urb);
136 spin_lock(&ahcd->lock);
137 }
138 @@ -557,9 +556,7 @@ static void td_submit_urb(struct admhcd
139 * Done List handling functions
140 *-------------------------------------------------------------------------*/
141
142 -/* calculate transfer length/status and update the urb
143 - * PRECONDITION: irqsafe (only for urb->status locking)
144 - */
145 +/* calculate transfer length/status and update the urb */
146 static int td_done(struct admhcd *ahcd, struct urb *urb, struct td *td)
147 {
148 struct urb_priv *urb_priv = urb->hcpriv;
149 @@ -568,6 +565,7 @@ static int td_done(struct admhcd *ahcd,
150 u32 tdDBP;
151 int type = usb_pipetype(urb->pipe);
152 int cc;
153 + int status = -EINPROGRESS;
154
155 info = hc32_to_cpup(ahcd, &td->hwINFO);
156 tdDBP = hc32_to_cpup(ahcd, &td->hwDBP);
157 @@ -582,10 +580,9 @@ static int td_done(struct admhcd *ahcd,
158 /* NOTE: assumes FC in tdINFO == 0, and that
159 * only the first of 0..MAXPSW psws is used.
160 */
161 -#if 0
162 - if (tdINFO & TD_CC) /* hc didn't touch? */
163 - return;
164 -#endif
165 + if (info & TD_CC) /* hc didn't touch? */
166 + return status;
167 +
168 if (usb_pipeout(urb->pipe))
169 dlen = urb->iso_frame_desc[td->index].length;
170 else {
171 @@ -614,11 +611,9 @@ static int td_done(struct admhcd *ahcd,
172 && !(urb->transfer_flags & URB_SHORT_NOT_OK))
173 cc = TD_CC_NOERROR;
174
175 - if (cc != TD_CC_NOERROR && cc < TD_CC_HCD0) {
176 - spin_lock(&urb->lock);
177 - urb->status = cc_to_error[cc];
178 - spin_unlock(&urb->lock);
179 - }
180 + if (cc != TD_CC_NOERROR && cc < TD_CC_HCD0)
181 + status = cc_to_error[cc];
182 +
183
184 /* count all non-empty packets except control SETUP packet */
185 if ((type != PIPE_CONTROL || td->index != 0) && tdDBP != 0) {
186 @@ -636,7 +631,7 @@ static int td_done(struct admhcd *ahcd,
187 list_del(&td->td_list);
188 urb_priv->td_idx++;
189
190 - return cc;
191 + return status;
192 }
193
194 /*-------------------------------------------------------------------------*/
195 @@ -771,6 +766,7 @@ rescan_this:
196 struct urb *urb;
197 struct urb_priv *urb_priv;
198 __hc32 savebits;
199 + int status;
200
201 td = list_entry(entry, struct td, td_list);
202 urb = td->urb;
203 @@ -792,12 +788,12 @@ rescan_this:
204 #ifdef ADMHC_VERBOSE_DEBUG
205 urb_print(ahcd, urb, "PARTIAL", 0);
206 #endif
207 - td_done(ahcd, urb, td);
208 + status = td_done(ahcd, urb, td);
209
210 /* if URB is done, clean up */
211 if (urb_priv->td_idx == urb_priv->td_cnt) {
212 modified = completed = 1;
213 - finish_urb(ahcd, urb);
214 + finish_urb(ahcd, urb, status);
215 }
216 }
217 if (completed && !list_empty(&ed->td_list))
218 @@ -895,13 +891,13 @@ static void ed_update(struct admhcd *ahc
219 struct td *td = list_entry(entry, struct td, td_list);
220 struct urb *urb = td->urb;
221 struct urb_priv *urb_priv = urb->hcpriv;
222 - int cc;
223 + int status;
224
225 if (hc32_to_cpup(ahcd, &td->hwINFO) & TD_OWN)
226 break;
227
228 /* update URB's length and status from TD */
229 - cc = td_done(ahcd, urb, td);
230 + status = td_done(ahcd, urb, td);
231 if (is_ed_halted(ahcd, ed) && is_td_halted(ahcd, ed, td))
232 ed_unhalt(ahcd, ed, urb);
233
234 @@ -910,7 +906,7 @@ static void ed_update(struct admhcd *ahc
235
236 /* If all this urb's TDs are done, call complete() */
237 if (urb_priv->td_idx == urb_priv->td_cnt)
238 - finish_urb(ahcd, urb);
239 + finish_urb(ahcd, urb, status);
240
241 /* clean schedule: unlink EDs that are no longer busy */
242 if (list_empty(&ed->td_list)) {