diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 45 |
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 | ||
322 | usbhsh_pipe_attach_done: | 327 | usbhsh_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 | */ |
922 | static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | 931 | static 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, | |||
1072 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | 1087 | static 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 | ||