drivers/usb/host/xhci-ring.c
Source file repositories/reference/linux-study-clean/drivers/usb/host/xhci-ring.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/host/xhci-ring.c- Extension
.c- Size
- 136585 bytes
- Lines
- 4488
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/jiffies.hlinux/scatterlist.hlinux/slab.hlinux/string_choices.hlinux/dma-mapping.hxhci.hxhci-trace.h
Detected Declarations
function xhci_trb_virt_to_dmafunction xhci_for_each_ring_segfunction trb_is_noopfunction trb_is_linkfunction last_trb_on_segfunction last_trb_on_ringfunction link_trb_toggles_cyclefunction last_td_in_urbfunction unhandled_event_trbfunction inc_td_cntfunction trb_to_noopfunction trb_to_posfunction next_trbfunction inc_deqfunction inc_enq_past_linkfunction clearedfunction dma_in_rangefunction trb_in_tdfunction xhci_num_trbs_freefunction xhci_ring_expansion_neededfunction xhci_ring_cmd_dbfunction xhci_mod_cmd_timerfunction xhci_handle_stopped_cmd_ringfunction xhci_abort_cmd_ringfunction xhci_ring_ep_doorbellfunction ring_doorbell_for_active_ringsfunction xhci_ring_doorbell_for_active_ringsfunction xhci_get_hw_deqfunction xhci_move_dequeue_past_tdfunction foundfunction td_to_noopfunction xhci_giveback_urb_in_irqfunction xhci_unmap_td_bounce_bufferfunction xhci_td_cleanupfunction xhci_dequeue_tdfunction xhci_giveback_invalidated_tdsfunction list_for_each_entry_safefunction xhci_reset_halted_epfunction xhci_handle_halted_endpointfunction xhci_invalidate_cancelled_tdsfunction list_for_each_entry_safefunction list_for_each_entry_safefunction ringfunction xhci_handle_cmd_stop_epfunction xhci_kill_ring_urbsfunction list_for_each_entry_safefunction xhci_kill_endpoint_urbsfunction list_for_each_entry_safe
Annotated Snippet
if (in_range(dma, seg->dma, TRB_SEGMENT_SIZE)) {
if (match_seg)
*match_seg = seg;
return &seg->trbs[(dma - seg->dma) / sizeof(union xhci_trb)];
}
}
return NULL;
}
static bool trb_is_noop(union xhci_trb *trb)
{
return TRB_TYPE_NOOP_LE32(trb->generic.field[3]);
}
static bool trb_is_link(union xhci_trb *trb)
{
return TRB_TYPE_LINK_LE32(trb->link.control);
}
static bool last_trb_on_seg(struct xhci_segment *seg, union xhci_trb *trb)
{
return trb == &seg->trbs[TRBS_PER_SEGMENT - 1];
}
static bool last_trb_on_ring(struct xhci_ring *ring,
struct xhci_segment *seg, union xhci_trb *trb)
{
return last_trb_on_seg(seg, trb) && (seg->next == ring->first_seg);
}
static bool link_trb_toggles_cycle(union xhci_trb *trb)
{
return le32_to_cpu(trb->link.control) & LINK_TOGGLE;
}
static bool last_td_in_urb(struct xhci_td *td)
{
struct urb_priv *urb_priv = td->urb->hcpriv;
return urb_priv->num_tds_done == urb_priv->num_tds;
}
static bool unhandled_event_trb(struct xhci_ring *ring)
{
return ((le32_to_cpu(ring->dequeue->event_cmd.flags) & TRB_CYCLE) ==
ring->cycle_state);
}
static void inc_td_cnt(struct urb *urb)
{
struct urb_priv *urb_priv = urb->hcpriv;
urb_priv->num_tds_done++;
}
static void trb_to_noop(union xhci_trb *trb, u32 noop_type, bool unchain_links)
{
if (trb_is_link(trb)) {
if (unchain_links)
trb->link.control &= cpu_to_le32(~TRB_CHAIN);
} else {
trb->generic.field[0] = 0;
trb->generic.field[1] = 0;
trb->generic.field[2] = 0;
/* Preserve only the cycle bit of this TRB */
trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE);
trb->generic.field[3] |= cpu_to_le32(TRB_TYPE(noop_type));
}
}
static unsigned int trb_to_pos(struct xhci_segment *seg, union xhci_trb *trb)
{
return seg->num * TRBS_PER_SEGMENT + (trb - seg->trbs);
}
/* Updates trb to point to the next TRB in the ring, and updates seg if the next
* TRB is in a new segment. This does not skip over link TRBs, and it does not
* effect the ring dequeue or enqueue pointers.
*/
static void next_trb(struct xhci_segment **seg,
union xhci_trb **trb)
{
if (trb_is_link(*trb) || last_trb_on_seg(*seg, *trb)) {
*seg = (*seg)->next;
*trb = ((*seg)->trbs);
} else {
(*trb)++;
}
}
Annotation
- Immediate include surface: `linux/jiffies.h`, `linux/scatterlist.h`, `linux/slab.h`, `linux/string_choices.h`, `linux/dma-mapping.h`, `xhci.h`, `xhci-trace.h`.
- Detected declarations: `function xhci_trb_virt_to_dma`, `function xhci_for_each_ring_seg`, `function trb_is_noop`, `function trb_is_link`, `function last_trb_on_seg`, `function last_trb_on_ring`, `function link_trb_toggles_cycle`, `function last_td_in_urb`, `function unhandled_event_trb`, `function inc_td_cnt`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: integration 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.