diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-10-24 05:24:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-14 14:51:29 -0500 |
commit | 73ef635a07c0e6a0a159d8beabffb83399429188 (patch) | |
tree | bcf776025ffd5f18293356a80dfa778625470715 /drivers/usb | |
parent | 4703d2e9d06cd1e5add773aa6cc5587e6664bf78 (diff) |
usb: gadget: renesas_usbhs: bugfix: care pipe direction
renesas_usbhs is caring pipe type and its direction.
but current usbhs_endpoint_alloc() didn't check direction.
this patch modify it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index b964f25ebdb7..f8f612c46ea4 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, | |||
355 | struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | 355 | struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, |
356 | struct usbhsh_device *udev, | 356 | struct usbhsh_device *udev, |
357 | struct usb_host_endpoint *ep, | 357 | struct usb_host_endpoint *ep, |
358 | int dir_in_req, | ||
358 | gfp_t mem_flags) | 359 | gfp_t mem_flags) |
359 | { | 360 | { |
360 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 361 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
@@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
364 | struct usbhs_pipe *pipe, *best_pipe; | 365 | struct usbhs_pipe *pipe, *best_pipe; |
365 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 366 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
366 | struct usb_endpoint_descriptor *desc = &ep->desc; | 367 | struct usb_endpoint_descriptor *desc = &ep->desc; |
367 | int type, i; | 368 | int type, i, dir_in; |
368 | unsigned int min_usr; | 369 | unsigned int min_usr; |
369 | 370 | ||
371 | dir_in_req = !!dir_in_req; | ||
372 | |||
370 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | 373 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); |
371 | if (!uep) { | 374 | if (!uep) { |
372 | dev_err(dev, "usbhsh_ep alloc fail\n"); | 375 | dev_err(dev, "usbhsh_ep alloc fail\n"); |
373 | return NULL; | 376 | return NULL; |
374 | } | 377 | } |
375 | type = usb_endpoint_type(desc); | 378 | |
379 | if (usb_endpoint_xfer_control(desc)) { | ||
380 | best_pipe = usbhsh_hpriv_to_dcp(hpriv); | ||
381 | goto usbhsh_endpoint_alloc_find_pipe; | ||
382 | } | ||
376 | 383 | ||
377 | /* | 384 | /* |
378 | * find best pipe for endpoint | 385 | * find best pipe for endpoint |
379 | * see | 386 | * see |
380 | * HARDWARE LIMITATION | 387 | * HARDWARE LIMITATION |
381 | */ | 388 | */ |
389 | type = usb_endpoint_type(desc); | ||
382 | min_usr = ~0; | 390 | min_usr = ~0; |
383 | best_pipe = NULL; | 391 | best_pipe = NULL; |
384 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | 392 | usbhs_for_each_pipe(pipe, priv, i) { |
385 | if (!usbhs_pipe_type_is(pipe, type)) | 393 | if (!usbhs_pipe_type_is(pipe, type)) |
386 | continue; | 394 | continue; |
387 | 395 | ||
396 | dir_in = !!usbhs_pipe_is_dir_in(pipe); | ||
397 | if (0 != (dir_in - dir_in_req)) | ||
398 | continue; | ||
399 | |||
388 | info = usbhsh_pipe_info(pipe); | 400 | info = usbhsh_pipe_info(pipe); |
389 | 401 | ||
390 | if (min_usr > info->usr_cnt) { | 402 | if (min_usr > info->usr_cnt) { |
@@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
398 | kfree(uep); | 410 | kfree(uep); |
399 | return NULL; | 411 | return NULL; |
400 | } | 412 | } |
401 | 413 | usbhsh_endpoint_alloc_find_pipe: | |
402 | /* | 414 | /* |
403 | * init uep | 415 | * init uep |
404 | */ | 416 | */ |
@@ -430,7 +442,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | |||
430 | 442 | ||
431 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 443 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, |
432 | usbhsh_device_number(hpriv, udev), | 444 | usbhsh_device_number(hpriv, udev), |
433 | usbhs_pipe_name(pipe), uep); | 445 | usbhs_pipe_name(uep->pipe), uep); |
434 | 446 | ||
435 | return uep; | 447 | return uep; |
436 | } | 448 | } |
@@ -722,11 +734,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
722 | struct usbhsh_device *udev, *new_udev = NULL; | 734 | struct usbhsh_device *udev, *new_udev = NULL; |
723 | struct usbhs_pipe *pipe; | 735 | struct usbhs_pipe *pipe; |
724 | struct usbhsh_ep *uep; | 736 | struct usbhsh_ep *uep; |
737 | int is_dir_in = usb_pipein(urb->pipe); | ||
725 | 738 | ||
726 | int ret; | 739 | int ret; |
727 | 740 | ||
728 | dev_dbg(dev, "%s (%s)\n", | 741 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
729 | __func__, usb_pipein(urb->pipe) ? "in" : "out"); | ||
730 | 742 | ||
731 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 743 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
732 | if (ret) | 744 | if (ret) |
@@ -749,7 +761,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
749 | */ | 761 | */ |
750 | uep = usbhsh_ep_to_uep(ep); | 762 | uep = usbhsh_ep_to_uep(ep); |
751 | if (!uep) { | 763 | if (!uep) { |
752 | uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags); | 764 | uep = usbhsh_endpoint_alloc(hpriv, udev, ep, |
765 | is_dir_in, mem_flags); | ||
753 | if (!uep) | 766 | if (!uep) |
754 | goto usbhsh_urb_enqueue_error_free_device; | 767 | goto usbhsh_urb_enqueue_error_free_device; |
755 | } | 768 | } |