diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-12-08 21:28:24 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-12-13 06:06:25 -0500 |
commit | e5679d07a6ca5512070fb5e65dcc66eeb5087d0d (patch) | |
tree | 26a0a5eb4bdad75e8661a67e97f90ff114d6798f /drivers/usb/renesas_usbhs | |
parent | e4c57ded48d9bad95a4d7254e75a81f7abcffef9 (diff) |
usb: renesas_usbhs: add usbhs_pipe_attach() method
driver has to re-use the limited pipe for each device/endpoint
when it is USB host hub mode, since number of pipe has limitation.
This patch adds usbhsh_pipe_attach/detach() functions for it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/renesas_usbhs')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 292 |
1 files changed, 168 insertions, 124 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 5b6ae2a8d303..c7f9be9f5c17 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -45,32 +45,31 @@ | |||
45 | * | 45 | * |
46 | * +--------+ pipes are reused for each uep. | 46 | * +--------+ pipes are reused for each uep. |
47 | * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when | 47 | * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when |
48 | * +--------+ | | target device was changed | 48 | * +--------+ | | other device requested |
49 | * +- [uep 1 (bulk)] --|---+ +--------------+ | 49 | * +- [uep 1 (bulk)] --|---+ +--------------+ |
50 | * | +--------------> | pipe0 (dcp) | | 50 | * | +--------------> | pipe0 (dcp) | |
51 | * +- [uep 2 (bulk)] --|---|---+ +--------------+ | 51 | * +- [uep 2 (bulk)] -@ | +--------------+ |
52 | * | | | | pipe1 (isoc) | | 52 | * | | pipe1 (isoc) | |
53 | * +--------+ | | | +--------------+ | 53 | * +--------+ | +--------------+ |
54 | * | udev 2 |-+- [uep 0 (dcp) ] --+ +-- |------> | pipe2 (bulk) | | 54 | * | udev 2 |-+- [uep 0 (dcp) ] -@ +----------> | pipe2 (bulk) | |
55 | * +--------+ | | | | +--------------+ | 55 | * +--------+ | +--------------+ |
56 | * +- [uep 1 (int) ] --|-+ | +------> | pipe3 (bulk) | | 56 | * +- [uep 1 (int) ] ----+ +------> | pipe3 (bulk) | |
57 | * | | | | +--------------+ | 57 | * | | +--------------+ |
58 | * +--------+ | +-|---|------> | pipe4 (int) | | 58 | * +--------+ +-----|------> | pipe4 (int) | |
59 | * | udev 3 |-+- [uep 0 (dcp) ] --+ | | +--------------+ | 59 | * | udev 3 |-+- [uep 0 (dcp) ] -@ | +--------------+ |
60 | * +--------+ | | | | .... | | 60 | * +--------+ | | | .... | |
61 | * +- [uep 1 (bulk)] ------+ | | .... | | 61 | * +- [uep 1 (bulk)] -@ | | .... | |
62 | * | | | 62 | * | | |
63 | * +- [uep 2 (bulk)]-----------+ | 63 | * +- [uep 2 (bulk)]-----------+ |
64 | * | ||
65 | * @ : uep requested free pipe, but all have been used. | ||
66 | * now it is waiting for free pipe | ||
64 | */ | 67 | */ |
65 | 68 | ||
66 | 69 | ||
67 | /* | 70 | /* |
68 | * struct | 71 | * struct |
69 | */ | 72 | */ |
70 | struct usbhsh_pipe_info { | ||
71 | unsigned int usr_cnt; /* see usbhsh_endpoint_alloc() */ | ||
72 | }; | ||
73 | |||
74 | struct usbhsh_request { | 73 | struct usbhsh_request { |
75 | struct urb *urb; | 74 | struct urb *urb; |
76 | struct usbhs_pkt pkt; | 75 | struct usbhs_pkt pkt; |
@@ -82,12 +81,10 @@ struct usbhsh_device { | |||
82 | }; | 81 | }; |
83 | 82 | ||
84 | struct usbhsh_ep { | 83 | struct usbhsh_ep { |
85 | struct usbhs_pipe *pipe; | 84 | struct usbhs_pipe *pipe; /* attached pipe */ |
86 | struct usbhsh_device *udev; /* attached udev */ | 85 | struct usbhsh_device *udev; /* attached udev */ |
87 | struct usb_host_endpoint *ep; | 86 | struct usb_host_endpoint *ep; |
88 | struct list_head ep_list; /* list to usbhsh_device */ | 87 | struct list_head ep_list; /* list to usbhsh_device */ |
89 | |||
90 | int maxp; | ||
91 | }; | 88 | }; |
92 | 89 | ||
93 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ | 90 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ |
@@ -98,9 +95,6 @@ struct usbhsh_hpriv { | |||
98 | 95 | ||
99 | struct usbhsh_device udev[USBHSH_DEVICE_MAX]; | 96 | struct usbhsh_device udev[USBHSH_DEVICE_MAX]; |
100 | 97 | ||
101 | struct usbhsh_pipe_info *pipe_info; | ||
102 | int pipe_size; | ||
103 | |||
104 | u32 port_stat; /* USB_PORT_STAT_xxx */ | 98 | u32 port_stat; /* USB_PORT_STAT_xxx */ |
105 | 99 | ||
106 | struct completion setup_ack_done; | 100 | struct completion setup_ack_done; |
@@ -115,17 +109,6 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
115 | #define usbhsh_priv_to_hpriv(priv) \ | 109 | #define usbhsh_priv_to_hpriv(priv) \ |
116 | container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) | 110 | container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) |
117 | 111 | ||
118 | #define __usbhsh_for_each_hpipe(start, pos, h, i) \ | ||
119 | for (i = start, pos = (h)->hpipe + i; \ | ||
120 | i < (h)->hpipe_size; \ | ||
121 | i++, pos = (h)->hpipe + i) | ||
122 | |||
123 | #define usbhsh_for_each_hpipe(pos, hpriv, i) \ | ||
124 | __usbhsh_for_each_hpipe(1, pos, hpriv, i) | ||
125 | |||
126 | #define usbhsh_for_each_hpipe_with_dcp(pos, hpriv, i) \ | ||
127 | __usbhsh_for_each_hpipe(0, pos, hpriv, i) | ||
128 | |||
129 | #define __usbhsh_for_each_udev(start, pos, h, i) \ | 112 | #define __usbhsh_for_each_udev(start, pos, h, i) \ |
130 | for (i = start, pos = (h)->udev + i; \ | 113 | for (i = start, pos = (h)->udev + i; \ |
131 | i < USBHSH_DEVICE_MAX; \ | 114 | i < USBHSH_DEVICE_MAX; \ |
@@ -158,7 +141,7 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
158 | #define usbhsh_udev_to_usbv(h) ((h)->usbv) | 141 | #define usbhsh_udev_to_usbv(h) ((h)->usbv) |
159 | #define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) | 142 | #define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) |
160 | 143 | ||
161 | #define usbhsh_pipe_info(p) ((p)->mod_private) | 144 | #define usbhsh_pipe_to_uep(p) ((p)->mod_private) |
162 | 145 | ||
163 | #define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) | 146 | #define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) |
164 | #define usbhsh_device_hubport(d) ((d)->usbv->portnum) | 147 | #define usbhsh_device_hubport(d) ((d)->usbv->portnum) |
@@ -208,106 +191,166 @@ static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, | |||
208 | } | 191 | } |
209 | 192 | ||
210 | /* | 193 | /* |
211 | * end-point control | 194 | * pipe control |
212 | */ | 195 | */ |
213 | static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, | 196 | static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, |
214 | struct urb *urb); | 197 | struct urb *urb); |
215 | static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, | 198 | |
216 | struct urb *urb, | 199 | static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, |
217 | gfp_t mem_flags) | 200 | struct urb *urb) |
218 | { | 201 | { |
219 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 202 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
203 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
220 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); | 204 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); |
221 | struct usb_host_endpoint *ep = urb->ep; | 205 | struct usbhs_pipe *pipe; |
222 | struct usbhsh_ep *uep; | 206 | struct usb_endpoint_descriptor *desc = &urb->ep->desc; |
223 | struct usbhsh_pipe_info *info; | ||
224 | struct usbhs_pipe *best_pipe = NULL; | ||
225 | struct device *dev = usbhs_priv_to_dev(priv); | 207 | struct device *dev = usbhs_priv_to_dev(priv); |
226 | struct usb_endpoint_descriptor *desc = &ep->desc; | ||
227 | unsigned long flags; | 208 | unsigned long flags; |
228 | 209 | int dir_in_req = !!usb_pipein(urb->pipe); | |
229 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | 210 | int is_dcp = usb_endpoint_xfer_control(desc); |
230 | if (!uep) { | 211 | int i, dir_in; |
231 | dev_err(dev, "usbhsh_ep alloc fail\n"); | 212 | int ret = -EBUSY; |
232 | return -ENOMEM; | ||
233 | } | ||
234 | 213 | ||
235 | /******************** spin lock ********************/ | 214 | /******************** spin lock ********************/ |
236 | usbhs_lock(priv, flags); | 215 | usbhs_lock(priv, flags); |
237 | 216 | ||
238 | /* | 217 | if (unlikely(usbhsh_uep_to_pipe(uep))) { |
239 | * find best pipe for endpoint | 218 | dev_err(dev, "uep already has pipe\n"); |
240 | * see | 219 | goto usbhsh_pipe_attach_done; |
241 | * HARDWARE LIMITATION | 220 | } |
242 | */ | ||
243 | if (usb_endpoint_xfer_control(desc)) { | ||
244 | /* best pipe is DCP */ | ||
245 | best_pipe = usbhsh_hpriv_to_dcp(hpriv); | ||
246 | } else { | ||
247 | struct usbhs_pipe *pipe; | ||
248 | unsigned int min_usr = ~0; | ||
249 | int dir_in_req = !!usb_pipein(urb->pipe); | ||
250 | int i, dir_in; | ||
251 | 221 | ||
252 | usbhs_for_each_pipe(pipe, priv, i) { | 222 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { |
253 | if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) | 223 | |
254 | continue; | 224 | /* check pipe type */ |
225 | if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) | ||
226 | continue; | ||
255 | 227 | ||
228 | /* check pipe direction if normal pipe */ | ||
229 | if (!is_dcp) { | ||
256 | dir_in = !!usbhs_pipe_is_dir_in(pipe); | 230 | dir_in = !!usbhs_pipe_is_dir_in(pipe); |
257 | if (0 != (dir_in - dir_in_req)) | 231 | if (0 != (dir_in - dir_in_req)) |
258 | continue; | 232 | continue; |
233 | } | ||
259 | 234 | ||
260 | info = usbhsh_pipe_info(pipe); | 235 | /* check pipe is free */ |
261 | if (min_usr > info->usr_cnt) { | 236 | if (usbhsh_pipe_to_uep(pipe)) |
262 | min_usr = info->usr_cnt; | 237 | continue; |
263 | best_pipe = pipe; | 238 | |
264 | } | 239 | /* |
240 | * attach pipe to uep | ||
241 | * | ||
242 | * usbhs_pipe_config_update() should be called after | ||
243 | * usbhs_set_device_config() | ||
244 | * see | ||
245 | * DCPMAXP/PIPEMAXP | ||
246 | */ | ||
247 | usbhsh_uep_to_pipe(uep) = pipe; | ||
248 | usbhsh_pipe_to_uep(pipe) = uep; | ||
249 | |||
250 | if (!usb_gettoggle(urb->dev, | ||
251 | usb_pipeendpoint(urb->pipe), | ||
252 | usb_pipeout(urb->pipe))) { | ||
253 | usbhs_pipe_sequence_data0(pipe); | ||
254 | usb_settoggle(urb->dev, | ||
255 | usb_pipeendpoint(urb->pipe), | ||
256 | usb_pipeout(urb->pipe), 1); | ||
265 | } | 257 | } |
258 | |||
259 | usbhs_pipe_config_update(pipe, | ||
260 | usbhsh_device_number(hpriv, udev), | ||
261 | usb_endpoint_num(desc), | ||
262 | usb_endpoint_maxp(desc)); | ||
263 | |||
264 | dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, | ||
265 | usbhsh_device_number(hpriv, udev), | ||
266 | usb_endpoint_num(desc), | ||
267 | usbhs_pipe_name(pipe), | ||
268 | dir_in_req ? "in" : "out"); | ||
269 | |||
270 | ret = 0; | ||
271 | break; | ||
266 | } | 272 | } |
267 | 273 | ||
268 | if (best_pipe) { | 274 | usbhsh_pipe_attach_done: |
269 | /* update pipe user count */ | 275 | usbhs_unlock(priv, flags); |
270 | info = usbhsh_pipe_info(best_pipe); | 276 | /******************** spin unlock ******************/ |
271 | info->usr_cnt++; | ||
272 | 277 | ||
273 | /* init this endpoint, and attach it to udev */ | 278 | return ret; |
274 | INIT_LIST_HEAD(&uep->ep_list); | 279 | } |
275 | list_add_tail(&uep->ep_list, &udev->ep_list_head); | 280 | |
281 | static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, | ||
282 | struct usbhsh_ep *uep) | ||
283 | { | ||
284 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
285 | struct usbhs_pipe *pipe; | ||
286 | struct device *dev = usbhs_priv_to_dev(priv); | ||
287 | unsigned long flags; | ||
288 | |||
289 | /******************** spin lock ********************/ | ||
290 | usbhs_lock(priv, flags); | ||
291 | |||
292 | pipe = usbhsh_uep_to_pipe(uep); | ||
293 | |||
294 | if (unlikely(!pipe)) { | ||
295 | dev_err(dev, "uep doens't have pipe\n"); | ||
296 | } else { | ||
297 | struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); | ||
298 | struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); | ||
299 | |||
300 | /* detach pipe from uep */ | ||
301 | usbhsh_uep_to_pipe(uep) = NULL; | ||
302 | usbhsh_pipe_to_uep(pipe) = NULL; | ||
303 | |||
304 | dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, | ||
305 | usbhsh_device_number(hpriv, udev), | ||
306 | usb_endpoint_num(&ep->desc), | ||
307 | usbhs_pipe_name(pipe)); | ||
276 | } | 308 | } |
277 | 309 | ||
278 | usbhs_unlock(priv, flags); | 310 | usbhs_unlock(priv, flags); |
279 | /******************** spin unlock ******************/ | 311 | /******************** spin unlock ******************/ |
312 | } | ||
280 | 313 | ||
281 | if (unlikely(!best_pipe)) { | 314 | /* |
282 | dev_err(dev, "couldn't find best pipe\n"); | 315 | * endpoint control |
283 | kfree(uep); | 316 | */ |
284 | return -EIO; | 317 | static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, |
318 | struct urb *urb, | ||
319 | gfp_t mem_flags) | ||
320 | { | ||
321 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
322 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); | ||
323 | struct usb_host_endpoint *ep = urb->ep; | ||
324 | struct usbhsh_ep *uep; | ||
325 | struct device *dev = usbhs_priv_to_dev(priv); | ||
326 | struct usb_endpoint_descriptor *desc = &ep->desc; | ||
327 | unsigned long flags; | ||
328 | |||
329 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | ||
330 | if (!uep) { | ||
331 | dev_err(dev, "usbhsh_ep alloc fail\n"); | ||
332 | return -ENOMEM; | ||
285 | } | 333 | } |
286 | 334 | ||
335 | /******************** spin lock ********************/ | ||
336 | usbhs_lock(priv, flags); | ||
337 | |||
287 | /* | 338 | /* |
288 | * init uep | 339 | * init endpoint |
289 | */ | 340 | */ |
290 | uep->pipe = best_pipe; | 341 | INIT_LIST_HEAD(&uep->ep_list); |
291 | uep->maxp = usb_endpoint_maxp(desc); | 342 | list_add_tail(&uep->ep_list, &udev->ep_list_head); |
343 | |||
292 | usbhsh_uep_to_udev(uep) = udev; | 344 | usbhsh_uep_to_udev(uep) = udev; |
293 | usbhsh_uep_to_ep(uep) = ep; | 345 | usbhsh_uep_to_ep(uep) = ep; |
294 | usbhsh_ep_to_uep(ep) = uep; | 346 | usbhsh_ep_to_uep(ep) = uep; |
295 | 347 | ||
296 | /* | 348 | usbhs_unlock(priv, flags); |
297 | * usbhs_pipe_config_update() should be called after | 349 | /******************** spin unlock ******************/ |
298 | * usbhs_set_device_config() | ||
299 | * see | ||
300 | * DCPMAXP/PIPEMAXP | ||
301 | */ | ||
302 | usbhs_pipe_sequence_data0(uep->pipe); | ||
303 | usbhs_pipe_config_update(uep->pipe, | ||
304 | usbhsh_device_number(hpriv, udev), | ||
305 | usb_endpoint_num(desc), | ||
306 | uep->maxp); | ||
307 | 350 | ||
308 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 351 | dev_dbg(dev, "%s [%d-%d]\n", __func__, |
309 | usbhsh_device_number(hpriv, udev), | 352 | usbhsh_device_number(hpriv, udev), |
310 | usbhs_pipe_name(uep->pipe), uep); | 353 | usb_endpoint_num(desc)); |
311 | 354 | ||
312 | return 0; | 355 | return 0; |
313 | } | 356 | } |
@@ -318,27 +361,24 @@ static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, | |||
318 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 361 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
319 | struct device *dev = usbhs_priv_to_dev(priv); | 362 | struct device *dev = usbhs_priv_to_dev(priv); |
320 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); | 363 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); |
321 | struct usbhsh_pipe_info *info; | ||
322 | unsigned long flags; | 364 | unsigned long flags; |
323 | 365 | ||
324 | if (!uep) | 366 | if (!uep) |
325 | return; | 367 | return; |
326 | 368 | ||
327 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 369 | dev_dbg(dev, "%s [%d-%d]\n", __func__, |
328 | usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), | 370 | usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), |
329 | usbhs_pipe_name(uep->pipe), uep); | 371 | usb_endpoint_num(&ep->desc)); |
372 | |||
373 | if (usbhsh_uep_to_pipe(uep)) | ||
374 | usbhsh_pipe_detach(hpriv, uep); | ||
330 | 375 | ||
331 | /******************** spin lock ********************/ | 376 | /******************** spin lock ********************/ |
332 | usbhs_lock(priv, flags); | 377 | usbhs_lock(priv, flags); |
333 | 378 | ||
334 | info = usbhsh_pipe_info(uep->pipe); | ||
335 | info->usr_cnt--; | ||
336 | |||
337 | /* remove this endpoint from udev */ | 379 | /* remove this endpoint from udev */ |
338 | list_del_init(&uep->ep_list); | 380 | list_del_init(&uep->ep_list); |
339 | 381 | ||
340 | uep->pipe = NULL; | ||
341 | uep->maxp = 0; | ||
342 | usbhsh_uep_to_udev(uep) = NULL; | 382 | usbhsh_uep_to_udev(uep) = NULL; |
343 | usbhsh_uep_to_ep(uep) = NULL; | 383 | usbhsh_uep_to_ep(uep) = NULL; |
344 | usbhsh_ep_to_uep(ep) = NULL; | 384 | usbhsh_ep_to_uep(ep) = NULL; |
@@ -545,6 +585,7 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | |||
545 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 585 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
546 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 586 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
547 | struct urb *urb = ureq->urb; | 587 | struct urb *urb = ureq->urb; |
588 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
548 | struct device *dev = usbhs_priv_to_dev(priv); | 589 | struct device *dev = usbhs_priv_to_dev(priv); |
549 | 590 | ||
550 | dev_dbg(dev, "%s\n", __func__); | 591 | dev_dbg(dev, "%s\n", __func__); |
@@ -559,6 +600,8 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | |||
559 | 600 | ||
560 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 601 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
561 | usb_hcd_giveback_urb(hcd, urb, 0); | 602 | usb_hcd_giveback_urb(hcd, urb, 0); |
603 | |||
604 | usbhsh_pipe_detach(hpriv, uep); | ||
562 | } | 605 | } |
563 | 606 | ||
564 | static int usbhsh_queue_push(struct usb_hcd *hcd, | 607 | static int usbhsh_queue_push(struct usb_hcd *hcd, |
@@ -811,7 +854,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
811 | struct usb_host_endpoint *ep = urb->ep; | 854 | struct usb_host_endpoint *ep = urb->ep; |
812 | struct usbhsh_device *new_udev = NULL; | 855 | struct usbhsh_device *new_udev = NULL; |
813 | int is_dir_in = usb_pipein(urb->pipe); | 856 | int is_dir_in = usb_pipein(urb->pipe); |
814 | 857 | int i; | |
815 | int ret; | 858 | int ret; |
816 | 859 | ||
817 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); | 860 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
@@ -822,6 +865,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
822 | 865 | ||
823 | /* | 866 | /* |
824 | * attach udev if needed | 867 | * attach udev if needed |
868 | * see [image of mod_host] | ||
825 | */ | 869 | */ |
826 | if (!usbhsh_device_get(hpriv, urb)) { | 870 | if (!usbhsh_device_get(hpriv, urb)) { |
827 | new_udev = usbhsh_device_attach(hpriv, urb); | 871 | new_udev = usbhsh_device_attach(hpriv, urb); |
@@ -833,6 +877,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
833 | 877 | ||
834 | /* | 878 | /* |
835 | * attach endpoint if needed | 879 | * attach endpoint if needed |
880 | * see [image of mod_host] | ||
836 | */ | 881 | */ |
837 | if (!usbhsh_ep_to_uep(ep)) { | 882 | if (!usbhsh_ep_to_uep(ep)) { |
838 | ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); | 883 | ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); |
@@ -841,6 +886,20 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
841 | } | 886 | } |
842 | 887 | ||
843 | /* | 888 | /* |
889 | * attach pipe to endpoint | ||
890 | * see [image of mod_host] | ||
891 | */ | ||
892 | for (i = 0; i < 1024; i++) { | ||
893 | ret = usbhsh_pipe_attach(hpriv, urb); | ||
894 | if (ret < 0) | ||
895 | msleep(100); | ||
896 | else | ||
897 | break; | ||
898 | } | ||
899 | if (ret < 0) | ||
900 | goto usbhsh_urb_enqueue_error_free_endpoint; | ||
901 | |||
902 | /* | ||
844 | * push packet | 903 | * push packet |
845 | */ | 904 | */ |
846 | if (usb_pipecontrol(urb->pipe)) | 905 | if (usb_pipecontrol(urb->pipe)) |
@@ -850,6 +909,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
850 | 909 | ||
851 | return ret; | 910 | return ret; |
852 | 911 | ||
912 | usbhsh_urb_enqueue_error_free_endpoint: | ||
913 | usbhsh_endpoint_detach(hpriv, ep); | ||
853 | usbhsh_urb_enqueue_error_free_device: | 914 | usbhsh_urb_enqueue_error_free_device: |
854 | if (new_udev) | 915 | if (new_udev) |
855 | usbhsh_device_detach(hpriv, new_udev); | 916 | usbhsh_device_detach(hpriv, new_udev); |
@@ -1192,7 +1253,6 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv, | |||
1192 | static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | 1253 | static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) |
1193 | { | 1254 | { |
1194 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1255 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1195 | struct usbhsh_pipe_info *pipe_info = hpriv->pipe_info; | ||
1196 | struct usbhs_pipe *pipe; | 1256 | struct usbhs_pipe *pipe; |
1197 | u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); | 1257 | u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); |
1198 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | 1258 | int pipe_size = usbhs_get_dparam(priv, pipe_size); |
@@ -1201,7 +1261,6 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | |||
1201 | /* init all pipe */ | 1261 | /* init all pipe */ |
1202 | old_type = USB_ENDPOINT_XFER_CONTROL; | 1262 | old_type = USB_ENDPOINT_XFER_CONTROL; |
1203 | for (i = 0; i < pipe_size; i++) { | 1263 | for (i = 0; i < pipe_size; i++) { |
1204 | pipe_info[i].usr_cnt = 0; | ||
1205 | 1264 | ||
1206 | /* | 1265 | /* |
1207 | * data "output" will be finished as soon as possible, | 1266 | * data "output" will be finished as soon as possible, |
@@ -1235,7 +1294,7 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | |||
1235 | dir_in); | 1294 | dir_in); |
1236 | } | 1295 | } |
1237 | 1296 | ||
1238 | pipe->mod_private = pipe_info + i; | 1297 | pipe->mod_private = NULL; |
1239 | } | 1298 | } |
1240 | } | 1299 | } |
1241 | 1300 | ||
@@ -1312,10 +1371,8 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1312 | { | 1371 | { |
1313 | struct usbhsh_hpriv *hpriv; | 1372 | struct usbhsh_hpriv *hpriv; |
1314 | struct usb_hcd *hcd; | 1373 | struct usb_hcd *hcd; |
1315 | struct usbhsh_pipe_info *pipe_info; | ||
1316 | struct usbhsh_device *udev; | 1374 | struct usbhsh_device *udev; |
1317 | struct device *dev = usbhs_priv_to_dev(priv); | 1375 | struct device *dev = usbhs_priv_to_dev(priv); |
1318 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | ||
1319 | int i; | 1376 | int i; |
1320 | 1377 | ||
1321 | /* initialize hcd */ | 1378 | /* initialize hcd */ |
@@ -1325,12 +1382,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1325 | return -ENOMEM; | 1382 | return -ENOMEM; |
1326 | } | 1383 | } |
1327 | 1384 | ||
1328 | pipe_info = kzalloc(sizeof(*pipe_info) * pipe_size, GFP_KERNEL); | ||
1329 | if (!pipe_info) { | ||
1330 | dev_err(dev, "Could not allocate pipe_info\n"); | ||
1331 | goto usbhs_mod_host_probe_err; | ||
1332 | } | ||
1333 | |||
1334 | /* | 1385 | /* |
1335 | * CAUTION | 1386 | * CAUTION |
1336 | * | 1387 | * |
@@ -1350,8 +1401,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1350 | hpriv->mod.name = "host"; | 1401 | hpriv->mod.name = "host"; |
1351 | hpriv->mod.start = usbhsh_start; | 1402 | hpriv->mod.start = usbhsh_start; |
1352 | hpriv->mod.stop = usbhsh_stop; | 1403 | hpriv->mod.stop = usbhsh_stop; |
1353 | hpriv->pipe_info = pipe_info; | ||
1354 | hpriv->pipe_size = pipe_size; | ||
1355 | usbhsh_port_stat_init(hpriv); | 1404 | usbhsh_port_stat_init(hpriv); |
1356 | 1405 | ||
1357 | /* init all device */ | 1406 | /* init all device */ |
@@ -1363,11 +1412,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1363 | dev_info(dev, "host probed\n"); | 1412 | dev_info(dev, "host probed\n"); |
1364 | 1413 | ||
1365 | return 0; | 1414 | return 0; |
1366 | |||
1367 | usbhs_mod_host_probe_err: | ||
1368 | usb_put_hcd(hcd); | ||
1369 | |||
1370 | return -ENOMEM; | ||
1371 | } | 1415 | } |
1372 | 1416 | ||
1373 | int usbhs_mod_host_remove(struct usbhs_priv *priv) | 1417 | int usbhs_mod_host_remove(struct usbhs_priv *priv) |