aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-12-08 21:27:49 -0500
committerFelipe Balbi <balbi@ti.com>2011-12-13 06:06:24 -0500
commite4c57ded48d9bad95a4d7254e75a81f7abcffef9 (patch)
treea9a7514ee43bbd2f530236b4af73565cd6c7db49 /drivers
parentc1e4877a4106a31319c4ad65b625c11393df98d6 (diff)
usb: renesas_usbhs: add usbhsh_endpoint_detach_all() for error case
This patch adds usbhsh_endpoint_detach_all() for error case. usbhs_endpoitn_xxx() functions were moved to upper side in source code. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c302
1 files changed, 163 insertions, 139 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 164f28ee9610..5b6ae2a8d303 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -84,6 +84,7 @@ struct usbhsh_device {
84struct usbhsh_ep { 84struct usbhsh_ep {
85 struct usbhs_pipe *pipe; 85 struct usbhs_pipe *pipe;
86 struct usbhsh_device *udev; /* attached udev */ 86 struct usbhsh_device *udev; /* attached udev */
87 struct usb_host_endpoint *ep;
87 struct list_head ep_list; /* list to usbhsh_device */ 88 struct list_head ep_list; /* list to usbhsh_device */
88 89
89 int maxp; 90 int maxp;
@@ -147,6 +148,8 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host";
147#define usbhsh_ep_to_uep(u) ((u)->hcpriv) 148#define usbhsh_ep_to_uep(u) ((u)->hcpriv)
148#define usbhsh_uep_to_pipe(u) ((u)->pipe) 149#define usbhsh_uep_to_pipe(u) ((u)->pipe)
149#define usbhsh_uep_to_udev(u) ((u)->udev) 150#define usbhsh_uep_to_udev(u) ((u)->udev)
151#define usbhsh_uep_to_ep(u) ((u)->ep)
152
150#define usbhsh_urb_to_ureq(u) ((u)->hcpriv) 153#define usbhsh_urb_to_ureq(u) ((u)->hcpriv)
151#define usbhsh_urb_to_usbv(u) ((u)->dev) 154#define usbhsh_urb_to_usbv(u) ((u)->dev)
152 155
@@ -205,6 +208,157 @@ static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv,
205} 208}
206 209
207/* 210/*
211 * end-point control
212 */
213static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv,
214 struct urb *urb);
215static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
216 struct urb *urb,
217 gfp_t mem_flags)
218{
219 struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
220 struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb);
221 struct usb_host_endpoint *ep = urb->ep;
222 struct usbhsh_ep *uep;
223 struct usbhsh_pipe_info *info;
224 struct usbhs_pipe *best_pipe = NULL;
225 struct device *dev = usbhs_priv_to_dev(priv);
226 struct usb_endpoint_descriptor *desc = &ep->desc;
227 unsigned long flags;
228
229 uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
230 if (!uep) {
231 dev_err(dev, "usbhsh_ep alloc fail\n");
232 return -ENOMEM;
233 }
234
235 /******************** spin lock ********************/
236 usbhs_lock(priv, flags);
237
238 /*
239 * find best pipe for endpoint
240 * see
241 * HARDWARE LIMITATION
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
252 usbhs_for_each_pipe(pipe, priv, i) {
253 if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc)))
254 continue;
255
256 dir_in = !!usbhs_pipe_is_dir_in(pipe);
257 if (0 != (dir_in - dir_in_req))
258 continue;
259
260 info = usbhsh_pipe_info(pipe);
261 if (min_usr > info->usr_cnt) {
262 min_usr = info->usr_cnt;
263 best_pipe = pipe;
264 }
265 }
266 }
267
268 if (best_pipe) {
269 /* update pipe user count */
270 info = usbhsh_pipe_info(best_pipe);
271 info->usr_cnt++;
272
273 /* init this endpoint, and attach it to udev */
274 INIT_LIST_HEAD(&uep->ep_list);
275 list_add_tail(&uep->ep_list, &udev->ep_list_head);
276 }
277
278 usbhs_unlock(priv, flags);
279 /******************** spin unlock ******************/
280
281 if (unlikely(!best_pipe)) {
282 dev_err(dev, "couldn't find best pipe\n");
283 kfree(uep);
284 return -EIO;
285 }
286
287 /*
288 * init uep
289 */
290 uep->pipe = best_pipe;
291 uep->maxp = usb_endpoint_maxp(desc);
292 usbhsh_uep_to_udev(uep) = udev;
293 usbhsh_uep_to_ep(uep) = ep;
294 usbhsh_ep_to_uep(ep) = uep;
295
296 /*
297 * usbhs_pipe_config_update() should be called after
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
308 dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
309 usbhsh_device_number(hpriv, udev),
310 usbhs_pipe_name(uep->pipe), uep);
311
312 return 0;
313}
314
315static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv,
316 struct usb_host_endpoint *ep)
317{
318 struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
319 struct device *dev = usbhs_priv_to_dev(priv);
320 struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep);
321 struct usbhsh_pipe_info *info;
322 unsigned long flags;
323
324 if (!uep)
325 return;
326
327 dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
328 usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)),
329 usbhs_pipe_name(uep->pipe), uep);
330
331 /******************** spin lock ********************/
332 usbhs_lock(priv, flags);
333
334 info = usbhsh_pipe_info(uep->pipe);
335 info->usr_cnt--;
336
337 /* remove this endpoint from udev */
338 list_del_init(&uep->ep_list);
339
340 uep->pipe = NULL;
341 uep->maxp = 0;
342 usbhsh_uep_to_udev(uep) = NULL;
343 usbhsh_uep_to_ep(uep) = NULL;
344 usbhsh_ep_to_uep(ep) = NULL;
345
346 usbhs_unlock(priv, flags);
347 /******************** spin unlock ******************/
348
349 kfree(uep);
350}
351
352static void usbhsh_endpoint_detach_all(struct usbhsh_hpriv *hpriv,
353 struct usbhsh_device *udev)
354{
355 struct usbhsh_ep *uep, *next;
356
357 list_for_each_entry_safe(uep, next, &udev->ep_list_head, ep_list)
358 usbhsh_endpoint_detach(hpriv, usbhsh_uep_to_ep(uep));
359}
360
361/*
208 * device control 362 * device control
209 */ 363 */
210static int usbhsh_connected_to_rhdev(struct usb_hcd *hcd, 364static int usbhsh_connected_to_rhdev(struct usb_hcd *hcd,
@@ -295,11 +449,15 @@ static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv,
295 return NULL; 449 return NULL;
296 } 450 }
297 451
298 if (usbhsh_device_has_endpoint(udev)) 452 if (usbhsh_device_has_endpoint(udev)) {
299 dev_warn(dev, "udev have old endpoint\n"); 453 dev_warn(dev, "udev have old endpoint\n");
454 usbhsh_endpoint_detach_all(hpriv, udev);
455 }
300 456
301 if (usbhsh_device_has_endpoint(udev0)) 457 if (usbhsh_device_has_endpoint(udev0)) {
302 dev_warn(dev, "udev0 have old endpoint\n"); 458 dev_warn(dev, "udev0 have old endpoint\n");
459 usbhsh_endpoint_detach_all(hpriv, udev0);
460 }
303 461
304 /* uep will be attached */ 462 /* uep will be attached */
305 INIT_LIST_HEAD(&udev0->ep_list_head); 463 INIT_LIST_HEAD(&udev0->ep_list_head);
@@ -349,8 +507,10 @@ static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv,
349 dev_dbg(dev, "%s [%d](%p)\n", __func__, 507 dev_dbg(dev, "%s [%d](%p)\n", __func__,
350 usbhsh_device_number(hpriv, udev), udev); 508 usbhsh_device_number(hpriv, udev), udev);
351 509
352 if (usbhsh_device_has_endpoint(udev)) 510 if (usbhsh_device_has_endpoint(udev)) {
353 dev_warn(dev, "udev still have endpoint\n"); 511 dev_warn(dev, "udev still have endpoint\n");
512 usbhsh_endpoint_detach_all(hpriv, udev);
513 }
354 514
355 /* 515 /*
356 * There is nothing to do if it is device0. 516 * There is nothing to do if it is device0.
@@ -377,142 +537,6 @@ static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv,
377} 537}
378 538
379/* 539/*
380 * end-point control
381 */
382static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
383 struct urb *urb,
384 gfp_t mem_flags)
385{
386 struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
387 struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb);
388 struct usb_host_endpoint *ep = urb->ep;
389 struct usbhsh_ep *uep;
390 struct usbhsh_pipe_info *info;
391 struct usbhs_pipe *best_pipe = NULL;
392 struct device *dev = usbhs_priv_to_dev(priv);
393 struct usb_endpoint_descriptor *desc = &ep->desc;
394 unsigned long flags;
395
396 uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
397 if (!uep) {
398 dev_err(dev, "usbhsh_ep alloc fail\n");
399 return -ENOMEM;
400 }
401
402 /******************** spin lock ********************/
403 usbhs_lock(priv, flags);
404
405 /*
406 * find best pipe for endpoint
407 * see
408 * HARDWARE LIMITATION
409 */
410 if (usb_endpoint_xfer_control(desc)) {
411 /* best pipe is DCP */
412 best_pipe = usbhsh_hpriv_to_dcp(hpriv);
413 } else {
414 struct usbhs_pipe *pipe;
415 unsigned int min_usr = ~0;
416 int dir_in_req = !!usb_pipein(urb->pipe);
417 int i, dir_in;
418
419 usbhs_for_each_pipe(pipe, priv, i) {
420 if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc)))
421 continue;
422
423 dir_in = !!usbhs_pipe_is_dir_in(pipe);
424 if (0 != (dir_in - dir_in_req))
425 continue;
426
427 info = usbhsh_pipe_info(pipe);
428 if (min_usr > info->usr_cnt) {
429 min_usr = info->usr_cnt;
430 best_pipe = pipe;
431 }
432 }
433 }
434
435 if (best_pipe) {
436 /* update pipe user count */
437 info = usbhsh_pipe_info(best_pipe);
438 info->usr_cnt++;
439
440 /* init this endpoint, and attach it to udev */
441 INIT_LIST_HEAD(&uep->ep_list);
442 list_add_tail(&uep->ep_list, &udev->ep_list_head);
443 }
444
445 usbhs_unlock(priv, flags);
446 /******************** spin unlock ******************/
447
448 if (unlikely(!best_pipe)) {
449 dev_err(dev, "couldn't find best pipe\n");
450 kfree(uep);
451 return -EIO;
452 }
453
454 /*
455 * init uep
456 */
457 uep->pipe = best_pipe;
458 uep->maxp = usb_endpoint_maxp(desc);
459 usbhsh_uep_to_udev(uep) = udev;
460 usbhsh_ep_to_uep(ep) = uep;
461
462 /*
463 * usbhs_pipe_config_update() should be called after
464 * usbhs_set_device_config()
465 * see
466 * DCPMAXP/PIPEMAXP
467 */
468 usbhs_pipe_sequence_data0(uep->pipe);
469 usbhs_pipe_config_update(uep->pipe,
470 usbhsh_device_number(hpriv, udev),
471 usb_endpoint_num(desc),
472 uep->maxp);
473
474 dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
475 usbhsh_device_number(hpriv, udev),
476 usbhs_pipe_name(uep->pipe), uep);
477
478 return 0;
479}
480
481static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv,
482 struct usb_host_endpoint *ep)
483{
484 struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
485 struct device *dev = usbhs_priv_to_dev(priv);
486 struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep);
487 struct usbhsh_pipe_info *info;
488 unsigned long flags;
489
490 if (!uep)
491 return;
492
493 dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
494 usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)),
495 usbhs_pipe_name(uep->pipe), uep);
496
497 /******************** spin lock ********************/
498 usbhs_lock(priv, flags);
499
500 info = usbhsh_pipe_info(uep->pipe);
501 info->usr_cnt--;
502
503 /* remove this endpoint from udev */
504 list_del_init(&uep->ep_list);
505
506 usbhsh_uep_to_udev(uep) = NULL;
507 usbhsh_ep_to_uep(ep) = NULL;
508
509 usbhs_unlock(priv, flags);
510 /******************** spin unlock ******************/
511
512 kfree(uep);
513}
514
515/*
516 * queue push/pop 540 * queue push/pop
517 */ 541 */
518static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) 542static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)