Skip to content

Commit 3b63736

Browse files
Gerard CauvyFelipe Balbi
authored andcommitted
usb: dwc3: ep0: fix SetFeature(TEST)
When host requests us to enter a test mode, we cannot directly enter the test mode before Status Phase is completed, otherwise the core will never be able to deliver the Status ZLP to host, because it has already entered the requested Test Mode. In order to fix the error, we move the actual start of Test Mode right after we receive Transfer Complete event of the status phase. Signed-off-by: Gerard Cauvy <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 0907254 commit 3b63736

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

drivers/usb/dwc3/core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ struct dwc3 {
684684

685685
struct dwc3_hwparams hwparams;
686686
struct dentry *root;
687+
688+
u8 test_mode;
689+
u8 test_mode_nr;
687690
};
688691

689692
/* -------------------------------------------------------------------------- */

drivers/usb/dwc3/ep0.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
316316
u32 wValue;
317317
u32 wIndex;
318318
int ret;
319-
u32 mode;
320319

321320
wValue = le16_to_cpu(ctrl->wValue);
322321
wIndex = le16_to_cpu(ctrl->wIndex);
@@ -355,13 +354,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
355354
if (!set)
356355
return -EINVAL;
357356

358-
mode = wIndex >> 8;
359-
ret = dwc3_gadget_set_test_mode(dwc, mode);
360-
if (ret < 0) {
361-
dev_dbg(dwc->dev, "Invalid Test #%d\n",
362-
mode);
363-
return ret;
364-
}
357+
dwc->test_mode_nr = wIndex >> 8;
358+
dwc->test_mode = true;
365359
}
366360
break;
367361

@@ -604,6 +598,17 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc,
604598
dwc3_gadget_giveback(dep, r, 0);
605599
}
606600

601+
if (dwc->test_mode) {
602+
int ret;
603+
604+
ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
605+
if (ret < 0) {
606+
dev_dbg(dwc->dev, "Invalid Test #%d\n",
607+
dwc->test_mode_nr);
608+
dwc3_ep0_stall_and_restart(dwc);
609+
}
610+
}
611+
607612
dwc->ep0state = EP0_SETUP_PHASE;
608613
dwc3_ep0_out_start(dwc);
609614
}

drivers/usb/dwc3/gadget.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
19621962
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
19631963
reg &= ~DWC3_DCTL_TSTCTRL_MASK;
19641964
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
1965+
dwc->test_mode = false;
19651966

19661967
dwc3_stop_active_transfers(dwc);
19671968
dwc3_clear_stall_all_ep(dwc);

0 commit comments

Comments
 (0)