From: Felipe Balbi Date: Mon, 22 Jul 2013 09:41:47 +0000 (+0300) Subject: usb: dwc3: ep0: don't change to configured state too early X-Git-Tag: firefly_0821_release~176^2~5474^2~77^2~64 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7c81290e87bf01b507deabf0f478e051367cb416;p=firefly-linux-kernel-4.4.55.git 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 Signed-off-by: Felipe Balbi --- 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, direction = !dwc->ep0_expect_in; dwc->delayed_status = false; + usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED); if (dwc->ep0state == EP0_STATUS_PHASE) __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) ret = dwc3_ep0_delegate_req(dwc, ctrl); /* if the cfg matches and the cfg is non zero */ if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { - usb_gadget_set_state(&dwc->gadget, - USB_STATE_CONFIGURED); + + /* + * only change state if set_config has already + * been processed. If gadget driver returns + * USB_GADGET_DELAYED_STATUS, we will wait + * to change the state on the next usb_ep_queue() + */ + if (ret == 0) + usb_gadget_set_state(&dwc->gadget, + USB_STATE_CONFIGURED); /* * Enable transition to U1/U2 state when