aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-11-06 03:11:53 -0500
committerFelipe Balbi <balbi@ti.com>2012-11-06 08:04:28 -0500
commit7b332e5fef480ee14d133d9b83af22d03819368e (patch)
treed9720f428f53b4038de082815e0089f7e0c250a2 /drivers/usb
parent24e4c1c30da3926db547aab4ec873afdc60bd3ee (diff)
usb: renesas_usbhs: host: add endpoint user counter
renesas_usbhs attaches pipe to endpoint when urb was queued, and it will be detached when transfer was done. Multi device controlling was enabled by this behavior. Now renesas_usbhs driver tried to wait until detaching if urb was queued to endpoint which already has been attached to pipe, and it created strange driver behavior. But it can re-use this attached pipe if multi urb was queued. This patch implements it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 33f706387237..73c5039f7670 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -85,6 +85,7 @@ struct usbhsh_ep {
85 struct usbhsh_device *udev; /* attached udev */ 85 struct usbhsh_device *udev; /* attached udev */
86 struct usb_host_endpoint *ep; 86 struct usb_host_endpoint *ep;
87 struct list_head ep_list; /* list to usbhsh_device */ 87 struct list_head ep_list; /* list to usbhsh_device */
88 unsigned int counter; /* pipe attach counter */
88}; 89};
89 90
90#define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ 91#define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */
@@ -271,8 +272,12 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
271 /******************** spin lock ********************/ 272 /******************** spin lock ********************/
272 usbhs_lock(priv, flags); 273 usbhs_lock(priv, flags);
273 274
274 if (unlikely(usbhsh_uep_to_pipe(uep))) { 275 /*
275 dev_err(dev, "uep already has pipe\n"); 276 * if uep has been attached to pipe,
277 * reuse it
278 */
279 if (usbhsh_uep_to_pipe(uep)) {
280 ret = 0;
276 goto usbhsh_pipe_attach_done; 281 goto usbhsh_pipe_attach_done;
277 } 282 }
278 283
@@ -320,6 +325,9 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv,
320 } 325 }
321 326
322usbhsh_pipe_attach_done: 327usbhsh_pipe_attach_done:
328 if (0 == ret)
329 uep->counter++;
330
323 usbhs_unlock(priv, flags); 331 usbhs_unlock(priv, flags);
324 /******************** spin unlock ******************/ 332 /******************** spin unlock ******************/
325 333
@@ -341,7 +349,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,
341 349
342 if (unlikely(!pipe)) { 350 if (unlikely(!pipe)) {
343 dev_err(dev, "uep doens't have pipe\n"); 351 dev_err(dev, "uep doens't have pipe\n");
344 } else { 352 } else if (1 == uep->counter--) { /* last user */
345 struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); 353 struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep);
346 struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); 354 struct usbhsh_device *udev = usbhsh_uep_to_udev(uep);
347 355
@@ -386,6 +394,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
386 /* 394 /*
387 * init endpoint 395 * init endpoint
388 */ 396 */
397 uep->counter = 0;
389 INIT_LIST_HEAD(&uep->ep_list); 398 INIT_LIST_HEAD(&uep->ep_list);
390 list_add_tail(&uep->ep_list, &udev->ep_list_head); 399 list_add_tail(&uep->ep_list, &udev->ep_list_head);
391 400
@@ -954,7 +963,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
954 struct usb_host_endpoint *ep = urb->ep; 963 struct usb_host_endpoint *ep = urb->ep;
955 struct usbhsh_device *new_udev = NULL; 964 struct usbhsh_device *new_udev = NULL;
956 int is_dir_in = usb_pipein(urb->pipe); 965 int is_dir_in = usb_pipein(urb->pipe);
957 int i;
958 int ret; 966 int ret;
959 967
960 dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); 968 dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
@@ -1000,13 +1008,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
1000 * attach pipe to endpoint 1008 * attach pipe to endpoint
1001 * see [image of mod_host] 1009 * see [image of mod_host]
1002 */ 1010 */
1003 for (i = 0; i < 1024; i++) { 1011 ret = usbhsh_pipe_attach(hpriv, urb);
1004 ret = usbhsh_pipe_attach(hpriv, urb);
1005 if (ret < 0)
1006 msleep(100);
1007 else
1008 break;
1009 }
1010 if (ret < 0) { 1012 if (ret < 0) {
1011 dev_err(dev, "pipe attach failed\n"); 1013 dev_err(dev, "pipe attach failed\n");
1012 goto usbhsh_urb_enqueue_error_free_endpoint; 1014 goto usbhsh_urb_enqueue_error_free_endpoint;