drivers/usb/musb/musb_host.c
Source file repositories/reference/linux-study-clean/drivers/usb/musb/musb_host.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/musb/musb_host.c- Extension
.c- Size
- 75695 bytes
- Lines
- 2766
- 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/module.hlinux/kernel.hlinux/delay.hlinux/sched.hlinux/slab.hlinux/string_choices.hlinux/errno.hlinux/list.hlinux/dma-mapping.hmusb_core.hmusb_host.hmusb_trace.h
Detected Declarations
struct musb_temp_bufferfunction musb_h_tx_flush_fifofunction musb_h_ep0_flush_fifofunction musb_h_tx_startfunction musb_h_tx_dma_startfunction musb_ep_set_qhfunction musb_start_urbfunction musb_givebackfunction musb_advance_schedulefunction list_emptyfunction musb_h_flush_rxfifofunction packetfunction musb_rx_reinitfunction musb_tx_dma_set_mode_mentorfunction musb_tx_dma_set_mode_cppi_tusbfunction musb_tx_dma_programfunction musb_ep_programfunction musb_bulk_nak_timeoutfunction endpointfunction musb_interruptfunction Isrfunction musb_rx_dma_iso_cppi41function musb_rx_dma_iso_cppi41function musb_rx_dma_inventra_cppi41function transferfunction musb_rx_dma_inventra_cppi41function musb_rx_dma_in_inventra_cppi41function musb_host_rxfunction musb_schedulefunction musb_urb_enqueuefunction musb_cleanup_urbfunction musb_urb_dequeuefunction musb_h_disablefunction hw_epfunction musb_h_get_frame_numberfunction musb_h_startfunction musb_h_stopfunction musb_bus_suspendfunction musb_bus_resumefunction musb_free_temp_bufferfunction musb_alloc_temp_bufferfunction musb_map_urb_for_dmafunction musb_unmap_urb_for_dmafunction musb_host_allocfunction musb_host_cleanupfunction musb_host_freefunction musb_host_setupfunction musb_host_resume_root_hub
Annotated Snippet
struct musb_temp_buffer {
void *kmalloc_ptr;
void *old_xfer_buffer;
u8 data[];
};
static void musb_free_temp_buffer(struct urb *urb)
{
enum dma_data_direction dir;
struct musb_temp_buffer *temp;
size_t length;
if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
temp = container_of(urb->transfer_buffer, struct musb_temp_buffer,
data);
if (dir == DMA_FROM_DEVICE) {
if (usb_pipeisoc(urb->pipe))
length = urb->transfer_buffer_length;
else
length = urb->actual_length;
memcpy(temp->old_xfer_buffer, temp->data, length);
}
urb->transfer_buffer = temp->old_xfer_buffer;
kfree(temp->kmalloc_ptr);
urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
}
static int musb_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
{
enum dma_data_direction dir;
struct musb_temp_buffer *temp;
void *kmalloc_ptr;
size_t kmalloc_size;
if (urb->num_sgs || urb->sg ||
urb->transfer_buffer_length == 0 ||
!((uintptr_t)urb->transfer_buffer & (MUSB_USB_DMA_ALIGN - 1)))
return 0;
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
/* Allocate a buffer with enough padding for alignment */
kmalloc_size = urb->transfer_buffer_length +
sizeof(struct musb_temp_buffer) + MUSB_USB_DMA_ALIGN - 1;
kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
if (!kmalloc_ptr)
return -ENOMEM;
/* Position our struct temp_buffer such that data is aligned */
temp = PTR_ALIGN(kmalloc_ptr, MUSB_USB_DMA_ALIGN);
temp->kmalloc_ptr = kmalloc_ptr;
temp->old_xfer_buffer = urb->transfer_buffer;
if (dir == DMA_TO_DEVICE)
memcpy(temp->data, urb->transfer_buffer,
urb->transfer_buffer_length);
urb->transfer_buffer = temp->data;
urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
return 0;
}
static int musb_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
gfp_t mem_flags)
{
struct musb *musb = hcd_to_musb(hcd);
int ret;
/*
* The DMA engine in RTL1.8 and above cannot handle
* DMA addresses that are not aligned to a 4 byte boundary.
* For such engine implemented (un)map_urb_for_dma hooks.
* Do not use these hooks for RTL<1.8
*/
if (musb->hwvers < MUSB_HWVERS_1800)
return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
ret = musb_alloc_temp_buffer(urb, mem_flags);
if (ret)
return ret;
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/delay.h`, `linux/sched.h`, `linux/slab.h`, `linux/string_choices.h`, `linux/errno.h`, `linux/list.h`.
- Detected declarations: `struct musb_temp_buffer`, `function musb_h_tx_flush_fifo`, `function musb_h_ep0_flush_fifo`, `function musb_h_tx_start`, `function musb_h_tx_dma_start`, `function musb_ep_set_qh`, `function musb_start_urb`, `function musb_giveback`, `function musb_advance_schedule`, `function list_empty`.
- 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.