drivers/misc/genwqe/card_utils.c
Source file repositories/reference/linux-study-clean/drivers/misc/genwqe/card_utils.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/genwqe/card_utils.c- Extension
.c- Size
- 27792 bytes
- Lines
- 1050
- Domain
- Driver Families
- Bucket
- drivers/misc
- 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 user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/kernel.hlinux/sched.hlinux/vmalloc.hlinux/page-flags.hlinux/scatterlist.hlinux/hugetlb.hlinux/iommu.hlinux/pci.hlinux/dma-mapping.hlinux/ctype.hlinux/module.hlinux/platform_device.hlinux/delay.hlinux/pgtable.hgenwqe_driver.hcard_base.hcard_ddcb.h
Detected Declarations
function __genwqe_writeqfunction __genwqe_readqfunction __genwqe_writelfunction __genwqe_readlfunction genwqe_read_app_idfunction genwqe_init_crc32function genwqe_crc32function __genwqe_free_consistentfunction genwqe_unmap_pagesfunction genwqe_map_pagesfunction genwqe_sgl_sizefunction genwqe_alloc_sync_sglfunction genwqe_setup_sglfunction genwqe_free_sync_sglfunction genwqe_user_vmapfunction genwqe_user_vunmapfunction genwqe_card_typefunction genwqe_card_resetfunction genwqe_read_softresetfunction genwqe_set_interrupt_capabilityfunction genwqe_reset_interrupt_capabilityfunction set_reg_idxfunction set_regfunction genwqe_read_ffdc_regsfunction genwqe_ffdc_buff_sizefunction genwqe_ffdc_buff_readfunction genwqe_write_vregfunction genwqe_read_vregfunction genwqe_base_clock_frequencyfunction genwqe_stop_trapsfunction genwqe_start_traps
Annotated Snippet
if (dma_mapping_error(&pci_dev->dev, daddr)) {
dev_err(&pci_dev->dev,
"[%s] err: no dma addr daddr=%016llx!\n",
__func__, (long long)daddr);
goto err;
}
dma_list[i] = daddr;
}
return 0;
err:
genwqe_unmap_pages(cd, dma_list, num_pages);
return -EIO;
}
static int genwqe_sgl_size(int num_pages)
{
int len, num_tlb = num_pages / 7;
len = sizeof(struct sg_entry) * (num_pages+num_tlb + 1);
return roundup(len, PAGE_SIZE);
}
/*
* genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages
*
* Allocates memory for sgl and overlapping pages. Pages which might
* overlap other user-space memory blocks are being cached for DMAs,
* such that we do not run into syncronization issues. Data is copied
* from user-space into the cached pages.
*/
int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
void __user *user_addr, size_t user_size, int write)
{
int ret = -ENOMEM;
struct pci_dev *pci_dev = cd->pci_dev;
sgl->fpage_offs = offset_in_page((unsigned long)user_addr);
sgl->fpage_size = min_t(size_t, PAGE_SIZE-sgl->fpage_offs, user_size);
sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE);
sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE;
dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n",
__func__, user_addr, user_size, sgl->nr_pages,
sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size);
sgl->user_addr = user_addr;
sgl->user_size = user_size;
sgl->write = write;
sgl->sgl_size = genwqe_sgl_size(sgl->nr_pages);
if (get_order(sgl->sgl_size) > MAX_PAGE_ORDER) {
dev_err(&pci_dev->dev,
"[%s] err: too much memory requested!\n", __func__);
return ret;
}
sgl->sgl = __genwqe_alloc_consistent(cd, sgl->sgl_size,
&sgl->sgl_dma_addr);
if (sgl->sgl == NULL) {
dev_err(&pci_dev->dev,
"[%s] err: no memory available!\n", __func__);
return ret;
}
/* Only use buffering on incomplete pages */
if ((sgl->fpage_size != 0) && (sgl->fpage_size != PAGE_SIZE)) {
sgl->fpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
&sgl->fpage_dma_addr);
if (sgl->fpage == NULL)
goto err_out;
/* Sync with user memory */
if (copy_from_user(sgl->fpage + sgl->fpage_offs,
user_addr, sgl->fpage_size)) {
ret = -EFAULT;
goto err_out;
}
}
if (sgl->lpage_size != 0) {
sgl->lpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
&sgl->lpage_dma_addr);
if (sgl->lpage == NULL)
goto err_out1;
/* Sync with user memory */
if (copy_from_user(sgl->lpage, user_addr + user_size -
sgl->lpage_size, sgl->lpage_size)) {
ret = -EFAULT;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched.h`, `linux/vmalloc.h`, `linux/page-flags.h`, `linux/scatterlist.h`, `linux/hugetlb.h`, `linux/iommu.h`, `linux/pci.h`.
- Detected declarations: `function __genwqe_writeq`, `function __genwqe_readq`, `function __genwqe_writel`, `function __genwqe_readl`, `function genwqe_read_app_id`, `function genwqe_init_crc32`, `function genwqe_crc32`, `function __genwqe_free_consistent`, `function genwqe_unmap_pages`, `function genwqe_map_pages`.
- Atlas domain: Driver Families / drivers/misc.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.