drivers/usb/gadget/udc/bdc/bdc_ep.c
Source file repositories/reference/linux-study-clean/drivers/usb/gadget/udc/bdc/bdc_ep.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/gadget/udc/bdc/bdc_ep.c- Extension
.c- Size
- 50851 bytes
- Lines
- 2039
- 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.
- 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/pci.hlinux/dma-mapping.hlinux/kernel.hlinux/delay.hlinux/dmapool.hlinux/ioport.hlinux/sched.hlinux/slab.hlinux/errno.hlinux/init.hlinux/timer.hlinux/list.hlinux/interrupt.hlinux/moduleparam.hlinux/device.hlinux/usb/ch9.hlinux/usb/gadget.hlinux/usb/otg.hlinux/pm.hlinux/io.hlinux/irq.hlinux/unaligned.hlinux/platform_device.hlinux/usb/composite.hbdc.hbdc_ep.hbdc_cmd.hbdc_dbg.h
Detected Declarations
function ep_bd_list_freefunction chain_tablefunction ep_bd_list_allocfunction bd_needed_reqfunction bd_add_to_bdifunction bdi_to_tbifunction find_end_bdifunction bd_available_epfunction bdc_notify_xfrfunction ep_bdlist_eqp_advfunction setup_first_bd_ep0function setup_bd_list_xfrfunction bdc_queue_xfrfunction bdc_req_completefunction bdc_ep_disablefunction bdc_ep_enablefunction ep0_queue_status_stagefunction ep0_queuefunction ep0_queue_data_stagefunction ep_queuefunction ep_dequeuefunction ep_set_haltfunction bdc_free_epfunction bdc_set_test_modefunction handle_xsr_succ_statusfunction bdc_xsf_ep0_setup_recvfunction ep0_stallfunction ep0_set_addressfunction ep0_handle_feature_devfunction ep0_handle_featurefunction ep0_handle_statusfunction ep0_set_sel_cmplfunction ep0_queue_zlpfunction handle_control_requestfunction bdc_xsf_ep0_data_startfunction bdc_xsf_ep0_status_startfunction ep0_xsf_completefunction bdc_sr_xsffunction bdc_gadget_ep_queuefunction bdc_gadget_ep_dequeuefunction bdc_gadget_ep_set_haltfunction bdc_gadget_free_requestfunction bdc_gadget_ep_enablefunction bdc_gadget_ep_disablefunction init_epfunction bdc_init_ep
Annotated Snippet
if (!bd_table) {
dev_dbg(bdc->dev, "bd_table not allocated\n");
continue;
}
if (!bd_table->start_bd) {
dev_dbg(bdc->dev, "bd dma pool not allocated\n");
continue;
}
dev_dbg(bdc->dev,
"Free dma pool start_bd:%p dma:%llx\n",
bd_table->start_bd,
(unsigned long long)bd_table->dma);
dma_pool_free(bdc->bd_table_pool,
bd_table->start_bd,
bd_table->dma);
/* Free the bd_table structure */
kfree(bd_table);
}
/* Free the bd table array */
kfree(ep->bd_list.bd_table_array);
}
/*
* chain the tables, by insteting a chain bd at the end of prev_table, pointing
* to next_table
*/
static inline void chain_table(struct bd_table *prev_table,
struct bd_table *next_table,
u32 bd_p_tab)
{
/* Chain the prev table to next table */
prev_table->start_bd[bd_p_tab-1].offset[0] =
cpu_to_le32(lower_32_bits(next_table->dma));
prev_table->start_bd[bd_p_tab-1].offset[1] =
cpu_to_le32(upper_32_bits(next_table->dma));
prev_table->start_bd[bd_p_tab-1].offset[2] =
0x0;
prev_table->start_bd[bd_p_tab-1].offset[3] =
cpu_to_le32(MARK_CHAIN_BD);
}
/* Allocate the bdl for ep, during config ep */
static int ep_bd_list_alloc(struct bdc_ep *ep)
{
struct bd_table *prev_table = NULL;
int index, num_tabs, bd_p_tab;
struct bdc *bdc = ep->bdc;
struct bd_table *bd_table;
dma_addr_t dma;
if (usb_endpoint_xfer_isoc(ep->desc))
num_tabs = NUM_TABLES_ISOCH;
else
num_tabs = NUM_TABLES;
bd_p_tab = NUM_BDS_PER_TABLE;
/* if there is only 1 table in bd list then loop chain to self */
dev_dbg(bdc->dev,
"%s ep:%p num_tabs:%d\n",
__func__, ep, num_tabs);
/* Allocate memory for table array */
ep->bd_list.bd_table_array = kzalloc_objs(struct bd_table *, num_tabs,
GFP_ATOMIC);
if (!ep->bd_list.bd_table_array)
return -ENOMEM;
/* Allocate memory for each table */
for (index = 0; index < num_tabs; index++) {
/* Allocate memory for bd_table structure */
bd_table = kzalloc_obj(*bd_table, GFP_ATOMIC);
if (!bd_table)
goto fail;
bd_table->start_bd = dma_pool_zalloc(bdc->bd_table_pool,
GFP_ATOMIC,
&dma);
if (!bd_table->start_bd) {
kfree(bd_table);
goto fail;
}
bd_table->dma = dma;
dev_dbg(bdc->dev,
Annotation
- Immediate include surface: `linux/module.h`, `linux/pci.h`, `linux/dma-mapping.h`, `linux/kernel.h`, `linux/delay.h`, `linux/dmapool.h`, `linux/ioport.h`, `linux/sched.h`.
- Detected declarations: `function ep_bd_list_free`, `function chain_table`, `function ep_bd_list_alloc`, `function bd_needed_req`, `function bd_add_to_bdi`, `function bdi_to_tbi`, `function find_end_bdi`, `function bd_available_ep`, `function bdc_notify_xfr`, `function ep_bdlist_eqp_adv`.
- 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.
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.