aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/mod_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 069cd765400c..3d3cd6ca2689 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
@@ -346,7 +354,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,
346 354
347 if (unlikely(!pipe)) { 355 if (unlikely(!pipe)) {
348 dev_err(dev, "uep doens't have pipe\n"); 356 dev_err(dev, "uep doens't have pipe\n");
349 } else { 357 } else if (1 == uep->counter--) { /* last user */
350 struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); 358 struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep);
351 struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); 359 struct usbhsh_device *udev = usbhsh_uep_to_udev(uep);
352 360
@@ -391,6 +399,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv,
391 /* 399 /*
392 * init endpoint 400 * init endpoint
393 */ 401 */
402 uep->counter = 0;
394 INIT_LIST_HEAD(&uep->ep_list); 403 INIT_LIST_HEAD(&uep->ep_list);
395 list_add_tail(&uep->ep_list, &udev->ep_list_head); 404 list_add_tail(&uep->ep_list, &udev->ep_list_head);
396 405
@@ -686,9 +695,9 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
686 } 695 }
687 696
688 if (usb_pipein(urb->pipe)) 697 if (usb_pipein(urb->pipe))
689 pipe->handler = &usbhs_fifo_pio_pop_handler; 698 pipe->handler = &usbhs_fifo_dma_pop_handler;
690 else 699 else
691 pipe->handler = &usbhs_fifo_pio_push_handler; 700 pipe->handler = &usbhs_fifo_dma_push_handler;
692 701
693 buf = (void *)(urb->transfer_buffer + urb->actual_length); 702 buf = (void *)(urb->transfer_buffer + urb->actual_length);
694 len = urb->transfer_buffer_length - urb->actual_length; 703 len = urb->transfer_buffer_length - urb->actual_length;
@@ -921,6 +930,19 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
921 */ 930 */
922static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 931static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
923{ 932{
933 if (map) {
934 struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt);
935 struct urb *urb = ureq->urb;
936
937 /* it can not use scatter/gather */
938 if (urb->num_sgs)
939 return -EINVAL;
940
941 pkt->dma = urb->transfer_dma;
942 if (!pkt->dma)
943 return -EINVAL;
944 }
945
924 return 0; 946 return 0;
925} 947}
926 948
@@ -946,7 +968,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
946 struct usb_host_endpoint *ep = urb->ep; 968 struct usb_host_endpoint *ep = urb->ep;
947 struct usbhsh_device *new_udev = NULL; 969 struct usbhsh_device *new_udev = NULL;
948 int is_dir_in = usb_pipein(urb->pipe); 970 int is_dir_in = usb_pipein(urb->pipe);
949 int i;
950 int ret; 971 int ret;
951 972
952 dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); 973 dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
@@ -992,13 +1013,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
992 * attach pipe to endpoint 1013 * attach pipe to endpoint
993 * see [image of mod_host] 1014 * see [image of mod_host]
994 */ 1015 */
995 for (i = 0; i < 1024; i++) { 1016 ret = usbhsh_pipe_attach(hpriv, urb);
996 ret = usbhsh_pipe_attach(hpriv, urb);
997 if (ret < 0)
998 msleep(100);
999 else
1000 break;
1001 }
1002 if (ret < 0) { 1017 if (ret < 0) {
1003 dev_err(dev, "pipe attach failed\n"); 1018 dev_err(dev, "pipe attach failed\n");
1004 goto usbhsh_urb_enqueue_error_free_endpoint; 1019 goto usbhsh_urb_enqueue_error_free_endpoint;
@@ -1072,8 +1087,6 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd,
1072static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) 1087static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf)
1073{ 1088{
1074 struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); 1089 struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
1075 struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
1076 struct device *dev = usbhs_priv_to_dev(priv);
1077 int roothub_id = 1; /* only 1 root hub */ 1090 int roothub_id = 1; /* only 1 root hub */
1078 1091
1079 /* 1092 /*
@@ -1085,8 +1098,6 @@ static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf)
1085 else 1098 else
1086 *buf = 0; 1099 *buf = 0;
1087 1100
1088 dev_dbg(dev, "%s (%02x)\n", __func__, *buf);
1089
1090 return !!(*buf); 1101 return !!(*buf);
1091} 1102}
1092 1103