aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorGerard Cauvy <g-cauvy1@ti.com>2012-02-10 05:21:18 -0500
committerFelipe Balbi <balbi@ti.com>2012-02-10 06:11:46 -0500
commit3b637367ae40b6d3c20e30cb0cdd059e67bbf848 (patch)
tree0d74b50fafb3f1191a29b87a0dcd1660cb95d7d2 /drivers/usb/dwc3
parent090725431b9636a0a59516ff0fe94933cf09a82b (diff)
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 <g-cauvy1@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.h3
-rw-r--r--drivers/usb/dwc3/ep0.c21
-rw-r--r--drivers/usb/dwc3/gadget.c1
3 files changed, 17 insertions, 8 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 71d958af2393..4dac9828577e 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -684,6 +684,9 @@ struct dwc3 {
684 684
685 struct dwc3_hwparams hwparams; 685 struct dwc3_hwparams hwparams;
686 struct dentry *root; 686 struct dentry *root;
687
688 u8 test_mode;
689 u8 test_mode_nr;
687}; 690};
688 691
689/* -------------------------------------------------------------------------- */ 692/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 5104dbf46680..c20e30c8b695 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -316,7 +316,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
316 u32 wValue; 316 u32 wValue;
317 u32 wIndex; 317 u32 wIndex;
318 int ret; 318 int ret;
319 u32 mode;
320 319
321 wValue = le16_to_cpu(ctrl->wValue); 320 wValue = le16_to_cpu(ctrl->wValue);
322 wIndex = le16_to_cpu(ctrl->wIndex); 321 wIndex = le16_to_cpu(ctrl->wIndex);
@@ -355,13 +354,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
355 if (!set) 354 if (!set)
356 return -EINVAL; 355 return -EINVAL;
357 356
358 mode = wIndex >> 8; 357 dwc->test_mode_nr = wIndex >> 8;
359 ret = dwc3_gadget_set_test_mode(dwc, mode); 358 dwc->test_mode = true;
360 if (ret < 0) {
361 dev_dbg(dwc->dev, "Invalid Test #%d\n",
362 mode);
363 return ret;
364 }
365 } 359 }
366 break; 360 break;
367 361
@@ -604,6 +598,17 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc,
604 dwc3_gadget_giveback(dep, r, 0); 598 dwc3_gadget_giveback(dep, r, 0);
605 } 599 }
606 600
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
607 dwc->ep0state = EP0_SETUP_PHASE; 612 dwc->ep0state = EP0_SETUP_PHASE;
608 dwc3_ep0_out_start(dwc); 613 dwc3_ep0_out_start(dwc);
609} 614}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index c30ab6da3d0e..76327005d54c 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1962,6 +1962,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
1962 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 1962 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
1963 reg &= ~DWC3_DCTL_TSTCTRL_MASK; 1963 reg &= ~DWC3_DCTL_TSTCTRL_MASK;
1964 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 1964 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
1965 dwc->test_mode = false;
1965 1966
1966 dwc3_stop_active_transfers(dwc); 1967 dwc3_stop_active_transfers(dwc);
1967 dwc3_clear_stall_all_ep(dwc); 1968 dwc3_clear_stall_all_ep(dwc);