aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/ep0.c
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/ep0.c
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/ep0.c')
-rw-r--r--drivers/usb/dwc3/ep0.c21
1 files changed, 13 insertions, 8 deletions
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}