diff options
Diffstat (limited to 'drivers/usb/dwc3/ep0.c')
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 4f28122f1bb8..c47e53ccd7b2 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -236,7 +236,10 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) struct dwc3_request *req; req = next_request(&dep->pending_list); - dwc3_gadget_giveback(dep, req, -ECONNRESET); + if (!dwc->connected) + dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + else + dwc3_gadget_giveback(dep, req, -ECONNRESET); } dwc->ep0state = EP0_SETUP_PHASE; @@ -339,6 +342,11 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, usb_status |= 1 << USB_DEV_STAT_U2_ENABLED; } + /* Sends the status indicating if the remote wakeup is + * supported by device. + */ + usb_status |= dwc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; + break; case USB_RECIP_INTERFACE: @@ -457,7 +465,12 @@ static int dwc3_ep0_handle_device(struct dwc3 *dwc, switch (wValue) { case USB_DEVICE_REMOTE_WAKEUP: + if (set) + dwc->remote_wakeup = 1; + else + dwc->remote_wakeup = 0; break; + /* * 9.4.1 says only only for SS, in AddressState only for * default control pipe @@ -474,6 +487,34 @@ static int dwc3_ep0_handle_device(struct dwc3 *dwc, case USB_DEVICE_TEST_MODE: ret = dwc3_ep0_handle_test(dwc, state, wIndex, set); break; + case USB_DEVICE_B_HNP_ENABLE: + if (set) { + if (dwc->gadget.host_request_flag) { + struct usb_phy *phy = + usb_get_phy(USB_PHY_TYPE_USB3); + + dwc->gadget.b_hnp_enable = 0; + dwc->gadget.host_request_flag = 0; + otg_start_hnp(phy->otg); + usb_put_phy(phy); + } else { + dwc->gadget.b_hnp_enable = 1; + } + } else + return -EINVAL; + break; + + case USB_DEVICE_A_HNP_SUPPORT: + /* RH port supports HNP */ + dev_dbg(dwc->dev, + "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n"); + break; + + case USB_DEVICE_A_ALT_HNP_SUPPORT: + /* other RH port does */ + dev_dbg(dwc->dev, + "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n"); + break; default: ret = -EINVAL; } @@ -760,7 +801,10 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) switch (ctrl->bRequest) { case USB_REQ_GET_STATUS: - ret = dwc3_ep0_handle_status(dwc, ctrl); + if (le16_to_cpu(ctrl->wIndex) == OTG_STS_SELECTOR) + ret = dwc3_ep0_delegate_req(dwc, ctrl); + else + ret = dwc3_ep0_handle_status(dwc, ctrl); break; case USB_REQ_CLEAR_FEATURE: ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); |