| From bddfc00d111a346e29ef152840d3116d37929bad Mon Sep 17 00:00:00 2001 |
| From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| Date: Wed, 9 Jul 2014 20:30:13 +0900 |
| Subject: usb: renesas_usbhs: gadget: fix re-enabling pipe without |
| re-connecting |
| |
| This patch fixes an issue that the renesas_usbhs driver in gadget mode |
| cannot work correctly even if I disabled DMAC of the driver when I used |
| the g_zero driver and the testusb tool. |
| |
| When a usb cable is re-connected, the renesas_usbhs driver calls the |
| usbhsp_flags_init() (via usbhs_hotplug() --> usbhs_mod_call(start) --> |
| usbhsg_try_start() --> usbhs_pipe_init()). However, the driver doesn't |
| call the usbhsp_flags_init() when usbhsg_ep_disable() is called. |
| So, if a gadget driver calls usb_ep_enable() and usb_ep_disable() again |
| and again, the renesas_usbhs driver will output the following log: |
| |
| renesas_usbhs renesas_usbhs: can't get pipe (BULK) |
| renesas_usbhs renesas_usbhs: wrong recip request |
| |
| Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| Signed-off-by: Felipe Balbi <balbi@ti.com> |
| (cherry picked from commit dfb87b8bfe09f933abaf387693992089f6f9053e) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/renesas_usbhs/mod_gadget.c | 2 ++ |
| drivers/usb/renesas_usbhs/pipe.c | 10 ++++++++++ |
| drivers/usb/renesas_usbhs/pipe.h | 1 + |
| 3 files changed, 13 insertions(+) |
| |
| diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c |
| index 458f3766bef1..04e6505777d0 100644 |
| --- a/drivers/usb/renesas_usbhs/mod_gadget.c |
| +++ b/drivers/usb/renesas_usbhs/mod_gadget.c |
| @@ -600,8 +600,10 @@ static int usbhsg_ep_enable(struct usb_ep *ep, |
| static int usbhsg_ep_disable(struct usb_ep *ep) |
| { |
| struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
| + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
| |
| usbhsg_pipe_disable(uep); |
| + usbhs_pipe_free(pipe); |
| |
| uep->pipe->mod_private = NULL; |
| uep->pipe = NULL; |
| diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c |
| index 239b889ca5b5..75fbcf6b102e 100644 |
| --- a/drivers/usb/renesas_usbhs/pipe.c |
| +++ b/drivers/usb/renesas_usbhs/pipe.c |
| @@ -640,6 +640,11 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type) |
| return pipe; |
| } |
| |
| +static void usbhsp_put_pipe(struct usbhs_pipe *pipe) |
| +{ |
| + usbhsp_flags_init(pipe); |
| +} |
| + |
| void usbhs_pipe_init(struct usbhs_priv *priv, |
| int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map)) |
| { |
| @@ -727,6 +732,11 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, |
| return pipe; |
| } |
| |
| +void usbhs_pipe_free(struct usbhs_pipe *pipe) |
| +{ |
| + usbhsp_put_pipe(pipe); |
| +} |
| + |
| void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) |
| { |
| if (pipe->fifo) |
| diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h |
| index 3e5349879838..406f36d050e4 100644 |
| --- a/drivers/usb/renesas_usbhs/pipe.h |
| +++ b/drivers/usb/renesas_usbhs/pipe.h |
| @@ -75,6 +75,7 @@ struct usbhs_pipe_info { |
| char *usbhs_pipe_name(struct usbhs_pipe *pipe); |
| struct usbhs_pipe |
| *usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in); |
| +void usbhs_pipe_free(struct usbhs_pipe *pipe); |
| int usbhs_pipe_probe(struct usbhs_priv *priv); |
| void usbhs_pipe_remove(struct usbhs_priv *priv); |
| int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); |
| -- |
| 2.1.2 |
| |