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: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
Felipe Balbi 2016-10-03 12:55:29 +03:00
parent 6d729a55cc
commit 39e07ffb1c
1 changed files with 175 additions and 104 deletions

View File

@ -371,121 +371,66 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
}
static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set)
static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
int set)
{
struct dwc3_ep *dep;
u32 recip;
u32 wValue;
u32 wIndex;
u32 reg;
int ret;
enum usb_device_state state;
u32 reg;
wValue = le16_to_cpu(ctrl->wValue);
wIndex = le16_to_cpu(ctrl->wIndex);
recip = ctrl->bRequestType & USB_RECIP_MASK;
state = dwc->gadget.state;
if (state != USB_STATE_CONFIGURED)
return -EINVAL;
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
switch (recip) {
case USB_RECIP_DEVICE:
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);
switch (wValue) {
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;
return 0;
}
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);
break;
static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
int set)
{
u32 reg;
case USB_DEVICE_U2_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);
if (set)
reg |= DWC3_DCTL_INITU2ENA;
else
reg &= ~DWC3_DCTL_INITU2ENA;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
break;
if (state != USB_STATE_CONFIGURED)
return -EINVAL;
if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
(dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
return -EINVAL;
case USB_DEVICE_LTM_ENABLE:
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);
case USB_DEVICE_TEST_MODE:
if ((wIndex & 0xff) != 0)
return -EINVAL;
if (!set)
return -EINVAL;
return 0;
}
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;
default:
return -EINVAL;
}
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;
case USB_RECIP_INTERFACE:
switch (wValue) {
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;
case USB_RECIP_ENDPOINT:
switch (wValue) {
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;
default:
return -EINVAL;
}
@ -493,6 +438,132 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return 0;
}
static int dwc3_ep0_handle_device(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set)
{
enum usb_device_state state;
u32 wValue;
u32 wIndex;
int ret = 0;
wValue = le16_to_cpu(ctrl->wValue);
wIndex = le16_to_cpu(ctrl->wIndex);
state = dwc->gadget.state;
switch (wValue) {
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;
}
return ret;
}
static int dwc3_ep0_handle_intf(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set)
{
enum usb_device_state state;
u32 wValue;
u32 wIndex;
int ret = 0;
wValue = le16_to_cpu(ctrl->wValue);
wIndex = le16_to_cpu(ctrl->wIndex);
state = dwc->gadget.state;
switch (wValue) {
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:
ret = -EINVAL;
}
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;
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;
}
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:
ret = dwc3_ep0_handle_intf(dwc, ctrl, set);
break;
case USB_RECIP_ENDPOINT:
ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set);
break;
default:
ret = -EINVAL;
}
return ret;
}
static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
{
enum usb_device_state state = dwc->gadget.state;