drivers/usb/musb/musb_gadget.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/musb_gadget.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/musb_gadget.c- Extension
.c- Size
- 54272 bytes
- Lines
- 2096
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/list.hlinux/timer.hlinux/module.hlinux/smp.hlinux/spinlock.hlinux/string_choices.hlinux/delay.hlinux/dma-mapping.hlinux/slab.hmusb_core.hmusb_trace.h
Detected Declarations
function Copyrightfunction unmap_dma_bufferfunction musb_g_givebackfunction nukefunction max_ep_writesizefunction txstatefunction updatefunction rxstatefunction musb_g_rxfunction musb_gadget_enablefunction musb_gadget_disablefunction musb_free_requestfunction musb_ep_restartfunction musb_ep_restart_resume_workfunction musb_gadget_queuefunction musb_gadget_dequeuefunction list_for_each_entryfunction musb_gadget_set_haltfunction musb_gadget_set_wedgefunction musb_gadget_fifo_statusfunction musb_gadget_fifo_flushfunction musb_gadget_get_framefunction musb_gadget_wakeupfunction musb_gadget_set_self_poweredfunction musb_pullupfunction musb_gadget_vbus_sessionfunction musb_gadget_vbus_drawfunction musb_gadget_workfunction musb_gadget_pullupfunction init_peripheral_epfunction musb_g_init_endpointsfunction musb_gadget_setupfunction musb_gadget_cleanupfunction musb_gadget_startfunction musb_gadget_stopfunction musb_g_resumefunction musb_g_suspendfunction musb_g_wakeupfunction musb_g_disconnectfunction musb_g_reset
Annotated Snippet
if (ep->is_in) {
/*
* The programming guide says that we must not clear
* the DMAMODE bit before DMAENAB, so we only
* clear it in the second write...
*/
musb_writew(epio, MUSB_TXCSR,
MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
musb_writew(epio, MUSB_TXCSR,
0 | MUSB_TXCSR_FLUSHFIFO);
} else {
musb_writew(epio, MUSB_RXCSR,
0 | MUSB_RXCSR_FLUSHFIFO);
musb_writew(epio, MUSB_RXCSR,
0 | MUSB_RXCSR_FLUSHFIFO);
}
value = c->channel_abort(ep->dma);
musb_dbg(musb, "%s: abort DMA --> %d", ep->name, value);
c->channel_release(ep->dma);
ep->dma = NULL;
}
while (!list_empty(&ep->req_list)) {
req = list_first_entry(&ep->req_list, struct musb_request, list);
musb_g_giveback(ep, &req->request, status);
}
}
/* ----------------------------------------------------------------------- */
/* Data transfers - pure PIO, pure DMA, or mixed mode */
/*
* This assumes the separate CPPI engine is responding to DMA requests
* from the usb core ... sequenced a bit differently from mentor dma.
*/
static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)
{
if (can_bulk_split(musb, ep->type))
return ep->hw_ep->max_packet_sz_tx;
else
return ep->packet_sz;
}
/*
* An endpoint is transmitting data. This can be called either from
* the IRQ routine or from ep.queue() to kickstart a request on an
* endpoint.
*
* Context: controller locked, IRQs blocked, endpoint selected
*/
static void txstate(struct musb *musb, struct musb_request *req)
{
u8 epnum = req->epnum;
struct musb_ep *musb_ep;
void __iomem *epio = musb->endpoints[epnum].regs;
struct usb_request *request;
u16 fifo_count = 0, csr;
int use_dma = 0;
musb_ep = req->ep;
/* Check if EP is disabled */
if (!musb_ep->desc) {
musb_dbg(musb, "ep:%s disabled - ignore request",
musb_ep->end_point.name);
return;
}
/* we shouldn't get here while DMA is active ... but we do ... */
if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
musb_dbg(musb, "dma pending...");
return;
}
/* read TXCSR before */
csr = musb_readw(epio, MUSB_TXCSR);
request = &req->request;
fifo_count = min(max_ep_writesize(musb, musb_ep),
(int)(request->length - request->actual));
if (csr & MUSB_TXCSR_TXPKTRDY) {
musb_dbg(musb, "%s old packet still ready , txcsr %03x",
musb_ep->end_point.name, csr);
return;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/list.h`, `linux/timer.h`, `linux/module.h`, `linux/smp.h`, `linux/spinlock.h`, `linux/string_choices.h`, `linux/delay.h`.
- Detected declarations: `function Copyright`, `function unmap_dma_buffer`, `function musb_g_giveback`, `function nuke`, `function max_ep_writesize`, `function txstate`, `function update`, `function rxstate`, `function musb_g_rx`, `function musb_gadget_enable`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.