diff options
author | Felipe Balbi <balbi@ti.com> | 2013-07-22 05:41:47 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-07-29 06:57:04 -0400 |
commit | 7c81290e87bf01b507deabf0f478e051367cb416 (patch) | |
tree | 0e378bf02105063f5a9e7622b135f6cc9a1768ff | |
parent | 7a42d83536a5ea7ea7b4ad279c34c4c4ce509b5a (diff) |
usb: dwc3: ep0: don't change to configured state too early
before changing to configured state, we need
to wait until gadget driver has had a chance
to process the request.
In case of USB_GADGET_DELAYED_STATUS, that means
we need to defer usb_gadget_set_state() until
the upcoming usb_ep_queue().
Reported-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 007651c21638..7fa93f4bc507 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -148,6 +148,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, | |||
148 | 148 | ||
149 | direction = !dwc->ep0_expect_in; | 149 | direction = !dwc->ep0_expect_in; |
150 | dwc->delayed_status = false; | 150 | dwc->delayed_status = false; |
151 | usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED); | ||
151 | 152 | ||
152 | if (dwc->ep0state == EP0_STATUS_PHASE) | 153 | if (dwc->ep0state == EP0_STATUS_PHASE) |
153 | __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); | 154 | __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); |
@@ -533,8 +534,16 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |||
533 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | 534 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
534 | /* if the cfg matches and the cfg is non zero */ | 535 | /* if the cfg matches and the cfg is non zero */ |
535 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { | 536 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { |
536 | usb_gadget_set_state(&dwc->gadget, | 537 | |
537 | USB_STATE_CONFIGURED); | 538 | /* |
539 | * only change state if set_config has already | ||
540 | * been processed. If gadget driver returns | ||
541 | * USB_GADGET_DELAYED_STATUS, we will wait | ||
542 | * to change the state on the next usb_ep_queue() | ||
543 | */ | ||
544 | if (ret == 0) | ||
545 | usb_gadget_set_state(&dwc->gadget, | ||
546 | USB_STATE_CONFIGURED); | ||
538 | 547 | ||
539 | /* | 548 | /* |
540 | * Enable transition to U1/U2 state when | 549 | * Enable transition to U1/U2 state when |