static int vp_vdpa_probe()

in virtio_pci/vp_vdpa.c [457:530]


static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct virtio_pci_modern_device *mdev;
	struct device *dev = &pdev->dev;
	struct vp_vdpa *vp_vdpa;
	int ret, i;

	ret = pcim_enable_device(pdev);
	if (ret)
		return ret;

	vp_vdpa = vdpa_alloc_device(struct vp_vdpa, vdpa,
				    dev, &vp_vdpa_ops, NULL, false);
	if (IS_ERR(vp_vdpa)) {
		dev_err(dev, "vp_vdpa: Failed to allocate vDPA structure\n");
		return PTR_ERR(vp_vdpa);
	}

	mdev = &vp_vdpa->mdev;
	mdev->pci_dev = pdev;

	ret = vp_modern_probe(mdev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to probe modern PCI device\n");
		goto err;
	}

	pci_set_master(pdev);
	pci_set_drvdata(pdev, vp_vdpa);

	vp_vdpa->vdpa.dma_dev = &pdev->dev;
	vp_vdpa->queues = vp_modern_get_num_queues(mdev);

	ret = devm_add_action_or_reset(dev, vp_vdpa_free_irq_vectors, pdev);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed for adding devres for freeing irq vectors\n");
		goto err;
	}

	vp_vdpa->vring = devm_kcalloc(&pdev->dev, vp_vdpa->queues,
				      sizeof(*vp_vdpa->vring),
				      GFP_KERNEL);
	if (!vp_vdpa->vring) {
		ret = -ENOMEM;
		dev_err(&pdev->dev, "Fail to allocate virtqueues\n");
		goto err;
	}

	for (i = 0; i < vp_vdpa->queues; i++) {
		vp_vdpa->vring[i].irq = VIRTIO_MSI_NO_VECTOR;
		vp_vdpa->vring[i].notify =
			vp_modern_map_vq_notify(mdev, i,
						&vp_vdpa->vring[i].notify_pa);
		if (!vp_vdpa->vring[i].notify) {
			ret = -EINVAL;
			dev_warn(&pdev->dev, "Fail to map vq notify %d\n", i);
			goto err;
		}
	}
	vp_vdpa->config_irq = VIRTIO_MSI_NO_VECTOR;

	ret = vdpa_register_device(&vp_vdpa->vdpa, vp_vdpa->queues);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register to vdpa bus\n");
		goto err;
	}

	return 0;

err:
	put_device(&vp_vdpa->vdpa.dev);
	return ret;
}