drivers/net/ethernet/qlogic/qed/qed_chain.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qlogic/qed/qed_chain.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/qlogic/qed/qed_chain.c- Extension
.c- Size
- 8659 bytes
- Lines
- 372
- Domain
- Driver Families
- Bucket
- drivers/net
- 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/qed/qed_chain.hlinux/vmalloc.hqed_dev_api.h
Detected Declarations
function qed_chain_initfunction qed_chain_init_next_ptr_elemfunction qed_chain_init_memfunction qed_chain_free_next_ptrfunction qed_chain_free_singlefunction qed_chain_free_pblfunction qed_chain_freefunction qed_chain_alloc_sanity_checkfunction elementsfunction qed_chain_alloc_next_ptrfunction qed_chain_alloc_singlefunction qed_chain_alloc_pblfunction qed_chain_alloc
Annotated Snippet
if (i == 0) {
qed_chain_init_mem(chain, virt, phys);
qed_chain_reset(chain);
} else {
qed_chain_init_next_ptr_elem(chain, virt_prev, virt,
phys);
}
virt_prev = virt;
}
/* Last page's next element should point to the beginning of the
* chain.
*/
qed_chain_init_next_ptr_elem(chain, virt_prev, chain->p_virt_addr,
chain->p_phys_addr);
return 0;
}
static int qed_chain_alloc_single(struct qed_dev *cdev,
struct qed_chain *chain)
{
dma_addr_t phys;
void *virt;
virt = dma_alloc_coherent(&cdev->pdev->dev, chain->page_size,
&phys, GFP_KERNEL);
if (!virt)
return -ENOMEM;
qed_chain_init_mem(chain, virt, phys);
qed_chain_reset(chain);
return 0;
}
static int qed_chain_alloc_pbl(struct qed_dev *cdev, struct qed_chain *chain)
{
struct device *dev = &cdev->pdev->dev;
struct addr_tbl_entry *addr_tbl;
dma_addr_t phys, pbl_phys;
__le64 *pbl_virt;
u32 page_cnt, i;
size_t size;
void *virt;
page_cnt = chain->page_cnt;
size = array_size(page_cnt, sizeof(*addr_tbl));
if (unlikely(size == SIZE_MAX))
return -EOVERFLOW;
addr_tbl = vzalloc(size);
if (!addr_tbl)
return -ENOMEM;
chain->pbl.pp_addr_tbl = addr_tbl;
if (chain->b_external_pbl) {
pbl_virt = chain->pbl_sp.table_virt;
goto alloc_pages;
}
size = array_size(page_cnt, sizeof(*pbl_virt));
if (unlikely(size == SIZE_MAX))
return -EOVERFLOW;
pbl_virt = dma_alloc_coherent(dev, size, &pbl_phys, GFP_KERNEL);
if (!pbl_virt)
return -ENOMEM;
chain->pbl_sp.table_virt = pbl_virt;
chain->pbl_sp.table_phys = pbl_phys;
chain->pbl_sp.table_size = size;
alloc_pages:
for (i = 0; i < page_cnt; i++) {
virt = dma_alloc_coherent(dev, chain->page_size, &phys,
GFP_KERNEL);
if (!virt)
return -ENOMEM;
if (i == 0) {
qed_chain_init_mem(chain, virt, phys);
qed_chain_reset(chain);
}
/* Fill the PBL table with the physical address of the page */
pbl_virt[i] = cpu_to_le64(phys);
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/qed/qed_chain.h`, `linux/vmalloc.h`, `qed_dev_api.h`.
- Detected declarations: `function qed_chain_init`, `function qed_chain_init_next_ptr_elem`, `function qed_chain_init_mem`, `function qed_chain_free_next_ptr`, `function qed_chain_free_single`, `function qed_chain_free_pbl`, `function qed_chain_free`, `function qed_chain_alloc_sanity_check`, `function elements`, `function qed_chain_alloc_next_ptr`.
- Atlas domain: Driver Families / drivers/net.
- 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.