drivers/usb/dwc3/ep0.c
Source file repositories/reference/linux-study-clean/drivers/usb/dwc3/ep0.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/dwc3/ep0.c- Extension
.c- Size
- 29087 bytes
- Lines
- 1234
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/slab.hlinux/spinlock.hlinux/platform_device.hlinux/pm_runtime.hlinux/interrupt.hlinux/io.hlinux/list.hlinux/dma-mapping.hlinux/usb/ch9.hlinux/usb/gadget.hlinux/usb/composite.hcore.hdebug.hgadget.hio.h
Detected Declarations
struct timingfunction dwc3_ep0_prepare_one_trbfunction dwc3_ep0_start_transfunction __dwc3_gadget_ep0_queuefunction XferNotReadyfunction dwc3_gadget_ep0_queuefunction dwc3_ep0_stall_and_restartfunction __dwc3_gadget_ep0_set_haltfunction dwc3_gadget_ep0_set_haltfunction dwc3_ep0_out_startfunction dwc3_ep0_status_cmplfunction dwc3_ep0_handle_u1function dwc3_ep0_handle_u2function dwc3_ep0_handle_testfunction dwc3_ep0_handle_devicefunction dwc3_ep0_handle_intffunction dwc3_ep0_handle_endpointfunction dwc3_ep0_handle_featurefunction dwc3_ep0_set_addressfunction dwc3_ep0_delegate_reqfunction dwc3_ep0_set_configfunction dwc3_ep0_set_sel_cmplfunction dwc3_ep0_set_selfunction dwc3_ep0_set_isoch_delayfunction dwc3_ep0_std_requestfunction dwc3_ep0_inspect_setupfunction dwc3_ep0_complete_datafunction dwc3_ep0_complete_statusfunction dwc3_ep0_xfer_completefunction __dwc3_ep0_do_control_datafunction dwc3_ep0_start_control_statusfunction __dwc3_ep0_do_control_statusfunction dwc3_ep0_do_control_statusfunction dwc3_ep0_send_delayed_statusfunction dwc3_ep0_end_control_datafunction dwc3_ep0_xfernotreadyfunction XferNotReadyfunction dwc3_ep0_interrupt
Annotated Snippet
struct timing {
u8 u1sel;
u8 u1pel;
__le16 u2sel;
__le16 u2pel;
} __packed timing;
int ret;
memcpy(&timing, req->buf, sizeof(timing));
dwc->u1sel = timing.u1sel;
dwc->u1pel = timing.u1pel;
dwc->u2sel = le16_to_cpu(timing.u2sel);
dwc->u2pel = le16_to_cpu(timing.u2pel);
reg = dwc3_readl(dwc, DWC3_DCTL);
if (reg & DWC3_DCTL_INITU2ENA)
param = dwc->u2pel;
if (reg & DWC3_DCTL_INITU1ENA)
param = dwc->u1pel;
/*
* According to Synopsys Databook, if parameter is
* greater than 125, a value of zero should be
* programmed in the register.
*/
if (param > 125)
param = 0;
/* now that we have the time, issue DGCMD Set Sel */
ret = dwc3_send_gadget_generic_command(dwc,
DWC3_DGCMD_SET_PERIODIC_PAR, param);
WARN_ON(ret < 0);
}
static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
{
struct dwc3_ep *dep;
enum usb_device_state state = dwc->gadget->state;
u16 wLength;
if (state == USB_STATE_DEFAULT)
return -EINVAL;
wLength = le16_to_cpu(ctrl->wLength);
if (wLength != 6) {
dev_err(dwc->dev, "Set SEL should be 6 bytes, got %d\n",
wLength);
return -EINVAL;
}
/*
* To handle Set SEL we need to receive 6 bytes from Host. So let's
* queue a usb_request for 6 bytes.
*
* Remember, though, this controller can't handle non-wMaxPacketSize
* aligned transfers on the OUT direction, so we queue a request for
* wMaxPacketSize instead.
*/
dep = dwc->eps[0];
dwc->ep0_usb_req.dep = dep;
dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket;
dwc->ep0_usb_req.request.buf = dwc->setup_buf;
dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl;
return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
}
static int dwc3_ep0_set_isoch_delay(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
{
u16 wLength;
u16 wValue;
u16 wIndex;
wValue = le16_to_cpu(ctrl->wValue);
wLength = le16_to_cpu(ctrl->wLength);
wIndex = le16_to_cpu(ctrl->wIndex);
if (wIndex || wLength)
return -EINVAL;
dwc->gadget->isoch_delay = wValue;
return 0;
}
static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
{
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/spinlock.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `linux/interrupt.h`, `linux/io.h`, `linux/list.h`.
- Detected declarations: `struct timing`, `function dwc3_ep0_prepare_one_trb`, `function dwc3_ep0_start_trans`, `function __dwc3_gadget_ep0_queue`, `function XferNotReady`, `function dwc3_gadget_ep0_queue`, `function dwc3_ep0_stall_and_restart`, `function __dwc3_gadget_ep0_set_halt`, `function dwc3_gadget_ep0_set_halt`, `function dwc3_ep0_out_start`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.