diff options
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
| -rw-r--r-- | drivers/usb/dwc3/ep0.c | 146 |
1 files changed, 92 insertions, 54 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9e8a3dce69fd..9b94886b66e5 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
| @@ -54,7 +54,9 @@ | |||
| 54 | #include "gadget.h" | 54 | #include "gadget.h" |
| 55 | #include "io.h" | 55 | #include "io.h" |
| 56 | 56 | ||
| 57 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum); | 57 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep); |
| 58 | static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, | ||
| 59 | struct dwc3_ep *dep, struct dwc3_request *req); | ||
| 58 | 60 | ||
| 59 | static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) | 61 | static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) |
| 60 | { | 62 | { |
| @@ -111,7 +113,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | dep->flags |= DWC3_EP_BUSY; | 115 | dep->flags |= DWC3_EP_BUSY; |
| 114 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, | 116 | dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc, |
| 115 | dep->number); | 117 | dep->number); |
| 116 | 118 | ||
| 117 | dwc->ep0_next_event = DWC3_EP0_COMPLETE; | 119 | dwc->ep0_next_event = DWC3_EP0_COMPLETE; |
| @@ -150,16 +152,15 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, | |||
| 150 | return 0; | 152 | return 0; |
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | ret = dwc3_ep0_start_trans(dwc, direction, | 155 | __dwc3_ep0_do_control_data(dwc, dwc->eps[direction], req); |
| 154 | req->request.dma, req->request.length, | 156 | |
| 155 | DWC3_TRBCTL_CONTROL_DATA); | ||
| 156 | dep->flags &= ~(DWC3_EP_PENDING_REQUEST | | 157 | dep->flags &= ~(DWC3_EP_PENDING_REQUEST | |
| 157 | DWC3_EP0_DIR_IN); | 158 | DWC3_EP0_DIR_IN); |
| 158 | } else if (dwc->delayed_status) { | 159 | } else if (dwc->delayed_status) { |
| 159 | dwc->delayed_status = false; | 160 | dwc->delayed_status = false; |
| 160 | 161 | ||
| 161 | if (dwc->ep0state == EP0_STATUS_PHASE) | 162 | if (dwc->ep0state == EP0_STATUS_PHASE) |
| 162 | dwc3_ep0_do_control_status(dwc, 1); | 163 | __dwc3_ep0_do_control_status(dwc, dwc->eps[1]); |
| 163 | else | 164 | else |
| 164 | dev_dbg(dwc->dev, "too early for delayed status\n"); | 165 | dev_dbg(dwc->dev, "too early for delayed status\n"); |
| 165 | } | 166 | } |
| @@ -224,6 +225,16 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) | |||
| 224 | dwc3_ep0_out_start(dwc); | 225 | dwc3_ep0_out_start(dwc); |
| 225 | } | 226 | } |
| 226 | 227 | ||
| 228 | int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) | ||
| 229 | { | ||
| 230 | struct dwc3_ep *dep = to_dwc3_ep(ep); | ||
| 231 | struct dwc3 *dwc = dep->dwc; | ||
| 232 | |||
| 233 | dwc3_ep0_stall_and_restart(dwc); | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 227 | void dwc3_ep0_out_start(struct dwc3 *dwc) | 238 | void dwc3_ep0_out_start(struct dwc3 *dwc) |
| 228 | { | 239 | { |
| 229 | int ret; | 240 | int ret; |
| @@ -463,6 +474,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |||
| 463 | { | 474 | { |
| 464 | u32 cfg; | 475 | u32 cfg; |
| 465 | int ret; | 476 | int ret; |
| 477 | u32 reg; | ||
| 466 | 478 | ||
| 467 | dwc->start_config_issued = false; | 479 | dwc->start_config_issued = false; |
| 468 | cfg = le16_to_cpu(ctrl->wValue); | 480 | cfg = le16_to_cpu(ctrl->wValue); |
| @@ -477,6 +489,14 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |||
| 477 | /* if the cfg matches and the cfg is non zero */ | 489 | /* if the cfg matches and the cfg is non zero */ |
| 478 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { | 490 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { |
| 479 | dwc->dev_state = DWC3_CONFIGURED_STATE; | 491 | dwc->dev_state = DWC3_CONFIGURED_STATE; |
| 492 | /* | ||
| 493 | * Enable transition to U1/U2 state when | ||
| 494 | * nothing is pending from application. | ||
| 495 | */ | ||
| 496 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
| 497 | reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); | ||
| 498 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
| 499 | |||
| 480 | dwc->resize_fifos = true; | 500 | dwc->resize_fifos = true; |
| 481 | dev_dbg(dwc->dev, "resize fifos flag SET\n"); | 501 | dev_dbg(dwc->dev, "resize fifos flag SET\n"); |
| 482 | } | 502 | } |
| @@ -514,8 +534,8 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req) | |||
| 514 | 534 | ||
| 515 | dwc->u1sel = timing.u1sel; | 535 | dwc->u1sel = timing.u1sel; |
| 516 | dwc->u1pel = timing.u1pel; | 536 | dwc->u1pel = timing.u1pel; |
| 517 | dwc->u2sel = timing.u2sel; | 537 | dwc->u2sel = le16_to_cpu(timing.u2sel); |
| 518 | dwc->u2pel = timing.u2pel; | 538 | dwc->u2pel = le16_to_cpu(timing.u2pel); |
| 519 | 539 | ||
| 520 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 540 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
| 521 | if (reg & DWC3_DCTL_INITU2ENA) | 541 | if (reg & DWC3_DCTL_INITU2ENA) |
| @@ -640,11 +660,11 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, | |||
| 640 | const struct dwc3_event_depevt *event) | 660 | const struct dwc3_event_depevt *event) |
| 641 | { | 661 | { |
| 642 | struct usb_ctrlrequest *ctrl = dwc->ctrl_req; | 662 | struct usb_ctrlrequest *ctrl = dwc->ctrl_req; |
| 643 | int ret; | 663 | int ret = -EINVAL; |
| 644 | u32 len; | 664 | u32 len; |
| 645 | 665 | ||
| 646 | if (!dwc->gadget_driver) | 666 | if (!dwc->gadget_driver) |
| 647 | goto err; | 667 | goto out; |
| 648 | 668 | ||
| 649 | len = le16_to_cpu(ctrl->wLength); | 669 | len = le16_to_cpu(ctrl->wLength); |
| 650 | if (!len) { | 670 | if (!len) { |
| @@ -665,11 +685,9 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, | |||
| 665 | if (ret == USB_GADGET_DELAYED_STATUS) | 685 | if (ret == USB_GADGET_DELAYED_STATUS) |
| 666 | dwc->delayed_status = true; | 686 | dwc->delayed_status = true; |
| 667 | 687 | ||
| 668 | if (ret >= 0) | 688 | out: |
| 669 | return; | 689 | if (ret < 0) |
| 670 | 690 | dwc3_ep0_stall_and_restart(dwc); | |
| 671 | err: | ||
| 672 | dwc3_ep0_stall_and_restart(dwc); | ||
| 673 | } | 691 | } |
| 674 | 692 | ||
| 675 | static void dwc3_ep0_complete_data(struct dwc3 *dwc, | 693 | static void dwc3_ep0_complete_data(struct dwc3 *dwc, |
| @@ -723,7 +741,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
| 723 | } | 741 | } |
| 724 | } | 742 | } |
| 725 | 743 | ||
| 726 | static void dwc3_ep0_complete_req(struct dwc3 *dwc, | 744 | static void dwc3_ep0_complete_status(struct dwc3 *dwc, |
| 727 | const struct dwc3_event_depevt *event) | 745 | const struct dwc3_event_depevt *event) |
| 728 | { | 746 | { |
| 729 | struct dwc3_request *r; | 747 | struct dwc3_request *r; |
| @@ -745,6 +763,7 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc, | |||
| 745 | dev_dbg(dwc->dev, "Invalid Test #%d\n", | 763 | dev_dbg(dwc->dev, "Invalid Test #%d\n", |
| 746 | dwc->test_mode_nr); | 764 | dwc->test_mode_nr); |
| 747 | dwc3_ep0_stall_and_restart(dwc); | 765 | dwc3_ep0_stall_and_restart(dwc); |
| 766 | return; | ||
| 748 | } | 767 | } |
| 749 | } | 768 | } |
| 750 | 769 | ||
| @@ -758,7 +777,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, | |||
| 758 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; | 777 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; |
| 759 | 778 | ||
| 760 | dep->flags &= ~DWC3_EP_BUSY; | 779 | dep->flags &= ~DWC3_EP_BUSY; |
| 761 | dep->res_trans_idx = 0; | 780 | dep->resource_index = 0; |
| 762 | dwc->setup_packet_pending = false; | 781 | dwc->setup_packet_pending = false; |
| 763 | 782 | ||
| 764 | switch (dwc->ep0state) { | 783 | switch (dwc->ep0state) { |
| @@ -774,7 +793,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, | |||
| 774 | 793 | ||
| 775 | case EP0_STATUS_PHASE: | 794 | case EP0_STATUS_PHASE: |
| 776 | dev_vdbg(dwc->dev, "Status Phase\n"); | 795 | dev_vdbg(dwc->dev, "Status Phase\n"); |
| 777 | dwc3_ep0_complete_req(dwc, event); | 796 | dwc3_ep0_complete_status(dwc, event); |
| 778 | break; | 797 | break; |
| 779 | default: | 798 | default: |
| 780 | WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state); | 799 | WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state); |
| @@ -787,68 +806,81 @@ static void dwc3_ep0_do_control_setup(struct dwc3 *dwc, | |||
| 787 | dwc3_ep0_out_start(dwc); | 806 | dwc3_ep0_out_start(dwc); |
| 788 | } | 807 | } |
| 789 | 808 | ||
| 790 | static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | 809 | static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, |
| 791 | const struct dwc3_event_depevt *event) | 810 | struct dwc3_ep *dep, struct dwc3_request *req) |
| 792 | { | 811 | { |
| 793 | struct dwc3_ep *dep; | ||
| 794 | struct dwc3_request *req; | ||
| 795 | int ret; | 812 | int ret; |
| 796 | 813 | ||
| 797 | dep = dwc->eps[0]; | 814 | req->direction = !!dep->number; |
| 798 | |||
| 799 | if (list_empty(&dep->request_list)) { | ||
| 800 | dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n"); | ||
| 801 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
| 802 | |||
| 803 | if (event->endpoint_number) | ||
| 804 | dep->flags |= DWC3_EP0_DIR_IN; | ||
| 805 | return; | ||
| 806 | } | ||
| 807 | |||
| 808 | req = next_request(&dep->request_list); | ||
| 809 | req->direction = !!event->endpoint_number; | ||
| 810 | 815 | ||
| 811 | if (req->request.length == 0) { | 816 | if (req->request.length == 0) { |
| 812 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | 817 | ret = dwc3_ep0_start_trans(dwc, dep->number, |
| 813 | dwc->ctrl_req_addr, 0, | 818 | dwc->ctrl_req_addr, 0, |
| 814 | DWC3_TRBCTL_CONTROL_DATA); | 819 | DWC3_TRBCTL_CONTROL_DATA); |
| 815 | } else if ((req->request.length % dep->endpoint.maxpacket) | 820 | } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) |
| 816 | && (event->endpoint_number == 0)) { | 821 | && (dep->number == 0)) { |
| 822 | u32 transfer_size; | ||
| 823 | |||
| 817 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, | 824 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
| 818 | event->endpoint_number); | 825 | dep->number); |
| 819 | if (ret) { | 826 | if (ret) { |
| 820 | dev_dbg(dwc->dev, "failed to map request\n"); | 827 | dev_dbg(dwc->dev, "failed to map request\n"); |
| 821 | return; | 828 | return; |
| 822 | } | 829 | } |
| 823 | 830 | ||
| 824 | WARN_ON(req->request.length > dep->endpoint.maxpacket); | 831 | WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE); |
| 832 | |||
| 833 | transfer_size = roundup(req->request.length, | ||
| 834 | (u32) dep->endpoint.maxpacket); | ||
| 825 | 835 | ||
| 826 | dwc->ep0_bounced = true; | 836 | dwc->ep0_bounced = true; |
| 827 | 837 | ||
| 828 | /* | 838 | /* |
| 829 | * REVISIT in case request length is bigger than EP0 | 839 | * REVISIT in case request length is bigger than |
| 830 | * wMaxPacketSize, we will need two chained TRBs to handle | 840 | * DWC3_EP0_BOUNCE_SIZE we will need two chained |
| 831 | * the transfer. | 841 | * TRBs to handle the transfer. |
| 832 | */ | 842 | */ |
| 833 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | 843 | ret = dwc3_ep0_start_trans(dwc, dep->number, |
| 834 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, | 844 | dwc->ep0_bounce_addr, transfer_size, |
| 835 | DWC3_TRBCTL_CONTROL_DATA); | 845 | DWC3_TRBCTL_CONTROL_DATA); |
| 836 | } else { | 846 | } else { |
| 837 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, | 847 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
| 838 | event->endpoint_number); | 848 | dep->number); |
| 839 | if (ret) { | 849 | if (ret) { |
| 840 | dev_dbg(dwc->dev, "failed to map request\n"); | 850 | dev_dbg(dwc->dev, "failed to map request\n"); |
| 841 | return; | 851 | return; |
| 842 | } | 852 | } |
| 843 | 853 | ||
| 844 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | 854 | ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma, |
| 845 | req->request.dma, req->request.length, | 855 | req->request.length, DWC3_TRBCTL_CONTROL_DATA); |
| 846 | DWC3_TRBCTL_CONTROL_DATA); | ||
| 847 | } | 856 | } |
| 848 | 857 | ||
| 849 | WARN_ON(ret < 0); | 858 | WARN_ON(ret < 0); |
| 850 | } | 859 | } |
| 851 | 860 | ||
| 861 | static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | ||
| 862 | const struct dwc3_event_depevt *event) | ||
| 863 | { | ||
| 864 | struct dwc3_ep *dep; | ||
| 865 | struct dwc3_request *req; | ||
| 866 | |||
| 867 | dep = dwc->eps[0]; | ||
| 868 | |||
| 869 | if (list_empty(&dep->request_list)) { | ||
| 870 | dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n"); | ||
| 871 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
| 872 | |||
| 873 | if (event->endpoint_number) | ||
| 874 | dep->flags |= DWC3_EP0_DIR_IN; | ||
| 875 | return; | ||
| 876 | } | ||
| 877 | |||
| 878 | req = next_request(&dep->request_list); | ||
| 879 | dep = dwc->eps[event->endpoint_number]; | ||
| 880 | |||
| 881 | __dwc3_ep0_do_control_data(dwc, dep, req); | ||
| 882 | } | ||
| 883 | |||
| 852 | static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) | 884 | static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) |
| 853 | { | 885 | { |
| 854 | struct dwc3 *dwc = dep->dwc; | 886 | struct dwc3 *dwc = dep->dwc; |
| @@ -861,10 +893,8 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) | |||
| 861 | dwc->ctrl_req_addr, 0, type); | 893 | dwc->ctrl_req_addr, 0, type); |
| 862 | } | 894 | } |
| 863 | 895 | ||
| 864 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) | 896 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) |
| 865 | { | 897 | { |
| 866 | struct dwc3_ep *dep = dwc->eps[epnum]; | ||
| 867 | |||
| 868 | if (dwc->resize_fifos) { | 898 | if (dwc->resize_fifos) { |
| 869 | dev_dbg(dwc->dev, "starting to resize fifos\n"); | 899 | dev_dbg(dwc->dev, "starting to resize fifos\n"); |
| 870 | dwc3_gadget_resize_tx_fifos(dwc); | 900 | dwc3_gadget_resize_tx_fifos(dwc); |
| @@ -874,13 +904,21 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) | |||
| 874 | WARN_ON(dwc3_ep0_start_control_status(dep)); | 904 | WARN_ON(dwc3_ep0_start_control_status(dep)); |
| 875 | } | 905 | } |
| 876 | 906 | ||
| 907 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, | ||
| 908 | const struct dwc3_event_depevt *event) | ||
| 909 | { | ||
| 910 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; | ||
| 911 | |||
| 912 | __dwc3_ep0_do_control_status(dwc, dep); | ||
| 913 | } | ||
| 914 | |||
| 877 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, | 915 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, |
| 878 | const struct dwc3_event_depevt *event) | 916 | const struct dwc3_event_depevt *event) |
| 879 | { | 917 | { |
| 880 | dwc->setup_packet_pending = true; | 918 | dwc->setup_packet_pending = true; |
| 881 | 919 | ||
| 882 | /* | 920 | /* |
| 883 | * This part is very tricky: If we has just handled | 921 | * This part is very tricky: If we have just handled |
| 884 | * XferNotReady(Setup) and we're now expecting a | 922 | * XferNotReady(Setup) and we're now expecting a |
| 885 | * XferComplete but, instead, we receive another | 923 | * XferComplete but, instead, we receive another |
| 886 | * XferNotReady(Setup), we should STALL and restart | 924 | * XferNotReady(Setup), we should STALL and restart |
| @@ -974,7 +1012,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, | |||
| 974 | return; | 1012 | return; |
| 975 | } | 1013 | } |
| 976 | 1014 | ||
| 977 | dwc3_ep0_do_control_status(dwc, event->endpoint_number); | 1015 | dwc3_ep0_do_control_status(dwc, event); |
| 978 | } | 1016 | } |
| 979 | } | 1017 | } |
| 980 | 1018 | ||
