Commit 39e07ffb authored by Felipe Balbi's avatar Felipe Balbi

usb: dwc3: ep0: simplify dwc3_ep0_handle_feature()

By extracting smaller functions from
dwc3_ep0_handle_feature(), it becomes far easier to
understand what's going on. Cleanup only, no
functional changes.
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 6d729a55
...@@ -371,126 +371,197 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, ...@@ -371,126 +371,197 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
} }
static int dwc3_ep0_handle_feature(struct dwc3 *dwc, static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
int set)
{
u32 reg;
if (state != USB_STATE_CONFIGURED)
return -EINVAL;
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU1ENA;
else
reg &= ~DWC3_DCTL_INITU1ENA;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
return 0;
}
static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
int set)
{
u32 reg;
if (state != USB_STATE_CONFIGURED)
return -EINVAL;
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (set)
reg |= DWC3_DCTL_INITU2ENA;
else
reg &= ~DWC3_DCTL_INITU2ENA;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
return 0;
}
static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state,
u32 wIndex, int set)
{
if ((wIndex & 0xff) != 0)
return -EINVAL;
if (!set)
return -EINVAL;
switch (wIndex >> 8) {
case TEST_J:
case TEST_K:
case TEST_SE0_NAK:
case TEST_PACKET:
case TEST_FORCE_EN:
dwc->test_mode_nr = wIndex >> 8;
dwc->test_mode = true;
break;
default:
return -EINVAL;
}
return 0;
}
static int dwc3_ep0_handle_device(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set) struct usb_ctrlrequest *ctrl, int set)
{ {
struct dwc3_ep *dep; enum usb_device_state state;
u32 recip;
u32 wValue; u32 wValue;
u32 wIndex; u32 wIndex;
u32 reg; int ret = 0;
int ret;
enum usb_device_state state;
wValue = le16_to_cpu(ctrl->wValue); wValue = le16_to_cpu(ctrl->wValue);
wIndex = le16_to_cpu(ctrl->wIndex); wIndex = le16_to_cpu(ctrl->wIndex);
recip = ctrl->bRequestType & USB_RECIP_MASK;
state = dwc->gadget.state; state = dwc->gadget.state;
switch (recip) { switch (wValue) {
case USB_RECIP_DEVICE: case USB_DEVICE_REMOTE_WAKEUP:
break;
/*
* 9.4.1 says only only for SS, in AddressState only for
* default control pipe
*/
case USB_DEVICE_U1_ENABLE:
ret = dwc3_ep0_handle_u1(dwc, state, set);
break;
case USB_DEVICE_U2_ENABLE:
ret = dwc3_ep0_handle_u2(dwc, state, set);
break;
case USB_DEVICE_LTM_ENABLE:
ret = -EINVAL;
break;
case USB_DEVICE_TEST_MODE:
ret = dwc3_ep0_handle_test(dwc, state, wIndex, set);
break;
default:
ret = -EINVAL;
}
switch (wValue) { return ret;
case USB_DEVICE_REMOTE_WAKEUP: }
break;
/*
* 9.4.1 says only only for SS, in AddressState only for
* default control pipe
*/
case USB_DEVICE_U1_ENABLE:
if (state != USB_STATE_CONFIGURED)
return -EINVAL;
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL); static int dwc3_ep0_handle_intf(struct dwc3 *dwc,
if (set) struct usb_ctrlrequest *ctrl, int set)
reg |= DWC3_DCTL_INITU1ENA; {
else enum usb_device_state state;
reg &= ~DWC3_DCTL_INITU1ENA; u32 wValue;
dwc3_writel(dwc->regs, DWC3_DCTL, reg); u32 wIndex;
break; int ret = 0;
case USB_DEVICE_U2_ENABLE: wValue = le16_to_cpu(ctrl->wValue);
if (state != USB_STATE_CONFIGURED) wIndex = le16_to_cpu(ctrl->wIndex);
return -EINVAL; state = dwc->gadget.state;
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL); switch (wValue) {
if (set) case USB_INTRF_FUNC_SUSPEND:
reg |= DWC3_DCTL_INITU2ENA; if (wIndex & USB_INTRF_FUNC_SUSPEND_LP)
else /* XXX enable Low power suspend */
reg &= ~DWC3_DCTL_INITU2ENA; ;
dwc3_writel(dwc->regs, DWC3_DCTL, reg); if (wIndex & USB_INTRF_FUNC_SUSPEND_RW)
break; /* XXX enable remote wakeup */
;
break;
default:
ret = -EINVAL;
}
case USB_DEVICE_LTM_ENABLE: return ret;
}
static int dwc3_ep0_handle_endpoint(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set)
{
struct dwc3_ep *dep;
enum usb_device_state state;
u32 wValue;
u32 wIndex;
int ret;
wValue = le16_to_cpu(ctrl->wValue);
wIndex = le16_to_cpu(ctrl->wIndex);
state = dwc->gadget.state;
switch (wValue) {
case USB_ENDPOINT_HALT:
dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
if (!dep)
return -EINVAL; return -EINVAL;
case USB_DEVICE_TEST_MODE: if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
if ((wIndex & 0xff) != 0)
return -EINVAL;
if (!set)
return -EINVAL;
switch (wIndex >> 8) {
case TEST_J:
case TEST_K:
case TEST_SE0_NAK:
case TEST_PACKET:
case TEST_FORCE_EN:
dwc->test_mode_nr = wIndex >> 8;
dwc->test_mode = true;
break;
default:
return -EINVAL;
}
break; break;
default:
ret = __dwc3_gadget_ep_set_halt(dep, set, true);
if (ret)
return -EINVAL; return -EINVAL;
}
break; break;
default:
return -EINVAL;
}
return 0;
}
static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set)
{
u32 recip;
int ret;
enum usb_device_state state;
recip = ctrl->bRequestType & USB_RECIP_MASK;
state = dwc->gadget.state;
switch (recip) {
case USB_RECIP_DEVICE:
ret = dwc3_ep0_handle_device(dwc, ctrl, set);
break;
case USB_RECIP_INTERFACE: case USB_RECIP_INTERFACE:
switch (wValue) { ret = dwc3_ep0_handle_intf(dwc, ctrl, set);
case USB_INTRF_FUNC_SUSPEND:
if (wIndex & USB_INTRF_FUNC_SUSPEND_LP)
/* XXX enable Low power suspend */
;
if (wIndex & USB_INTRF_FUNC_SUSPEND_RW)
/* XXX enable remote wakeup */
;
break;
default:
return -EINVAL;
}
break; break;
case USB_RECIP_ENDPOINT: case USB_RECIP_ENDPOINT:
switch (wValue) { ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set);
case USB_ENDPOINT_HALT:
dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
if (!dep)
return -EINVAL;
if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
break;
ret = __dwc3_gadget_ep_set_halt(dep, set, true);
if (ret)
return -EINVAL;
break;
default:
return -EINVAL;
}
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
return 0; return ret;
} }
static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment