drivers/usb/cdns3/cdnsp-ring.c
Source file repositories/reference/linux-study-clean/drivers/usb/cdns3/cdnsp-ring.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/cdns3/cdnsp-ring.c- Extension
.c- Size
- 69201 bytes
- Lines
- 2505
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/scatterlist.hlinux/dma-mapping.hlinux/delay.hlinux/slab.hlinux/irq.hcdnsp-trace.hcdnsp-gadget.h
Detected Declarations
function cdnsp_trb_virt_to_dmafunction cdnsp_trb_is_noopfunction cdnsp_trb_is_linkfunction cdnsp_last_trb_on_segfunction cdnsp_last_trb_on_ringfunction cdnsp_link_trb_toggles_cyclefunction cdnsp_trb_to_noopfunction cdnsp_next_trbfunction cdnsp_inc_deqfunction clearedfunction cdnsp_room_on_ringfunction cdnsp_force_l0_gofunction cdnsp_ring_cmd_dbfunction cdnsp_ring_ep_doorbellfunction cdnsp_request_to_transfer_ringfunction cdnsp_ring_doorbell_for_active_ringsfunction list_for_each_entry_safefunction cdnsp_get_hw_deqfunction cdnsp_find_new_dequeue_statefunction cdnsp_td_to_noopfunction cdnsp_unmap_td_bounce_bufferfunction cdnsp_cmd_set_deqfunction cdnsp_remove_requestfunction cdnsp_update_port_idfunction cdnsp_handle_port_statusfunction cdnsp_td_cleanupfunction cdnsp_finish_tdfunction cdnsp_sum_trb_lengthsfunction cdnsp_giveback_first_trbfunction cdnsp_process_ctrl_tdfunction cdnsp_process_isoc_tdfunction cdnsp_skip_isoc_tdfunction cdnsp_process_bulk_intr_tdfunction cdnsp_handle_tx_nrdyfunction list_for_each_entry_safefunction cdnsp_handle_tx_eventfunction cdnsp_handle_eventfunction cdnsp_thread_irq_handlerfunction cdnsp_irq_handlerfunction cdnsp_queue_trbfunction cdnsp_prepare_ringfunction cdnsp_prepare_transferfunction cdnsp_count_trbsfunction count_trbs_neededfunction count_sg_trbs_neededfunction for_each_sgfunction cdnsp_check_trb_mathfunction DIV_ROUND_UP
Annotated Snippet
if (!cdnsp_last_trb_on_seg(ring->deq_seg, ring->dequeue)) {
ring->dequeue++;
goto out;
}
if (cdnsp_last_trb_on_ring(ring, ring->deq_seg, ring->dequeue))
ring->cycle_state ^= 1;
ring->deq_seg = ring->deq_seg->next;
ring->dequeue = ring->deq_seg->trbs;
goto out;
}
/* All other rings have link trbs. */
if (!cdnsp_trb_is_link(ring->dequeue)) {
ring->dequeue++;
ring->num_trbs_free++;
}
while (cdnsp_trb_is_link(ring->dequeue)) {
ring->deq_seg = ring->deq_seg->next;
ring->dequeue = ring->deq_seg->trbs;
}
out:
trace_cdnsp_inc_deq(ring);
}
/*
* See Cycle bit rules. SW is the consumer for the event ring only.
* Don't make a ring full of link TRBs. That would be dumb and this would loop.
*
* If we've just enqueued a TRB that is in the middle of a TD (meaning the
* chain bit is set), then set the chain bit in all the following link TRBs.
* If we've enqueued the last TRB in a TD, make sure the following link TRBs
* have their chain bit cleared (so that each Link TRB is a separate TD).
*
* @more_trbs_coming: Will you enqueue more TRBs before ringing the doorbell.
*/
static void cdnsp_inc_enq(struct cdnsp_device *pdev,
struct cdnsp_ring *ring,
bool more_trbs_coming)
{
union cdnsp_trb *next;
u32 chain;
chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN;
/* If this is not event ring, there is one less usable TRB. */
if (!cdnsp_trb_is_link(ring->enqueue))
ring->num_trbs_free--;
next = ++(ring->enqueue);
/* Update the dequeue pointer further if that was a link TRB */
while (cdnsp_trb_is_link(next)) {
/*
* If the caller doesn't plan on enqueuing more TDs before
* ringing the doorbell, then we don't want to give the link TRB
* to the hardware just yet. We'll give the link TRB back in
* cdnsp_prepare_ring() just before we enqueue the TD at the
* top of the ring.
*/
if (!chain && !more_trbs_coming)
break;
next->link.control &= cpu_to_le32(~TRB_CHAIN);
next->link.control |= cpu_to_le32(chain);
/* Give this link TRB to the hardware */
wmb();
next->link.control ^= cpu_to_le32(TRB_CYCLE);
/* Toggle the cycle bit after the last ring segment. */
if (cdnsp_link_trb_toggles_cycle(next))
ring->cycle_state ^= 1;
ring->enq_seg = ring->enq_seg->next;
ring->enqueue = ring->enq_seg->trbs;
next = ring->enqueue;
}
trace_cdnsp_inc_enq(ring);
}
/*
* Check to see if there's room to enqueue num_trbs on the ring and make sure
* enqueue pointer will not advance into dequeue segment.
*/
static bool cdnsp_room_on_ring(struct cdnsp_device *pdev,
struct cdnsp_ring *ring,
unsigned int num_trbs)
{
Annotation
- Immediate include surface: `linux/scatterlist.h`, `linux/dma-mapping.h`, `linux/delay.h`, `linux/slab.h`, `linux/irq.h`, `cdnsp-trace.h`, `cdnsp-gadget.h`.
- Detected declarations: `function cdnsp_trb_virt_to_dma`, `function cdnsp_trb_is_noop`, `function cdnsp_trb_is_link`, `function cdnsp_last_trb_on_seg`, `function cdnsp_last_trb_on_ring`, `function cdnsp_link_trb_toggles_cycle`, `function cdnsp_trb_to_noop`, `function cdnsp_next_trb`, `function cdnsp_inc_deq`, `function cleared`.
- 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.