drivers/usb/cdns3/cdnsp-mem.c
Source file repositories/reference/linux-study-clean/drivers/usb/cdns3/cdnsp-mem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/cdns3/cdnsp-mem.c- Extension
.c- Size
- 36313 bytes
- Lines
- 1337
- 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.
- 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/dma-mapping.hlinux/dmapool.hlinux/slab.hlinux/usb.hcdnsp-gadget.hcdnsp-trace.h
Detected Declarations
function cdnsp_segment_freefunction cdnsp_free_segments_for_ringfunction cdnsp_link_segmentsfunction cdnsp_link_ringsfunction systemsfunction cdnsp_remove_segment_mappingfunction cdnsp_update_stream_segment_mappingfunction cdnsp_remove_stream_mappingfunction cdnsp_update_stream_mappingfunction cdnsp_ring_freefunction cdnsp_initialize_ring_infofunction cdnsp_alloc_segments_for_ringfunction cdnsp_free_endpoint_ringsfunction cdnsp_ring_expansionfunction cdnsp_init_device_ctxfunction cdnsp_free_stream_ctxfunction cdnsp_alloc_stream_infofunction cdnsp_free_stream_infofunction cdnsp_free_priv_devicefunction cdnsp_alloc_priv_devicefunction cdnsp_copy_ep0_dequeue_into_input_ctxfunction cdnsp_setup_addressable_priv_devfunction cdnsp_parse_exponent_intervalfunction microframesfunction cdnsp_get_endpoint_intervalfunction cdnsp_get_endpoint_multfunction cdnsp_get_endpoint_max_burstfunction cdnsp_get_endpoint_typefunction timefunction cdnsp_endpoint_initfunction cdnsp_endpoint_zerofunction cdnsp_alloc_erstfunction cdnsp_free_erstfunction cdnsp_mem_cleanupfunction cdnsp_set_event_deqfunction cdnsp_add_in_portfunction cdnsp_setup_port_arraysfunction CDNSP
Annotated Snippet
if (!next) {
cdnsp_free_segments_for_ring(pdev, *first);
return -ENOMEM;
}
cdnsp_link_segments(pdev, prev, next, type);
prev = next;
num_segs--;
}
cdnsp_link_segments(pdev, prev, *first, type);
*last = prev;
return 0;
}
/*
* Create a new ring with zero or more segments.
*
* Link each segment together into a ring.
* Set the end flag and the cycle toggle bit on the last segment.
*/
static struct cdnsp_ring *cdnsp_ring_alloc(struct cdnsp_device *pdev,
unsigned int num_segs,
enum cdnsp_ring_type type,
unsigned int max_packet,
gfp_t flags)
{
struct cdnsp_ring *ring;
int ret;
ring = kzalloc_obj(*(ring), flags);
if (!ring)
return NULL;
ring->num_segs = num_segs;
ring->bounce_buf_len = max_packet;
INIT_LIST_HEAD(&ring->td_list);
ring->type = type;
if (num_segs == 0)
return ring;
ret = cdnsp_alloc_segments_for_ring(pdev, &ring->first_seg,
&ring->last_seg, num_segs,
1, type, max_packet, flags);
if (ret)
goto fail;
/* Only event ring does not use link TRB. */
if (type != TYPE_EVENT)
ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |=
cpu_to_le32(LINK_TOGGLE);
cdnsp_initialize_ring_info(ring);
trace_cdnsp_ring_alloc(ring);
return ring;
fail:
kfree(ring);
return NULL;
}
void cdnsp_free_endpoint_rings(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
{
cdnsp_ring_free(pdev, pep->ring);
pep->ring = NULL;
cdnsp_free_stream_info(pdev, pep);
}
/*
* Expand an existing ring.
* Allocate a new ring which has same segment numbers and link the two rings.
*/
int cdnsp_ring_expansion(struct cdnsp_device *pdev,
struct cdnsp_ring *ring,
unsigned int num_trbs,
gfp_t flags)
{
unsigned int num_segs_needed;
struct cdnsp_segment *first;
struct cdnsp_segment *last;
unsigned int num_segs;
int ret;
num_segs_needed = (num_trbs + (TRBS_PER_SEGMENT - 1) - 1) /
(TRBS_PER_SEGMENT - 1);
/* Allocate number of segments we needed, or double the ring size. */
num_segs = max(ring->num_segs, num_segs_needed);
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/dmapool.h`, `linux/slab.h`, `linux/usb.h`, `cdnsp-gadget.h`, `cdnsp-trace.h`.
- Detected declarations: `function cdnsp_segment_free`, `function cdnsp_free_segments_for_ring`, `function cdnsp_link_segments`, `function cdnsp_link_rings`, `function systems`, `function cdnsp_remove_segment_mapping`, `function cdnsp_update_stream_segment_mapping`, `function cdnsp_remove_stream_mapping`, `function cdnsp_update_stream_mapping`, `function cdnsp_ring_free`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- 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.