in gadget/udc/net2280.c [2869:3076]
static void handle_stat0_irqs_superspeed(struct net2280 *dev,
struct net2280_ep *ep, struct usb_ctrlrequest r)
{
struct net2280_ep *e;
u16 status;
int tmp = 0;
#define w_value le16_to_cpu(r.wValue)
#define w_index le16_to_cpu(r.wIndex)
#define w_length le16_to_cpu(r.wLength)
switch (r.bRequest) {
case USB_REQ_SET_CONFIGURATION:
dev->addressed_state = !w_value;
goto usb3_delegate;
case USB_REQ_GET_STATUS:
switch (r.bRequestType) {
case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
status = dev->wakeup_enable ? 0x02 : 0x00;
if (dev->gadget.is_selfpowered)
status |= BIT(0);
status |= (dev->u1_enable << 2 | dev->u2_enable << 3 |
dev->ltm_enable << 4);
writel(0, &dev->epregs[0].ep_irqenb);
set_fifo_bytecount(ep, sizeof(status));
writel((__force u32) status, &dev->epregs[0].ep_data);
allow_status_338x(ep);
break;
case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
e = get_ep_by_addr(dev, w_index);
if (!e)
goto do_stall3;
status = readl(&e->regs->ep_rsp) &
BIT(CLEAR_ENDPOINT_HALT);
writel(0, &dev->epregs[0].ep_irqenb);
set_fifo_bytecount(ep, sizeof(status));
writel((__force u32) status, &dev->epregs[0].ep_data);
allow_status_338x(ep);
break;
default:
goto usb3_delegate;
}
break;
case USB_REQ_CLEAR_FEATURE:
switch (r.bRequestType) {
case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
if (!dev->addressed_state) {
switch (w_value) {
case USB_DEVICE_U1_ENABLE:
dev->u1_enable = 0;
writel(readl(&dev->usb_ext->usbctl2) &
~BIT(U1_ENABLE),
&dev->usb_ext->usbctl2);
allow_status_338x(ep);
goto next_endpoints3;
case USB_DEVICE_U2_ENABLE:
dev->u2_enable = 0;
writel(readl(&dev->usb_ext->usbctl2) &
~BIT(U2_ENABLE),
&dev->usb_ext->usbctl2);
allow_status_338x(ep);
goto next_endpoints3;
case USB_DEVICE_LTM_ENABLE:
dev->ltm_enable = 0;
writel(readl(&dev->usb_ext->usbctl2) &
~BIT(LTM_ENABLE),
&dev->usb_ext->usbctl2);
allow_status_338x(ep);
goto next_endpoints3;
default:
break;
}
}
if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
dev->wakeup_enable = 0;
writel(readl(&dev->usb->usbctl) &
~BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
&dev->usb->usbctl);
allow_status_338x(ep);
break;
}
goto usb3_delegate;
case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
e = get_ep_by_addr(dev, w_index);
if (!e)
goto do_stall3;
if (w_value != USB_ENDPOINT_HALT)
goto do_stall3;
ep_vdbg(dev, "%s clear halt\n", e->ep.name);
/*
* Workaround for SS SeqNum not cleared via
* Endpoint Halt (Clear) bit. select endpoint
*/
ep_clear_seqnum(e);
clear_halt(e);
if (!list_empty(&e->queue) && e->td_dma)
restart_dma(e);
allow_status(ep);
ep->stopped = 1;
break;
default:
goto usb3_delegate;
}
break;
case USB_REQ_SET_FEATURE:
switch (r.bRequestType) {
case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
if (!dev->addressed_state) {
switch (w_value) {
case USB_DEVICE_U1_ENABLE:
dev->u1_enable = 1;
writel(readl(&dev->usb_ext->usbctl2) |
BIT(U1_ENABLE),
&dev->usb_ext->usbctl2);
allow_status_338x(ep);
goto next_endpoints3;
case USB_DEVICE_U2_ENABLE:
dev->u2_enable = 1;
writel(readl(&dev->usb_ext->usbctl2) |
BIT(U2_ENABLE),
&dev->usb_ext->usbctl2);
allow_status_338x(ep);
goto next_endpoints3;
case USB_DEVICE_LTM_ENABLE:
dev->ltm_enable = 1;
writel(readl(&dev->usb_ext->usbctl2) |
BIT(LTM_ENABLE),
&dev->usb_ext->usbctl2);
allow_status_338x(ep);
goto next_endpoints3;
default:
break;
}
}
if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
dev->wakeup_enable = 1;
writel(readl(&dev->usb->usbctl) |
BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
&dev->usb->usbctl);
allow_status_338x(ep);
break;
}
goto usb3_delegate;
case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
e = get_ep_by_addr(dev, w_index);
if (!e || (w_value != USB_ENDPOINT_HALT))
goto do_stall3;
ep->stopped = 1;
if (ep->num == 0)
ep->dev->protocol_stall = 1;
else {
if (ep->dma)
abort_dma(ep);
set_halt(ep);
}
allow_status_338x(ep);
break;
default:
goto usb3_delegate;
}
break;
default:
usb3_delegate:
ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n",
r.bRequestType, r.bRequest,
w_value, w_index, w_length,
readl(&ep->cfg->ep_cfg));
ep->responded = 0;
if (dev->async_callbacks) {
spin_unlock(&dev->lock);
tmp = dev->driver->setup(&dev->gadget, &r);
spin_lock(&dev->lock);
}
}
do_stall3:
if (tmp < 0) {
ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n",
r.bRequestType, r.bRequest, tmp);
dev->protocol_stall = 1;
/* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */
set_halt(ep);
}
next_endpoints3:
#undef w_value
#undef w_index
#undef w_length
return;
}