drivers/infiniband/hw/cxgb4/provider.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/cxgb4/provider.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/cxgb4/provider.c
Extension
.c
Size
16420 bytes
Lines
574
Domain
Driver Families
Bucket
drivers/infiniband
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!mm) {
			ret = -ENOMEM;
			goto err;
		}

		uresp.status_page_size = PAGE_SIZE;

		spin_lock(&context->mmap_lock);
		uresp.status_page_key = context->key;
		context->key += PAGE_SIZE;
		spin_unlock(&context->mmap_lock);

		ret = ib_respond_udata(udata, uresp);
		if (ret)
			goto err_mm;

		mm->key = uresp.status_page_key;
		mm->addr = virt_to_phys(rhp->rdev.status_page);
		mm->len = PAGE_SIZE;
		mm->vaddr = NULL;
		mm->dma_addr = 0;
		insert_flag_to_mmap(&rhp->rdev, mm, mm->addr);
		insert_mmap(context, mm);
	}
	return 0;
err_mm:
	kfree(mm);
err:
	return ret;
}

static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
{
	int len = vma->vm_end - vma->vm_start;
	u32 key = vma->vm_pgoff << PAGE_SHIFT;
	struct c4iw_rdev *rdev;
	int ret = 0;
	struct c4iw_mm_entry *mm;
	struct c4iw_ucontext *ucontext;
	u64 addr;
	u8 mmap_flag;
	size_t size;
	void *vaddr;
	unsigned long vm_pgoff;
	dma_addr_t dma_addr;

	pr_debug("pgoff 0x%lx key 0x%x len %d\n", vma->vm_pgoff,
		 key, len);

	if (vma->vm_start & (PAGE_SIZE-1))
		return -EINVAL;

	rdev = &(to_c4iw_dev(context->device)->rdev);
	ucontext = to_c4iw_ucontext(context);

	mm = remove_mmap(ucontext, key, len);
	if (!mm)
		return -EINVAL;
	addr = mm->addr;
	vaddr = mm->vaddr;
	dma_addr = mm->dma_addr;
	size = mm->len;
	mmap_flag = mm->mmap_flag;
	kfree(mm);

	switch (mmap_flag) {
	case CXGB4_MMAP_BAR:
		ret = io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
					 len,
					 pgprot_noncached(vma->vm_page_prot));
		break;
	case CXGB4_MMAP_BAR_WC:
		ret = io_remap_pfn_range(vma, vma->vm_start,
					 addr >> PAGE_SHIFT,
					 len, t4_pgprot_wc(vma->vm_page_prot));
		break;
	case CXGB4_MMAP_CONTIG:
		ret = io_remap_pfn_range(vma, vma->vm_start,
					 addr >> PAGE_SHIFT,
					 len, vma->vm_page_prot);
		break;
	case CXGB4_MMAP_NON_CONTIG:
		vm_pgoff = vma->vm_pgoff;
		vma->vm_pgoff = 0;
		ret = dma_mmap_coherent(&rdev->lldi.pdev->dev, vma,
					vaddr, dma_addr, size);
		vma->vm_pgoff = vm_pgoff;
		break;
	default:
		ret = -EINVAL;

Annotation

Implementation Notes