aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/ep0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
-rw-r--r--drivers/usb/dwc3/ep0.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 4878d187c7d4..9bb1f8526f3e 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -39,18 +39,13 @@ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
39static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, 39static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
40 struct dwc3_ep *dep, struct dwc3_request *req); 40 struct dwc3_ep *dep, struct dwc3_request *req);
41 41
42static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, 42static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum,
43 u32 len, u32 type, bool chain) 43 dma_addr_t buf_dma, u32 len, u32 type, bool chain)
44{ 44{
45 struct dwc3_gadget_ep_cmd_params params;
46 struct dwc3_trb *trb; 45 struct dwc3_trb *trb;
47 struct dwc3_ep *dep; 46 struct dwc3_ep *dep;
48 47
49 int ret;
50
51 dep = dwc->eps[epnum]; 48 dep = dwc->eps[epnum];
52 if (dep->flags & DWC3_EP_BUSY)
53 return 0;
54 49
55 trb = &dwc->ep0_trb[dep->trb_enqueue]; 50 trb = &dwc->ep0_trb[dep->trb_enqueue];
56 51
@@ -71,15 +66,23 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
71 trb->ctrl |= (DWC3_TRB_CTRL_IOC 66 trb->ctrl |= (DWC3_TRB_CTRL_IOC
72 | DWC3_TRB_CTRL_LST); 67 | DWC3_TRB_CTRL_LST);
73 68
74 if (chain) 69 trace_dwc3_prepare_trb(dep, trb);
70}
71
72static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum)
73{
74 struct dwc3_gadget_ep_cmd_params params;
75 struct dwc3_ep *dep;
76 int ret;
77
78 dep = dwc->eps[epnum];
79 if (dep->flags & DWC3_EP_BUSY)
75 return 0; 80 return 0;
76 81
77 memset(&params, 0, sizeof(params)); 82 memset(&params, 0, sizeof(params));
78 params.param0 = upper_32_bits(dwc->ep0_trb_addr); 83 params.param0 = upper_32_bits(dwc->ep0_trb_addr);
79 params.param1 = lower_32_bits(dwc->ep0_trb_addr); 84 params.param1 = lower_32_bits(dwc->ep0_trb_addr);
80 85
81 trace_dwc3_prepare_trb(dep, trb);
82
83 ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, &params); 86 ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, &params);
84 if (ret < 0) 87 if (ret < 0)
85 return ret; 88 return ret;
@@ -280,8 +283,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
280 283
281 complete(&dwc->ep0_in_setup); 284 complete(&dwc->ep0_in_setup);
282 285
283 ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, 286 dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8,
284 DWC3_TRBCTL_CONTROL_SETUP, false); 287 DWC3_TRBCTL_CONTROL_SETUP, false);
288 ret = dwc3_ep0_start_trans(dwc, 0);
285 WARN_ON(ret < 0); 289 WARN_ON(ret < 0);
286} 290}
287 291
@@ -912,9 +916,9 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
912 916
913 dwc->ep0_next_event = DWC3_EP0_COMPLETE; 917 dwc->ep0_next_event = DWC3_EP0_COMPLETE;
914 918
915 ret = dwc3_ep0_start_trans(dwc, epnum, 919 dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ctrl_req_addr,
916 dwc->ctrl_req_addr, 0, 920 0, DWC3_TRBCTL_CONTROL_DATA, false);
917 DWC3_TRBCTL_CONTROL_DATA, false); 921 ret = dwc3_ep0_start_trans(dwc, epnum);
918 WARN_ON(ret < 0); 922 WARN_ON(ret < 0);
919 } 923 }
920 } 924 }
@@ -993,9 +997,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
993 req->direction = !!dep->number; 997 req->direction = !!dep->number;
994 998
995 if (req->request.length == 0) { 999 if (req->request.length == 0) {
996 ret = dwc3_ep0_start_trans(dwc, dep->number, 1000 dwc3_ep0_prepare_one_trb(dwc, dep->number,
997 dwc->ctrl_req_addr, 0, 1001 dwc->ctrl_req_addr, 0,
998 DWC3_TRBCTL_CONTROL_DATA, false); 1002 DWC3_TRBCTL_CONTROL_DATA, false);
1003 ret = dwc3_ep0_start_trans(dwc, dep->number);
999 } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) 1004 } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
1000 && (dep->number == 0)) { 1005 && (dep->number == 0)) {
1001 u32 transfer_size = 0; 1006 u32 transfer_size = 0;
@@ -1011,7 +1016,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
1011 if (req->request.length > DWC3_EP0_BOUNCE_SIZE) { 1016 if (req->request.length > DWC3_EP0_BOUNCE_SIZE) {
1012 transfer_size = ALIGN(req->request.length - maxpacket, 1017 transfer_size = ALIGN(req->request.length - maxpacket,
1013 maxpacket); 1018 maxpacket);
1014 ret = dwc3_ep0_start_trans(dwc, dep->number, 1019 dwc3_ep0_prepare_one_trb(dwc, dep->number,
1015 req->request.dma, 1020 req->request.dma,
1016 transfer_size, 1021 transfer_size,
1017 DWC3_TRBCTL_CONTROL_DATA, 1022 DWC3_TRBCTL_CONTROL_DATA,
@@ -1023,18 +1028,20 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
1023 1028
1024 dwc->ep0_bounced = true; 1029 dwc->ep0_bounced = true;
1025 1030
1026 ret = dwc3_ep0_start_trans(dwc, dep->number, 1031 dwc3_ep0_prepare_one_trb(dwc, dep->number,
1027 dwc->ep0_bounce_addr, transfer_size, 1032 dwc->ep0_bounce_addr, transfer_size,
1028 DWC3_TRBCTL_CONTROL_DATA, false); 1033 DWC3_TRBCTL_CONTROL_DATA, false);
1034 ret = dwc3_ep0_start_trans(dwc, dep->number);
1029 } else { 1035 } else {
1030 ret = usb_gadget_map_request_by_dev(dwc->sysdev, 1036 ret = usb_gadget_map_request_by_dev(dwc->sysdev,
1031 &req->request, dep->number); 1037 &req->request, dep->number);
1032 if (ret) 1038 if (ret)
1033 return; 1039 return;
1034 1040
1035 ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma, 1041 dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma,
1036 req->request.length, DWC3_TRBCTL_CONTROL_DATA, 1042 req->request.length, DWC3_TRBCTL_CONTROL_DATA,
1037 false); 1043 false);
1044 ret = dwc3_ep0_start_trans(dwc, dep->number);
1038 } 1045 }
1039 1046
1040 WARN_ON(ret < 0); 1047 WARN_ON(ret < 0);
@@ -1048,8 +1055,9 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
1048 type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 1055 type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3
1049 : DWC3_TRBCTL_CONTROL_STATUS2; 1056 : DWC3_TRBCTL_CONTROL_STATUS2;
1050 1057
1051 return dwc3_ep0_start_trans(dwc, dep->number, 1058 dwc3_ep0_prepare_one_trb(dwc, dep->number,
1052 dwc->ctrl_req_addr, 0, type, false); 1059 dwc->ctrl_req_addr, 0, type, false);
1060 return dwc3_ep0_start_trans(dwc, dep->number);
1053} 1061}
1054 1062
1055static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) 1063static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)