diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
| -rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 069cd765400c..b86815421c8d 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 | ||
| @@ -652,9 +661,10 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | |||
| 652 | status = -ESHUTDOWN; | 661 | status = -ESHUTDOWN; |
| 653 | 662 | ||
| 654 | urb->actual_length = pkt->actual; | 663 | urb->actual_length = pkt->actual; |
| 655 | usbhsh_ureq_free(hpriv, ureq); | ||
| 656 | 664 | ||
| 657 | usbhsh_endpoint_sequence_save(hpriv, urb, pkt); | 665 | usbhsh_endpoint_sequence_save(hpriv, urb, pkt); |
| 666 | usbhsh_ureq_free(hpriv, ureq); | ||
| 667 | |||
| 658 | usbhsh_pipe_detach(hpriv, usbhsh_ep_to_uep(urb->ep)); | 668 | usbhsh_pipe_detach(hpriv, usbhsh_ep_to_uep(urb->ep)); |
| 659 | 669 | ||
| 660 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 670 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
| @@ -686,9 +696,9 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, | |||
| 686 | } | 696 | } |
| 687 | 697 | ||
| 688 | if (usb_pipein(urb->pipe)) | 698 | if (usb_pipein(urb->pipe)) |
| 689 | pipe->handler = &usbhs_fifo_pio_pop_handler; | 699 | pipe->handler = &usbhs_fifo_dma_pop_handler; |
| 690 | else | 700 | else |
| 691 | pipe->handler = &usbhs_fifo_pio_push_handler; | 701 | pipe->handler = &usbhs_fifo_dma_push_handler; |
| 692 | 702 | ||
| 693 | buf = (void *)(urb->transfer_buffer + urb->actual_length); | 703 | buf = (void *)(urb->transfer_buffer + urb->actual_length); |
| 694 | len = urb->transfer_buffer_length - urb->actual_length; | 704 | len = urb->transfer_buffer_length - urb->actual_length; |
| @@ -921,6 +931,19 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, | |||
| 921 | */ | 931 | */ |
| 922 | static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | 932 | static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) |
| 923 | { | 933 | { |
| 934 | if (map) { | ||
| 935 | struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); | ||
| 936 | struct urb *urb = ureq->urb; | ||
| 937 | |||
| 938 | /* it can not use scatter/gather */ | ||
| 939 | if (urb->num_sgs) | ||
| 940 | return -EINVAL; | ||
| 941 | |||
| 942 | pkt->dma = urb->transfer_dma; | ||
| 943 | if (!pkt->dma) | ||
| 944 | return -EINVAL; | ||
| 945 | } | ||
| 946 | |||
| 924 | return 0; | 947 | return 0; |
| 925 | } | 948 | } |
| 926 | 949 | ||
| @@ -946,7 +969,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
| 946 | struct usb_host_endpoint *ep = urb->ep; | 969 | struct usb_host_endpoint *ep = urb->ep; |
| 947 | struct usbhsh_device *new_udev = NULL; | 970 | struct usbhsh_device *new_udev = NULL; |
| 948 | int is_dir_in = usb_pipein(urb->pipe); | 971 | int is_dir_in = usb_pipein(urb->pipe); |
| 949 | int i; | ||
| 950 | int ret; | 972 | int ret; |
| 951 | 973 | ||
| 952 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); | 974 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
| @@ -992,13 +1014,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
| 992 | * attach pipe to endpoint | 1014 | * attach pipe to endpoint |
| 993 | * see [image of mod_host] | 1015 | * see [image of mod_host] |
| 994 | */ | 1016 | */ |
| 995 | for (i = 0; i < 1024; i++) { | 1017 | 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) { | 1018 | if (ret < 0) { |
| 1003 | dev_err(dev, "pipe attach failed\n"); | 1019 | dev_err(dev, "pipe attach failed\n"); |
| 1004 | goto usbhsh_urb_enqueue_error_free_endpoint; | 1020 | goto usbhsh_urb_enqueue_error_free_endpoint; |
| @@ -1072,8 +1088,6 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, | |||
| 1072 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | 1088 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) |
| 1073 | { | 1089 | { |
| 1074 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); | 1090 | 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 */ | 1091 | int roothub_id = 1; /* only 1 root hub */ |
| 1078 | 1092 | ||
| 1079 | /* | 1093 | /* |
| @@ -1085,8 +1099,6 @@ static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
| 1085 | else | 1099 | else |
| 1086 | *buf = 0; | 1100 | *buf = 0; |
| 1087 | 1101 | ||
| 1088 | dev_dbg(dev, "%s (%02x)\n", __func__, *buf); | ||
| 1089 | |||
| 1090 | return !!(*buf); | 1102 | return !!(*buf); |
| 1091 | } | 1103 | } |
| 1092 | 1104 | ||
