diff options
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 363 |
1 files changed, 159 insertions, 204 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index f1e0a5eb0544..82a40a1b6b65 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -62,24 +62,12 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) | |||
62 | switch (state) { | 62 | switch (state) { |
63 | case EP0_UNCONNECTED: | 63 | case EP0_UNCONNECTED: |
64 | return "Unconnected"; | 64 | return "Unconnected"; |
65 | case EP0_IDLE: | 65 | case EP0_SETUP_PHASE: |
66 | return "Idle"; | 66 | return "Setup Phase"; |
67 | case EP0_IN_DATA_PHASE: | 67 | case EP0_DATA_PHASE: |
68 | return "IN Data Phase"; | 68 | return "Data Phase"; |
69 | case EP0_OUT_DATA_PHASE: | 69 | case EP0_STATUS_PHASE: |
70 | return "OUT Data Phase"; | 70 | return "Status Phase"; |
71 | case EP0_IN_WAIT_GADGET: | ||
72 | return "IN Wait Gadget"; | ||
73 | case EP0_OUT_WAIT_GADGET: | ||
74 | return "OUT Wait Gadget"; | ||
75 | case EP0_IN_WAIT_NRDY: | ||
76 | return "IN Wait NRDY"; | ||
77 | case EP0_OUT_WAIT_NRDY: | ||
78 | return "OUT Wait NRDY"; | ||
79 | case EP0_IN_STATUS_PHASE: | ||
80 | return "IN Status Phase"; | ||
81 | case EP0_OUT_STATUS_PHASE: | ||
82 | return "OUT Status Phase"; | ||
83 | case EP0_STALL: | 71 | case EP0_STALL: |
84 | return "Stall"; | 72 | return "Stall"; |
85 | default: | 73 | default: |
@@ -88,7 +76,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) | |||
88 | } | 76 | } |
89 | 77 | ||
90 | static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | 78 | static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, |
91 | u32 len) | 79 | u32 len, u32 type) |
92 | { | 80 | { |
93 | struct dwc3_gadget_ep_cmd_params params; | 81 | struct dwc3_gadget_ep_cmd_params params; |
94 | struct dwc3_trb_hw *trb_hw; | 82 | struct dwc3_trb_hw *trb_hw; |
@@ -98,52 +86,15 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
98 | int ret; | 86 | int ret; |
99 | 87 | ||
100 | dep = dwc->eps[epnum]; | 88 | dep = dwc->eps[epnum]; |
89 | if (dep->flags & DWC3_EP_BUSY) { | ||
90 | dev_vdbg(dwc->dev, "%s: still busy\n", dep->name); | ||
91 | return 0; | ||
92 | } | ||
101 | 93 | ||
102 | trb_hw = dwc->ep0_trb; | 94 | trb_hw = dwc->ep0_trb; |
103 | memset(&trb, 0, sizeof(trb)); | 95 | memset(&trb, 0, sizeof(trb)); |
104 | 96 | ||
105 | switch (dwc->ep0state) { | 97 | trb.trbctl = type; |
106 | case EP0_IDLE: | ||
107 | trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; | ||
108 | break; | ||
109 | |||
110 | case EP0_IN_WAIT_NRDY: | ||
111 | case EP0_OUT_WAIT_NRDY: | ||
112 | case EP0_IN_STATUS_PHASE: | ||
113 | case EP0_OUT_STATUS_PHASE: | ||
114 | if (dwc->three_stage_setup) | ||
115 | trb.trbctl = DWC3_TRBCTL_CONTROL_STATUS3; | ||
116 | else | ||
117 | trb.trbctl = DWC3_TRBCTL_CONTROL_STATUS2; | ||
118 | |||
119 | if (dwc->ep0state == EP0_IN_WAIT_NRDY) | ||
120 | dwc->ep0state = EP0_IN_STATUS_PHASE; | ||
121 | else if (dwc->ep0state == EP0_OUT_WAIT_NRDY) | ||
122 | dwc->ep0state = EP0_OUT_STATUS_PHASE; | ||
123 | break; | ||
124 | |||
125 | case EP0_IN_WAIT_GADGET: | ||
126 | dwc->ep0state = EP0_IN_WAIT_NRDY; | ||
127 | return 0; | ||
128 | break; | ||
129 | |||
130 | case EP0_OUT_WAIT_GADGET: | ||
131 | dwc->ep0state = EP0_OUT_WAIT_NRDY; | ||
132 | return 0; | ||
133 | |||
134 | break; | ||
135 | |||
136 | case EP0_IN_DATA_PHASE: | ||
137 | case EP0_OUT_DATA_PHASE: | ||
138 | trb.trbctl = DWC3_TRBCTL_CONTROL_DATA; | ||
139 | break; | ||
140 | |||
141 | default: | ||
142 | dev_err(dwc->dev, "%s() can't in state %d\n", __func__, | ||
143 | dwc->ep0state); | ||
144 | return -EINVAL; | ||
145 | } | ||
146 | |||
147 | trb.bplh = buf_dma; | 98 | trb.bplh = buf_dma; |
148 | trb.length = len; | 99 | trb.length = len; |
149 | 100 | ||
@@ -167,6 +118,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
167 | return ret; | 118 | return ret; |
168 | } | 119 | } |
169 | 120 | ||
121 | dep->flags |= DWC3_EP_BUSY; | ||
170 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, | 122 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, |
171 | dep->number); | 123 | dep->number); |
172 | 124 | ||
@@ -176,41 +128,46 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
176 | static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, | 128 | static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, |
177 | struct dwc3_request *req) | 129 | struct dwc3_request *req) |
178 | { | 130 | { |
179 | struct dwc3 *dwc = dep->dwc; | 131 | int ret = 0; |
180 | int ret; | ||
181 | 132 | ||
182 | req->request.actual = 0; | 133 | req->request.actual = 0; |
183 | req->request.status = -EINPROGRESS; | 134 | req->request.status = -EINPROGRESS; |
184 | req->direction = dep->direction; | ||
185 | req->epnum = dep->number; | 135 | req->epnum = dep->number; |
186 | 136 | ||
187 | list_add_tail(&req->list, &dep->request_list); | 137 | list_add_tail(&req->list, &dep->request_list); |
188 | if (req->request.length == 0) { | ||
189 | ret = dwc3_ep0_start_trans(dwc, dep->number, | ||
190 | dwc->ctrl_req_addr, 0); | ||
191 | } else if ((req->request.length % dep->endpoint.maxpacket) | ||
192 | && (dep->number == 0)) { | ||
193 | dwc->ep0_bounced = true; | ||
194 | |||
195 | WARN_ON(req->request.length > dep->endpoint.maxpacket); | ||
196 | 138 | ||
197 | /* | 139 | /* |
198 | * REVISIT in case request length is bigger than EP0 | 140 | * Gadget driver might not be quick enough to queue a request |
199 | * wMaxPacketSize, we will need two chained TRBs to handle | 141 | * before we get a Transfer Not Ready event on this endpoint. |
200 | * the transfer. | 142 | * |
201 | */ | 143 | * In that case, we will set DWC3_EP_PENDING_REQUEST. When that |
202 | ret = dwc3_ep0_start_trans(dwc, dep->number, | 144 | * flag is set, it's telling us that as soon as Gadget queues the |
203 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket); | 145 | * required request, we should kick the transfer here because the |
204 | } else { | 146 | * IRQ we were waiting for is long gone. |
205 | dwc3_map_buffer_to_dma(req); | 147 | */ |
206 | 148 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | |
207 | ret = dwc3_ep0_start_trans(dwc, dep->number, | 149 | struct dwc3 *dwc = dep->dwc; |
208 | req->request.dma, req->request.length); | 150 | unsigned direction; |
209 | } | 151 | u32 type; |
152 | |||
153 | direction = !!(dep->flags & DWC3_EP0_DIR_IN); | ||
154 | |||
155 | if (dwc->ep0state == EP0_STATUS_PHASE) { | ||
156 | type = dwc->three_stage_setup | ||
157 | ? DWC3_TRBCTL_CONTROL_STATUS3 | ||
158 | : DWC3_TRBCTL_CONTROL_STATUS2; | ||
159 | } else if (dwc->ep0state == EP0_DATA_PHASE) { | ||
160 | type = DWC3_TRBCTL_CONTROL_DATA; | ||
161 | } else { | ||
162 | /* should never happen */ | ||
163 | WARN_ON(1); | ||
164 | return 0; | ||
165 | } | ||
210 | 166 | ||
211 | if (ret < 0) { | 167 | ret = dwc3_ep0_start_trans(dwc, direction, |
212 | list_del(&req->list); | 168 | req->request.dma, req->request.length, type); |
213 | dwc3_unmap_buffer_from_dma(req); | 169 | dep->flags &= ~(DWC3_EP_PENDING_REQUEST | |
170 | DWC3_EP0_DIR_IN); | ||
214 | } | 171 | } |
215 | 172 | ||
216 | return ret; | 173 | return ret; |
@@ -227,24 +184,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | |||
227 | 184 | ||
228 | int ret; | 185 | int ret; |
229 | 186 | ||
230 | switch (dwc->ep0state) { | ||
231 | case EP0_IN_DATA_PHASE: | ||
232 | case EP0_IN_WAIT_GADGET: | ||
233 | case EP0_IN_WAIT_NRDY: | ||
234 | case EP0_IN_STATUS_PHASE: | ||
235 | dep = dwc->eps[1]; | ||
236 | break; | ||
237 | |||
238 | case EP0_OUT_DATA_PHASE: | ||
239 | case EP0_OUT_WAIT_GADGET: | ||
240 | case EP0_OUT_WAIT_NRDY: | ||
241 | case EP0_OUT_STATUS_PHASE: | ||
242 | dep = dwc->eps[0]; | ||
243 | break; | ||
244 | default: | ||
245 | return -EINVAL; | ||
246 | } | ||
247 | |||
248 | spin_lock_irqsave(&dwc->lock, flags); | 187 | spin_lock_irqsave(&dwc->lock, flags); |
249 | if (!dep->desc) { | 188 | if (!dep->desc) { |
250 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", | 189 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", |
@@ -278,50 +217,19 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) | |||
278 | /* stall is always issued on EP0 */ | 217 | /* stall is always issued on EP0 */ |
279 | __dwc3_gadget_ep_set_halt(dwc->eps[0], 1); | 218 | __dwc3_gadget_ep_set_halt(dwc->eps[0], 1); |
280 | dwc->eps[0]->flags &= ~DWC3_EP_STALL; | 219 | dwc->eps[0]->flags &= ~DWC3_EP_STALL; |
281 | dwc->ep0state = EP0_IDLE; | 220 | dwc->ep0state = EP0_SETUP_PHASE; |
282 | dwc3_ep0_out_start(dwc); | 221 | dwc3_ep0_out_start(dwc); |
283 | } | 222 | } |
284 | 223 | ||
285 | void dwc3_ep0_out_start(struct dwc3 *dwc) | 224 | void dwc3_ep0_out_start(struct dwc3 *dwc) |
286 | { | 225 | { |
287 | struct dwc3_ep *dep; | ||
288 | int ret; | 226 | int ret; |
289 | 227 | ||
290 | dep = dwc->eps[0]; | 228 | ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, |
291 | 229 | DWC3_TRBCTL_CONTROL_SETUP); | |
292 | ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8); | ||
293 | WARN_ON(ret < 0); | 230 | WARN_ON(ret < 0); |
294 | } | 231 | } |
295 | 232 | ||
296 | /* | ||
297 | * Send a zero length packet for the status phase of the control transfer | ||
298 | */ | ||
299 | static void dwc3_ep0_do_setup_status(struct dwc3 *dwc, | ||
300 | const struct dwc3_event_depevt *event) | ||
301 | { | ||
302 | struct dwc3_ep *dep; | ||
303 | int ret; | ||
304 | u32 epnum; | ||
305 | |||
306 | epnum = event->endpoint_number; | ||
307 | dep = dwc->eps[epnum]; | ||
308 | |||
309 | if (epnum) | ||
310 | dwc->ep0state = EP0_IN_STATUS_PHASE; | ||
311 | else | ||
312 | dwc->ep0state = EP0_OUT_STATUS_PHASE; | ||
313 | |||
314 | /* | ||
315 | * Not sure Why I need a buffer for a zero transfer. Maybe the | ||
316 | * HW reacts strange on a NULL pointer | ||
317 | */ | ||
318 | ret = dwc3_ep0_start_trans(dwc, epnum, dwc->ctrl_req_addr, 0); | ||
319 | if (ret) { | ||
320 | dev_dbg(dwc->dev, "failed to start transfer, stalling\n"); | ||
321 | dwc3_ep0_stall_and_restart(dwc); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) | 233 | static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) |
326 | { | 234 | { |
327 | struct dwc3_ep *dep; | 235 | struct dwc3_ep *dep; |
@@ -341,15 +249,9 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) | |||
341 | 249 | ||
342 | static void dwc3_ep0_send_status_response(struct dwc3 *dwc) | 250 | static void dwc3_ep0_send_status_response(struct dwc3 *dwc) |
343 | { | 251 | { |
344 | u32 epnum; | 252 | dwc3_ep0_start_trans(dwc, 1, dwc->ctrl_req_addr, |
345 | 253 | dwc->ep0_usb_req.length, | |
346 | if (dwc->ep0state == EP0_IN_DATA_PHASE) | 254 | DWC3_TRBCTL_CONTROL_DATA); |
347 | epnum = 1; | ||
348 | else | ||
349 | epnum = 0; | ||
350 | |||
351 | dwc3_ep0_start_trans(dwc, epnum, dwc->ctrl_req_addr, | ||
352 | dwc->ep0_usb_req.length); | ||
353 | dwc->ep0_status_pending = 1; | 255 | dwc->ep0_status_pending = 1; |
354 | } | 256 | } |
355 | 257 | ||
@@ -505,8 +407,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, | |||
505 | return -EINVAL; | 407 | return -EINVAL; |
506 | }; | 408 | }; |
507 | 409 | ||
508 | dwc->ep0state = EP0_IN_WAIT_NRDY; | ||
509 | |||
510 | return 0; | 410 | return 0; |
511 | } | 411 | } |
512 | 412 | ||
@@ -541,7 +441,7 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |||
541 | ret = -EINVAL; | 441 | ret = -EINVAL; |
542 | break; | 442 | break; |
543 | } | 443 | } |
544 | dwc->ep0state = EP0_IN_WAIT_NRDY; | 444 | |
545 | return ret; | 445 | return ret; |
546 | } | 446 | } |
547 | 447 | ||
@@ -628,16 +528,10 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, | |||
628 | goto err; | 528 | goto err; |
629 | 529 | ||
630 | len = le16_to_cpu(ctrl->wLength); | 530 | len = le16_to_cpu(ctrl->wLength); |
631 | if (!len) { | 531 | if (!len) |
632 | dwc->ep0state = EP0_IN_WAIT_GADGET; | ||
633 | dwc->three_stage_setup = 0; | 532 | dwc->three_stage_setup = 0; |
634 | } else { | 533 | else |
635 | dwc->three_stage_setup = 1; | 534 | dwc->three_stage_setup = 1; |
636 | if (ctrl->bRequestType & USB_DIR_IN) | ||
637 | dwc->ep0state = EP0_IN_DATA_PHASE; | ||
638 | else | ||
639 | dwc->ep0state = EP0_OUT_DATA_PHASE; | ||
640 | } | ||
641 | 535 | ||
642 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) | 536 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) |
643 | ret = dwc3_ep0_std_request(dwc, ctrl); | 537 | ret = dwc3_ep0_std_request(dwc, ctrl); |
@@ -665,7 +559,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
665 | dep = dwc->eps[epnum]; | 559 | dep = dwc->eps[epnum]; |
666 | 560 | ||
667 | if (!dwc->ep0_status_pending) { | 561 | if (!dwc->ep0_status_pending) { |
668 | r = next_request(&dep->request_list); | 562 | r = next_request(&dwc->eps[0]->request_list); |
669 | ur = &r->request; | 563 | ur = &r->request; |
670 | } else { | 564 | } else { |
671 | ur = &dwc->ep0_usb_req; | 565 | ur = &dwc->ep0_usb_req; |
@@ -677,7 +571,8 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
677 | if (dwc->ep0_bounced) { | 571 | if (dwc->ep0_bounced) { |
678 | struct dwc3_ep *ep0 = dwc->eps[0]; | 572 | struct dwc3_ep *ep0 = dwc->eps[0]; |
679 | 573 | ||
680 | transferred = min(ur->length, dep->endpoint.maxpacket - trb.length); | 574 | transferred = min_t(u32, ur->length, |
575 | ep0->endpoint.maxpacket - trb.length); | ||
681 | memcpy(ur->buf, dwc->ep0_bounce, transferred); | 576 | memcpy(ur->buf, dwc->ep0_bounce, transferred); |
682 | dwc->ep0_bounced = false; | 577 | dwc->ep0_bounced = false; |
683 | } else { | 578 | } else { |
@@ -695,12 +590,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
695 | * handle the case where we have to send a zero packet. This | 590 | * handle the case where we have to send a zero packet. This |
696 | * seems to be case when req.length > maxpacket. Could it be? | 591 | * seems to be case when req.length > maxpacket. Could it be? |
697 | */ | 592 | */ |
698 | /* The transfer is complete, wait for HOST */ | ||
699 | if (epnum & 1) | ||
700 | dwc->ep0state = EP0_IN_WAIT_NRDY; | ||
701 | else | ||
702 | dwc->ep0state = EP0_OUT_WAIT_NRDY; | ||
703 | |||
704 | if (r) | 593 | if (r) |
705 | dwc3_gadget_giveback(dep, r, 0); | 594 | dwc3_gadget_giveback(dep, r, 0); |
706 | } | 595 | } |
@@ -711,10 +600,8 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc, | |||
711 | { | 600 | { |
712 | struct dwc3_request *r; | 601 | struct dwc3_request *r; |
713 | struct dwc3_ep *dep; | 602 | struct dwc3_ep *dep; |
714 | u8 epnum; | ||
715 | 603 | ||
716 | epnum = event->endpoint_number; | 604 | dep = dwc->eps[0]; |
717 | dep = dwc->eps[epnum]; | ||
718 | 605 | ||
719 | if (!list_empty(&dep->request_list)) { | 606 | if (!list_empty(&dep->request_list)) { |
720 | r = next_request(&dep->request_list); | 607 | r = next_request(&dep->request_list); |
@@ -722,62 +609,130 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc, | |||
722 | dwc3_gadget_giveback(dep, r, 0); | 609 | dwc3_gadget_giveback(dep, r, 0); |
723 | } | 610 | } |
724 | 611 | ||
725 | dwc->ep0state = EP0_IDLE; | 612 | dwc->ep0state = EP0_SETUP_PHASE; |
726 | dwc3_ep0_out_start(dwc); | 613 | dwc3_ep0_out_start(dwc); |
727 | } | 614 | } |
728 | 615 | ||
729 | static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, | 616 | static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, |
730 | const struct dwc3_event_depevt *event) | 617 | const struct dwc3_event_depevt *event) |
731 | { | 618 | { |
619 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; | ||
620 | |||
621 | dep->flags &= ~DWC3_EP_BUSY; | ||
622 | |||
732 | switch (dwc->ep0state) { | 623 | switch (dwc->ep0state) { |
733 | case EP0_IDLE: | 624 | case EP0_SETUP_PHASE: |
625 | dev_vdbg(dwc->dev, "Inspecting Setup Bytes\n"); | ||
734 | dwc3_ep0_inspect_setup(dwc, event); | 626 | dwc3_ep0_inspect_setup(dwc, event); |
735 | break; | 627 | break; |
736 | 628 | ||
737 | case EP0_IN_DATA_PHASE: | 629 | case EP0_DATA_PHASE: |
738 | case EP0_OUT_DATA_PHASE: | 630 | dev_vdbg(dwc->dev, "Data Phase\n"); |
739 | dwc3_ep0_complete_data(dwc, event); | 631 | dwc3_ep0_complete_data(dwc, event); |
740 | break; | 632 | break; |
741 | 633 | ||
742 | case EP0_IN_STATUS_PHASE: | 634 | case EP0_STATUS_PHASE: |
743 | case EP0_OUT_STATUS_PHASE: | 635 | dev_vdbg(dwc->dev, "Status Phase\n"); |
744 | dwc3_ep0_complete_req(dwc, event); | 636 | dwc3_ep0_complete_req(dwc, event); |
745 | break; | 637 | break; |
638 | default: | ||
639 | WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state); | ||
640 | } | ||
641 | } | ||
746 | 642 | ||
747 | case EP0_IN_WAIT_NRDY: | 643 | static void dwc3_ep0_do_control_setup(struct dwc3 *dwc, |
748 | case EP0_OUT_WAIT_NRDY: | 644 | const struct dwc3_event_depevt *event) |
749 | case EP0_IN_WAIT_GADGET: | 645 | { |
750 | case EP0_OUT_WAIT_GADGET: | 646 | dwc->ep0state = EP0_SETUP_PHASE; |
751 | case EP0_UNCONNECTED: | 647 | dwc3_ep0_out_start(dwc); |
752 | case EP0_STALL: | 648 | } |
753 | break; | 649 | |
650 | static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | ||
651 | const struct dwc3_event_depevt *event) | ||
652 | { | ||
653 | struct dwc3_ep *dep; | ||
654 | struct dwc3_request *req; | ||
655 | int ret; | ||
656 | |||
657 | dep = dwc->eps[0]; | ||
658 | dwc->ep0state = EP0_DATA_PHASE; | ||
659 | |||
660 | if (list_empty(&dep->request_list)) { | ||
661 | dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n"); | ||
662 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
663 | |||
664 | if (event->endpoint_number) | ||
665 | dep->flags |= DWC3_EP0_DIR_IN; | ||
666 | return; | ||
754 | } | 667 | } |
668 | |||
669 | req = next_request(&dep->request_list); | ||
670 | req->direction = !!event->endpoint_number; | ||
671 | |||
672 | dwc->ep0state = EP0_DATA_PHASE; | ||
673 | if (req->request.length == 0) { | ||
674 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
675 | dwc->ctrl_req_addr, 0, | ||
676 | DWC3_TRBCTL_CONTROL_DATA); | ||
677 | } else if ((req->request.length % dep->endpoint.maxpacket) | ||
678 | && (event->endpoint_number == 0)) { | ||
679 | dwc3_map_buffer_to_dma(req); | ||
680 | |||
681 | WARN_ON(req->request.length > dep->endpoint.maxpacket); | ||
682 | |||
683 | dwc->ep0_bounced = true; | ||
684 | |||
685 | /* | ||
686 | * REVISIT in case request length is bigger than EP0 | ||
687 | * wMaxPacketSize, we will need two chained TRBs to handle | ||
688 | * the transfer. | ||
689 | */ | ||
690 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
691 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, | ||
692 | DWC3_TRBCTL_CONTROL_DATA); | ||
693 | } else { | ||
694 | dwc3_map_buffer_to_dma(req); | ||
695 | |||
696 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | ||
697 | req->request.dma, req->request.length, | ||
698 | DWC3_TRBCTL_CONTROL_DATA); | ||
699 | } | ||
700 | |||
701 | WARN_ON(ret < 0); | ||
755 | } | 702 | } |
756 | 703 | ||
757 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, | 704 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, |
758 | const struct dwc3_event_depevt *event) | 705 | const struct dwc3_event_depevt *event) |
759 | { | 706 | { |
760 | switch (dwc->ep0state) { | 707 | u32 type; |
761 | case EP0_IN_WAIT_GADGET: | 708 | int ret; |
762 | dwc->ep0state = EP0_IN_WAIT_NRDY; | ||
763 | break; | ||
764 | case EP0_OUT_WAIT_GADGET: | ||
765 | dwc->ep0state = EP0_OUT_WAIT_NRDY; | ||
766 | break; | ||
767 | 709 | ||
768 | case EP0_IN_WAIT_NRDY: | 710 | dwc->ep0state = EP0_STATUS_PHASE; |
769 | case EP0_OUT_WAIT_NRDY: | ||
770 | dwc3_ep0_do_setup_status(dwc, event); | ||
771 | break; | ||
772 | 711 | ||
773 | case EP0_IDLE: | 712 | type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 |
774 | case EP0_IN_STATUS_PHASE: | 713 | : DWC3_TRBCTL_CONTROL_STATUS2; |
775 | case EP0_OUT_STATUS_PHASE: | 714 | |
776 | case EP0_IN_DATA_PHASE: | 715 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, |
777 | case EP0_OUT_DATA_PHASE: | 716 | dwc->ctrl_req_addr, 0, type); |
778 | case EP0_UNCONNECTED: | 717 | |
779 | case EP0_STALL: | 718 | WARN_ON(ret < 0); |
780 | break; | 719 | } |
720 | |||
721 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, | ||
722 | const struct dwc3_event_depevt *event) | ||
723 | { | ||
724 | switch (event->status) { | ||
725 | case DEPEVT_STATUS_CONTROL_SETUP: | ||
726 | dev_vdbg(dwc->dev, "Control Setup\n"); | ||
727 | dwc3_ep0_do_control_setup(dwc, event); | ||
728 | break; | ||
729 | case DEPEVT_STATUS_CONTROL_DATA: | ||
730 | dev_vdbg(dwc->dev, "Control Data\n"); | ||
731 | dwc3_ep0_do_control_data(dwc, event); | ||
732 | break; | ||
733 | case DEPEVT_STATUS_CONTROL_STATUS: | ||
734 | dev_vdbg(dwc->dev, "Control Status\n"); | ||
735 | dwc3_ep0_do_control_status(dwc, event); | ||
781 | } | 736 | } |
782 | } | 737 | } |
783 | 738 | ||