.. | .. |
---|
2 | 2 | /* |
---|
3 | 3 | * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling |
---|
4 | 4 | * |
---|
5 | | - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com |
---|
| 5 | + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com |
---|
6 | 6 | * |
---|
7 | 7 | * Authors: Felipe Balbi <balbi@ti.com>, |
---|
8 | 8 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
---|
.. | .. |
---|
105 | 105 | * IRQ we were waiting for is long gone. |
---|
106 | 106 | */ |
---|
107 | 107 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
---|
108 | | - unsigned direction; |
---|
| 108 | + unsigned int direction; |
---|
109 | 109 | |
---|
110 | 110 | direction = !!(dep->flags & DWC3_EP0_DIR_IN); |
---|
111 | 111 | |
---|
.. | .. |
---|
127 | 127 | * handle it here. |
---|
128 | 128 | */ |
---|
129 | 129 | if (dwc->delayed_status) { |
---|
130 | | - unsigned direction; |
---|
| 130 | + unsigned int direction; |
---|
131 | 131 | |
---|
132 | 132 | direction = !dwc->ep0_expect_in; |
---|
133 | 133 | dwc->delayed_status = false; |
---|
134 | | - usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED); |
---|
| 134 | + usb_gadget_set_state(dwc->gadget, USB_STATE_CONFIGURED); |
---|
135 | 135 | |
---|
136 | 136 | if (dwc->ep0state == EP0_STATUS_PHASE) |
---|
137 | 137 | __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); |
---|
.. | .. |
---|
172 | 172 | * XferNotReady(STATUS). |
---|
173 | 173 | */ |
---|
174 | 174 | if (dwc->three_stage_setup) { |
---|
175 | | - unsigned direction; |
---|
| 175 | + unsigned int direction; |
---|
176 | 176 | |
---|
177 | 177 | direction = dwc->ep0_expect_in; |
---|
178 | 178 | dwc->ep0state = EP0_DATA_PHASE; |
---|
.. | .. |
---|
197 | 197 | int ret; |
---|
198 | 198 | |
---|
199 | 199 | spin_lock_irqsave(&dwc->lock, flags); |
---|
200 | | - if (!dep->endpoint.desc) { |
---|
| 200 | + if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) { |
---|
201 | 201 | dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", |
---|
202 | 202 | dep->name); |
---|
203 | 203 | ret = -ESHUTDOWN; |
---|
.. | .. |
---|
218 | 218 | return ret; |
---|
219 | 219 | } |
---|
220 | 220 | |
---|
221 | | -static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) |
---|
| 221 | +void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) |
---|
222 | 222 | { |
---|
223 | 223 | struct dwc3_ep *dep; |
---|
224 | 224 | |
---|
.. | .. |
---|
239 | 239 | dwc3_gadget_giveback(dep, req, -ECONNRESET); |
---|
240 | 240 | } |
---|
241 | 241 | |
---|
| 242 | + dwc->eps[0]->trb_enqueue = 0; |
---|
| 243 | + dwc->eps[1]->trb_enqueue = 0; |
---|
242 | 244 | dwc->ep0state = EP0_SETUP_PHASE; |
---|
243 | 245 | dwc3_ep0_out_start(dwc); |
---|
244 | 246 | } |
---|
.. | .. |
---|
271 | 273 | { |
---|
272 | 274 | struct dwc3_ep *dep; |
---|
273 | 275 | int ret; |
---|
| 276 | + int i; |
---|
274 | 277 | |
---|
275 | 278 | complete(&dwc->ep0_in_setup); |
---|
276 | 279 | |
---|
.. | .. |
---|
279 | 282 | DWC3_TRBCTL_CONTROL_SETUP, false); |
---|
280 | 283 | ret = dwc3_ep0_start_trans(dep); |
---|
281 | 284 | WARN_ON(ret < 0); |
---|
| 285 | + for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) { |
---|
| 286 | + struct dwc3_ep *dwc3_ep; |
---|
| 287 | + |
---|
| 288 | + dwc3_ep = dwc->eps[i]; |
---|
| 289 | + if (!dwc3_ep) |
---|
| 290 | + continue; |
---|
| 291 | + |
---|
| 292 | + if (!(dwc3_ep->flags & DWC3_EP_DELAY_STOP)) |
---|
| 293 | + continue; |
---|
| 294 | + |
---|
| 295 | + dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP; |
---|
| 296 | + if (dwc->connected) |
---|
| 297 | + dwc3_stop_active_transfer(dwc3_ep, true, true); |
---|
| 298 | + else |
---|
| 299 | + dwc3_remove_requests(dwc, dwc3_ep, -ESHUTDOWN); |
---|
| 300 | + } |
---|
282 | 301 | } |
---|
283 | 302 | |
---|
284 | 303 | static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) |
---|
285 | 304 | { |
---|
286 | | - struct dwc3_ep *dep = NULL; |
---|
| 305 | + struct dwc3_ep *dep; |
---|
287 | 306 | u32 windex = le16_to_cpu(wIndex_le); |
---|
288 | | - u32 epnum, ep_index; |
---|
289 | | - u8 num, direction; |
---|
| 307 | + u32 ep, epnum; |
---|
| 308 | + u8 num_in_eps, num_out_eps, min_eps; |
---|
290 | 309 | |
---|
291 | | - epnum = windex & USB_ENDPOINT_NUMBER_MASK; |
---|
292 | | - direction = windex & USB_ENDPOINT_DIR_MASK; |
---|
293 | | - ep_index = 0; |
---|
| 310 | + num_in_eps = DWC3_NUM_IN_EPS(&dwc->hwparams); |
---|
| 311 | + num_out_eps = dwc->num_eps - num_in_eps; |
---|
| 312 | + min_eps = min_t(u8, num_in_eps, num_out_eps); |
---|
| 313 | + ep = windex & USB_ENDPOINT_NUMBER_MASK; |
---|
294 | 314 | |
---|
295 | | - for (num = 0; num < dwc->num_eps; num++) { |
---|
296 | | - dep = dwc->eps[num]; |
---|
297 | | - if (!dep) { |
---|
298 | | - dev_warn(dwc->dev, "dep is NULL, num %d, windex 0x%08x\n", |
---|
299 | | - num, windex); |
---|
300 | | - return NULL; |
---|
301 | | - } |
---|
| 315 | + if (ep + 1 > min_eps && num_in_eps != num_out_eps) { |
---|
| 316 | + epnum = ep + min_eps; |
---|
302 | 317 | |
---|
303 | | - if ((direction == USB_DIR_IN && dep->direction) || |
---|
304 | | - (direction == USB_DIR_OUT && !dep->direction)) |
---|
305 | | - ep_index++; |
---|
306 | | - |
---|
307 | | - if (ep_index == epnum + 1) |
---|
308 | | - break; |
---|
| 318 | + } else { |
---|
| 319 | + epnum = ep << 1; |
---|
| 320 | + if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) |
---|
| 321 | + epnum |= 1; |
---|
309 | 322 | } |
---|
310 | 323 | |
---|
| 324 | + dep = dwc->eps[epnum]; |
---|
| 325 | + if (dep == NULL) |
---|
| 326 | + return NULL; |
---|
311 | 327 | |
---|
312 | | - if (dep && (dep->flags & DWC3_EP_ENABLED)) |
---|
| 328 | + if (dep->flags & DWC3_EP_ENABLED) |
---|
313 | 329 | return dep; |
---|
314 | 330 | |
---|
315 | 331 | return NULL; |
---|
.. | .. |
---|
342 | 358 | /* |
---|
343 | 359 | * LTM will be set once we know how to set this in HW. |
---|
344 | 360 | */ |
---|
345 | | - usb_status |= dwc->gadget.is_selfpowered; |
---|
| 361 | + usb_status |= dwc->gadget->is_selfpowered; |
---|
346 | 362 | |
---|
347 | 363 | if ((dwc->speed == DWC3_DSTS_SUPERSPEED) || |
---|
348 | 364 | (dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) { |
---|
.. | .. |
---|
396 | 412 | if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && |
---|
397 | 413 | (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) |
---|
398 | 414 | return -EINVAL; |
---|
| 415 | + if (set && dwc->dis_u1_entry_quirk) |
---|
| 416 | + return -EINVAL; |
---|
399 | 417 | |
---|
400 | 418 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
---|
401 | | - if (set && !dwc->dis_u1u2_quirk) |
---|
| 419 | + if (set) |
---|
402 | 420 | reg |= DWC3_DCTL_INITU1ENA; |
---|
403 | 421 | else |
---|
404 | 422 | reg &= ~DWC3_DCTL_INITU1ENA; |
---|
.. | .. |
---|
418 | 436 | if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && |
---|
419 | 437 | (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) |
---|
420 | 438 | return -EINVAL; |
---|
| 439 | + if (set && dwc->dis_u2_entry_quirk) |
---|
| 440 | + return -EINVAL; |
---|
421 | 441 | |
---|
422 | 442 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
---|
423 | | - if (set && !dwc->dis_u1u2_quirk) |
---|
| 443 | + if (set) |
---|
424 | 444 | reg |= DWC3_DCTL_INITU2ENA; |
---|
425 | 445 | else |
---|
426 | 446 | reg &= ~DWC3_DCTL_INITU2ENA; |
---|
.. | .. |
---|
438 | 458 | return -EINVAL; |
---|
439 | 459 | |
---|
440 | 460 | switch (wIndex >> 8) { |
---|
441 | | - case TEST_J: |
---|
442 | | - case TEST_K: |
---|
443 | | - case TEST_SE0_NAK: |
---|
444 | | - case TEST_PACKET: |
---|
445 | | - case TEST_FORCE_EN: |
---|
| 461 | + case USB_TEST_J: |
---|
| 462 | + case USB_TEST_K: |
---|
| 463 | + case USB_TEST_SE0_NAK: |
---|
| 464 | + case USB_TEST_PACKET: |
---|
| 465 | + case USB_TEST_FORCE_ENABLE: |
---|
446 | 466 | dwc->test_mode_nr = wIndex >> 8; |
---|
447 | 467 | dwc->test_mode = true; |
---|
448 | 468 | break; |
---|
.. | .. |
---|
463 | 483 | |
---|
464 | 484 | wValue = le16_to_cpu(ctrl->wValue); |
---|
465 | 485 | wIndex = le16_to_cpu(ctrl->wIndex); |
---|
466 | | - state = dwc->gadget.state; |
---|
| 486 | + state = dwc->gadget->state; |
---|
467 | 487 | |
---|
468 | 488 | switch (wValue) { |
---|
469 | 489 | case USB_DEVICE_REMOTE_WAKEUP: |
---|
470 | 490 | break; |
---|
471 | 491 | /* |
---|
472 | | - * 9.4.1 says only only for SS, in AddressState only for |
---|
| 492 | + * 9.4.1 says only for SS, in AddressState only for |
---|
473 | 493 | * default control pipe |
---|
474 | 494 | */ |
---|
475 | 495 | case USB_DEVICE_U1_ENABLE: |
---|
.. | .. |
---|
537 | 557 | ret = __dwc3_gadget_ep_set_halt(dep, set, true); |
---|
538 | 558 | if (ret) |
---|
539 | 559 | return -EINVAL; |
---|
| 560 | + |
---|
| 561 | + /* ClearFeature(Halt) may need delayed status */ |
---|
| 562 | + if (!set && (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) |
---|
| 563 | + return USB_GADGET_DELAYED_STATUS; |
---|
| 564 | + |
---|
540 | 565 | break; |
---|
541 | 566 | default: |
---|
542 | 567 | return -EINVAL; |
---|
.. | .. |
---|
572 | 597 | |
---|
573 | 598 | static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
---|
574 | 599 | { |
---|
575 | | - enum usb_device_state state = dwc->gadget.state; |
---|
| 600 | + enum usb_device_state state = dwc->gadget->state; |
---|
576 | 601 | u32 addr; |
---|
577 | 602 | u32 reg; |
---|
578 | 603 | |
---|
.. | .. |
---|
593 | 618 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); |
---|
594 | 619 | |
---|
595 | 620 | if (addr) |
---|
596 | | - usb_gadget_set_state(&dwc->gadget, USB_STATE_ADDRESS); |
---|
| 621 | + usb_gadget_set_state(dwc->gadget, USB_STATE_ADDRESS); |
---|
597 | 622 | else |
---|
598 | | - usb_gadget_set_state(&dwc->gadget, USB_STATE_DEFAULT); |
---|
| 623 | + usb_gadget_set_state(dwc->gadget, USB_STATE_DEFAULT); |
---|
599 | 624 | |
---|
600 | 625 | return 0; |
---|
601 | 626 | } |
---|
602 | 627 | |
---|
603 | 628 | static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
---|
604 | 629 | { |
---|
605 | | - int ret; |
---|
| 630 | + int ret = -EINVAL; |
---|
606 | 631 | |
---|
607 | | - spin_unlock(&dwc->lock); |
---|
608 | | - ret = dwc->gadget_driver->setup(&dwc->gadget, ctrl); |
---|
609 | | - spin_lock(&dwc->lock); |
---|
| 632 | + if (dwc->async_callbacks) { |
---|
| 633 | + spin_unlock(&dwc->lock); |
---|
| 634 | + ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); |
---|
| 635 | + spin_lock(&dwc->lock); |
---|
| 636 | + } |
---|
610 | 637 | return ret; |
---|
611 | 638 | } |
---|
612 | 639 | |
---|
613 | 640 | static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
---|
614 | 641 | { |
---|
615 | | - enum usb_device_state state = dwc->gadget.state; |
---|
| 642 | + enum usb_device_state state = dwc->gadget->state; |
---|
616 | 643 | u32 cfg; |
---|
617 | 644 | int ret; |
---|
618 | 645 | u32 reg; |
---|
.. | .. |
---|
624 | 651 | return -EINVAL; |
---|
625 | 652 | |
---|
626 | 653 | case USB_STATE_ADDRESS: |
---|
| 654 | + dwc3_gadget_clear_tx_fifos(dwc); |
---|
| 655 | + |
---|
627 | 656 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
---|
628 | 657 | /* if the cfg matches and the cfg is non zero */ |
---|
629 | 658 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { |
---|
.. | .. |
---|
635 | 664 | * to change the state on the next usb_ep_queue() |
---|
636 | 665 | */ |
---|
637 | 666 | if (ret == 0) |
---|
638 | | - usb_gadget_set_state(&dwc->gadget, |
---|
| 667 | + usb_gadget_set_state(dwc->gadget, |
---|
639 | 668 | USB_STATE_CONFIGURED); |
---|
640 | 669 | |
---|
641 | 670 | /* |
---|
.. | .. |
---|
643 | 672 | * nothing is pending from application. |
---|
644 | 673 | */ |
---|
645 | 674 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
---|
646 | | - if (dwc->dis_u1u2_quirk) |
---|
647 | | - reg &= ~(DWC3_DCTL_ACCEPTU1ENA | |
---|
648 | | - DWC3_DCTL_ACCEPTU2ENA); |
---|
649 | | - else |
---|
650 | | - reg |= (DWC3_DCTL_ACCEPTU1ENA | |
---|
651 | | - DWC3_DCTL_ACCEPTU2ENA); |
---|
| 675 | + if (!dwc->dis_u1_entry_quirk) |
---|
| 676 | + reg |= DWC3_DCTL_ACCEPTU1ENA; |
---|
| 677 | + if (!dwc->dis_u2_entry_quirk) |
---|
| 678 | + reg |= DWC3_DCTL_ACCEPTU2ENA; |
---|
652 | 679 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
---|
653 | 680 | } |
---|
654 | 681 | break; |
---|
.. | .. |
---|
656 | 683 | case USB_STATE_CONFIGURED: |
---|
657 | 684 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
---|
658 | 685 | if (!cfg && !ret) |
---|
659 | | - usb_gadget_set_state(&dwc->gadget, |
---|
| 686 | + usb_gadget_set_state(dwc->gadget, |
---|
660 | 687 | USB_STATE_ADDRESS); |
---|
661 | 688 | break; |
---|
662 | 689 | default: |
---|
.. | .. |
---|
712 | 739 | static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
---|
713 | 740 | { |
---|
714 | 741 | struct dwc3_ep *dep; |
---|
715 | | - enum usb_device_state state = dwc->gadget.state; |
---|
| 742 | + enum usb_device_state state = dwc->gadget->state; |
---|
716 | 743 | u16 wLength; |
---|
717 | 744 | |
---|
718 | 745 | if (state == USB_STATE_DEFAULT) |
---|
.. | .. |
---|
756 | 783 | if (wIndex || wLength) |
---|
757 | 784 | return -EINVAL; |
---|
758 | 785 | |
---|
759 | | - dwc->gadget.isoch_delay = wValue; |
---|
| 786 | + dwc->gadget->isoch_delay = wValue; |
---|
760 | 787 | |
---|
761 | 788 | return 0; |
---|
762 | 789 | } |
---|
.. | .. |
---|
801 | 828 | struct usb_ctrlrequest *ctrl = (void *) dwc->ep0_trb; |
---|
802 | 829 | int ret = -EINVAL; |
---|
803 | 830 | u32 len; |
---|
| 831 | + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); |
---|
804 | 832 | |
---|
805 | | - if (!dwc->gadget_driver) |
---|
| 833 | + if (!dwc->gadget_driver || !vdwc->softconnect || !dwc->connected) |
---|
806 | 834 | goto out; |
---|
807 | 835 | |
---|
808 | 836 | trace_dwc3_ctrl_req(ctrl); |
---|
.. | .. |
---|
1064 | 1092 | __dwc3_ep0_do_control_status(dwc, dep); |
---|
1065 | 1093 | } |
---|
1066 | 1094 | |
---|
1067 | | -static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) |
---|
| 1095 | +void dwc3_ep0_send_delayed_status(struct dwc3 *dwc) |
---|
| 1096 | +{ |
---|
| 1097 | + unsigned int direction = !dwc->ep0_expect_in; |
---|
| 1098 | + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); |
---|
| 1099 | + |
---|
| 1100 | + dwc->delayed_status = false; |
---|
| 1101 | + vdwc->clear_stall_protocol = 0; |
---|
| 1102 | + |
---|
| 1103 | + if (dwc->ep0state != EP0_STATUS_PHASE) |
---|
| 1104 | + return; |
---|
| 1105 | + |
---|
| 1106 | + __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); |
---|
| 1107 | +} |
---|
| 1108 | + |
---|
| 1109 | +void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) |
---|
1068 | 1110 | { |
---|
1069 | 1111 | struct dwc3_gadget_ep_cmd_params params; |
---|
1070 | 1112 | u32 cmd; |
---|
1071 | 1113 | int ret; |
---|
1072 | 1114 | |
---|
1073 | | - if (!dep->resource_index) |
---|
| 1115 | + /* |
---|
| 1116 | + * For status/DATA OUT stage, TRB will be queued on ep0 out |
---|
| 1117 | + * endpoint for which resource index is zero. Hence allow |
---|
| 1118 | + * queuing ENDXFER command for ep0 out endpoint. |
---|
| 1119 | + */ |
---|
| 1120 | + if (!dep->resource_index && dep->number) |
---|
1074 | 1121 | return; |
---|
1075 | 1122 | |
---|
1076 | 1123 | cmd = DWC3_DEPCMD_ENDTRANSFER; |
---|
.. | .. |
---|
1085 | 1132 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, |
---|
1086 | 1133 | const struct dwc3_event_depevt *event) |
---|
1087 | 1134 | { |
---|
| 1135 | + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); |
---|
| 1136 | + |
---|
1088 | 1137 | switch (event->status) { |
---|
1089 | 1138 | case DEPEVT_STATUS_CONTROL_DATA: |
---|
| 1139 | + if (!vdwc->softconnect || !dwc->connected) |
---|
| 1140 | + return; |
---|
1090 | 1141 | /* |
---|
1091 | 1142 | * We already have a DATA transfer in the controller's cache, |
---|
1092 | 1143 | * if we receive a XferNotReady(DATA) we will ignore it, unless |
---|
.. | .. |
---|
1111 | 1162 | if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) |
---|
1112 | 1163 | return; |
---|
1113 | 1164 | |
---|
| 1165 | + if (dwc->setup_packet_pending) { |
---|
| 1166 | + dwc3_ep0_stall_and_restart(dwc); |
---|
| 1167 | + return; |
---|
| 1168 | + } |
---|
| 1169 | + |
---|
1114 | 1170 | dwc->ep0state = EP0_STATUS_PHASE; |
---|
1115 | 1171 | |
---|
1116 | 1172 | if (dwc->delayed_status) { |
---|
.. | .. |
---|
1124 | 1180 | */ |
---|
1125 | 1181 | if (!list_empty(&dep->pending_list)) { |
---|
1126 | 1182 | dwc->delayed_status = false; |
---|
1127 | | - usb_gadget_set_state(&dwc->gadget, |
---|
| 1183 | + usb_gadget_set_state(dwc->gadget, |
---|
1128 | 1184 | USB_STATE_CONFIGURED); |
---|
1129 | 1185 | dwc3_ep0_do_control_status(dwc, event); |
---|
1130 | 1186 | } |
---|