diff options
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 82 |
1 files changed, 41 insertions, 41 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index d5c568e91874..25910e251c04 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -76,8 +76,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
76 | u32 len, u32 type) | 76 | u32 len, u32 type) |
77 | { | 77 | { |
78 | struct dwc3_gadget_ep_cmd_params params; | 78 | struct dwc3_gadget_ep_cmd_params params; |
79 | struct dwc3_trb_hw *trb_hw; | 79 | struct dwc3_trb *trb; |
80 | struct dwc3_trb trb; | ||
81 | struct dwc3_ep *dep; | 80 | struct dwc3_ep *dep; |
82 | 81 | ||
83 | int ret; | 82 | int ret; |
@@ -88,19 +87,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, | |||
88 | return 0; | 87 | return 0; |
89 | } | 88 | } |
90 | 89 | ||
91 | trb_hw = dwc->ep0_trb; | 90 | trb = dwc->ep0_trb; |
92 | memset(&trb, 0, sizeof(trb)); | ||
93 | 91 | ||
94 | trb.trbctl = type; | 92 | trb->bpl = lower_32_bits(buf_dma); |
95 | trb.bplh = buf_dma; | 93 | trb->bph = upper_32_bits(buf_dma); |
96 | trb.length = len; | 94 | trb->size = len; |
95 | trb->ctrl = type; | ||
97 | 96 | ||
98 | trb.hwo = 1; | 97 | trb->ctrl |= (DWC3_TRB_CTRL_HWO |
99 | trb.lst = 1; | 98 | | DWC3_TRB_CTRL_LST |
100 | trb.ioc = 1; | 99 | | DWC3_TRB_CTRL_IOC |
101 | trb.isp_imi = 1; | 100 | | DWC3_TRB_CTRL_ISP_IMI); |
102 | |||
103 | dwc3_trb_to_hw(&trb, trb_hw); | ||
104 | 101 | ||
105 | memset(¶ms, 0, sizeof(params)); | 102 | memset(¶ms, 0, sizeof(params)); |
106 | params.param0 = upper_32_bits(dwc->ep0_trb_addr); | 103 | params.param0 = upper_32_bits(dwc->ep0_trb_addr); |
@@ -315,9 +312,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, | |||
315 | u32 recip; | 312 | u32 recip; |
316 | u32 wValue; | 313 | u32 wValue; |
317 | u32 wIndex; | 314 | u32 wIndex; |
318 | u32 reg; | ||
319 | int ret; | 315 | int ret; |
320 | u32 mode; | ||
321 | 316 | ||
322 | wValue = le16_to_cpu(ctrl->wValue); | 317 | wValue = le16_to_cpu(ctrl->wValue); |
323 | wIndex = le16_to_cpu(ctrl->wIndex); | 318 | wIndex = le16_to_cpu(ctrl->wIndex); |
@@ -356,25 +351,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, | |||
356 | if (!set) | 351 | if (!set) |
357 | return -EINVAL; | 352 | return -EINVAL; |
358 | 353 | ||
359 | mode = wIndex >> 8; | 354 | dwc->test_mode_nr = wIndex >> 8; |
360 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 355 | dwc->test_mode = true; |
361 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | ||
362 | |||
363 | switch (mode) { | ||
364 | case TEST_J: | ||
365 | case TEST_K: | ||
366 | case TEST_SE0_NAK: | ||
367 | case TEST_PACKET: | ||
368 | case TEST_FORCE_EN: | ||
369 | reg |= mode << 1; | ||
370 | break; | ||
371 | default: | ||
372 | return -EINVAL; | ||
373 | } | ||
374 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
375 | break; | ||
376 | default: | ||
377 | return -EINVAL; | ||
378 | } | 356 | } |
379 | break; | 357 | break; |
380 | 358 | ||
@@ -396,7 +374,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, | |||
396 | case USB_RECIP_ENDPOINT: | 374 | case USB_RECIP_ENDPOINT: |
397 | switch (wValue) { | 375 | switch (wValue) { |
398 | case USB_ENDPOINT_HALT: | 376 | case USB_ENDPOINT_HALT: |
399 | dep = dwc3_wIndex_to_dep(dwc, wIndex); | 377 | dep = dwc3_wIndex_to_dep(dwc, wIndex); |
400 | if (!dep) | 378 | if (!dep) |
401 | return -EINVAL; | 379 | return -EINVAL; |
402 | ret = __dwc3_gadget_ep_set_halt(dep, set); | 380 | ret = __dwc3_gadget_ep_set_halt(dep, set); |
@@ -470,8 +448,11 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |||
470 | case DWC3_ADDRESS_STATE: | 448 | case DWC3_ADDRESS_STATE: |
471 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | 449 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
472 | /* if the cfg matches and the cfg is non zero */ | 450 | /* if the cfg matches and the cfg is non zero */ |
473 | if (!ret && cfg) | 451 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { |
474 | dwc->dev_state = DWC3_CONFIGURED_STATE; | 452 | dwc->dev_state = DWC3_CONFIGURED_STATE; |
453 | dwc->resize_fifos = true; | ||
454 | dev_dbg(dwc->dev, "resize fifos flag SET\n"); | ||
455 | } | ||
475 | break; | 456 | break; |
476 | 457 | ||
477 | case DWC3_CONFIGURED_STATE: | 458 | case DWC3_CONFIGURED_STATE: |
@@ -560,9 +541,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
560 | { | 541 | { |
561 | struct dwc3_request *r = NULL; | 542 | struct dwc3_request *r = NULL; |
562 | struct usb_request *ur; | 543 | struct usb_request *ur; |
563 | struct dwc3_trb trb; | 544 | struct dwc3_trb *trb; |
564 | struct dwc3_ep *ep0; | 545 | struct dwc3_ep *ep0; |
565 | u32 transferred; | 546 | u32 transferred; |
547 | u32 length; | ||
566 | u8 epnum; | 548 | u8 epnum; |
567 | 549 | ||
568 | epnum = event->endpoint_number; | 550 | epnum = event->endpoint_number; |
@@ -573,16 +555,16 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
573 | r = next_request(&ep0->request_list); | 555 | r = next_request(&ep0->request_list); |
574 | ur = &r->request; | 556 | ur = &r->request; |
575 | 557 | ||
576 | dwc3_trb_to_nat(dwc->ep0_trb, &trb); | 558 | trb = dwc->ep0_trb; |
559 | length = trb->size & DWC3_TRB_SIZE_MASK; | ||
577 | 560 | ||
578 | if (dwc->ep0_bounced) { | 561 | if (dwc->ep0_bounced) { |
579 | |||
580 | transferred = min_t(u32, ur->length, | 562 | transferred = min_t(u32, ur->length, |
581 | ep0->endpoint.maxpacket - trb.length); | 563 | ep0->endpoint.maxpacket - length); |
582 | memcpy(ur->buf, dwc->ep0_bounce, transferred); | 564 | memcpy(ur->buf, dwc->ep0_bounce, transferred); |
583 | dwc->ep0_bounced = false; | 565 | dwc->ep0_bounced = false; |
584 | } else { | 566 | } else { |
585 | transferred = ur->length - trb.length; | 567 | transferred = ur->length - length; |
586 | ur->actual += transferred; | 568 | ur->actual += transferred; |
587 | } | 569 | } |
588 | 570 | ||
@@ -614,6 +596,17 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc, | |||
614 | dwc3_gadget_giveback(dep, r, 0); | 596 | dwc3_gadget_giveback(dep, r, 0); |
615 | } | 597 | } |
616 | 598 | ||
599 | if (dwc->test_mode) { | ||
600 | int ret; | ||
601 | |||
602 | ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr); | ||
603 | if (ret < 0) { | ||
604 | dev_dbg(dwc->dev, "Invalid Test #%d\n", | ||
605 | dwc->test_mode_nr); | ||
606 | dwc3_ep0_stall_and_restart(dwc); | ||
607 | } | ||
608 | } | ||
609 | |||
617 | dwc->ep0state = EP0_SETUP_PHASE; | 610 | dwc->ep0state = EP0_SETUP_PHASE; |
618 | dwc3_ep0_out_start(dwc); | 611 | dwc3_ep0_out_start(dwc); |
619 | } | 612 | } |
@@ -624,6 +617,7 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, | |||
624 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; | 617 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; |
625 | 618 | ||
626 | dep->flags &= ~DWC3_EP_BUSY; | 619 | dep->flags &= ~DWC3_EP_BUSY; |
620 | dep->res_trans_idx = 0; | ||
627 | dwc->setup_packet_pending = false; | 621 | dwc->setup_packet_pending = false; |
628 | 622 | ||
629 | switch (dwc->ep0state) { | 623 | switch (dwc->ep0state) { |
@@ -730,6 +724,12 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) | |||
730 | { | 724 | { |
731 | struct dwc3_ep *dep = dwc->eps[epnum]; | 725 | struct dwc3_ep *dep = dwc->eps[epnum]; |
732 | 726 | ||
727 | if (dwc->resize_fifos) { | ||
728 | dev_dbg(dwc->dev, "starting to resize fifos\n"); | ||
729 | dwc3_gadget_resize_tx_fifos(dwc); | ||
730 | dwc->resize_fifos = 0; | ||
731 | } | ||
732 | |||
733 | WARN_ON(dwc3_ep0_start_control_status(dep)); | 733 | WARN_ON(dwc3_ep0_start_control_status(dep)); |
734 | } | 734 | } |
735 | 735 | ||