drivers/misc/bcm-vk/bcm_vk_dev.c

Source file repositories/reference/linux-study-clean/drivers/misc/bcm-vk/bcm_vk_dev.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/bcm-vk/bcm_vk_dev.c
Extension
.c
Size
45198 bytes
Lines
1653
Domain
Driver Families
Bucket
drivers/misc
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations bcm_vk_fops = {
	.owner = THIS_MODULE,
	.open = bcm_vk_open,
	.read = bcm_vk_read,
	.write = bcm_vk_write,
	.poll = bcm_vk_poll,
	.release = bcm_vk_release,
	.mmap = bcm_vk_mmap,
	.unlocked_ioctl = bcm_vk_ioctl,
};

static int bcm_vk_on_panic(struct notifier_block *nb,
			   unsigned long e, void *p)
{
	struct bcm_vk *vk = container_of(nb, struct bcm_vk, panic_nb);

	bcm_to_v_reset_doorbell(vk, VK_BAR0_RESET_DB_HARD);

	return 0;
}

static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	int err;
	int i;
	int id;
	int irq;
	char name[20];
	struct bcm_vk *vk;
	struct device *dev = &pdev->dev;
	struct miscdevice *misc_device;
	u32 boot_status;

	/* allocate vk structure which is tied to kref for freeing */
	vk = kzalloc_obj(*vk);
	if (!vk)
		return -ENOMEM;

	kref_init(&vk->kref);
	if (nr_ib_sgl_blk > BCM_VK_IB_SGL_BLK_MAX) {
		dev_warn(dev, "Inband SGL blk %d limited to max %d\n",
			 nr_ib_sgl_blk, BCM_VK_IB_SGL_BLK_MAX);
		nr_ib_sgl_blk = BCM_VK_IB_SGL_BLK_MAX;
	}
	vk->ib_sgl_size = nr_ib_sgl_blk * VK_MSGQ_BLK_SIZE;
	mutex_init(&vk->mutex);

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(dev, "Cannot enable PCI device\n");
		goto err_free_exit;
	}
	vk->pdev = pci_dev_get(pdev);

	err = pci_request_regions(pdev, DRV_MODULE_NAME);
	if (err) {
		dev_err(dev, "Cannot obtain PCI resources\n");
		goto err_disable_pdev;
	}

	/* make sure DMA is good */
	err = dma_set_mask_and_coherent(&pdev->dev,
					DMA_BIT_MASK(BCM_VK_DMA_BITS));
	if (err) {
		dev_err(dev, "failed to set DMA mask\n");
		goto err_disable_pdev;
	}

	/* The tdma is a scratch area for some DMA testings. */
	if (nr_scratch_pages) {
		vk->tdma_vaddr = dma_alloc_coherent
					(dev,
					 nr_scratch_pages * PAGE_SIZE,
					 &vk->tdma_addr, GFP_KERNEL);
		if (!vk->tdma_vaddr) {
			err = -ENOMEM;
			goto err_disable_pdev;
		}
	}

	pci_set_master(pdev);
	pci_set_drvdata(pdev, vk);

	irq = pci_alloc_irq_vectors(pdev,
				    VK_MSIX_IRQ_MIN_REQ,
				    VK_MSIX_IRQ_MAX,
				    PCI_IRQ_MSI | PCI_IRQ_MSIX);

	if (irq < VK_MSIX_IRQ_MIN_REQ) {
		dev_err(dev, "failed to get min %d MSIX interrupts, irq(%d)\n",

Annotation

Implementation Notes