static int ifcvf_vdpa_dev_add()

in ifcvf/ifcvf_main.c [493:550]


static int ifcvf_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
			      const struct vdpa_dev_set_config *config)
{
	struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev;
	struct ifcvf_adapter *adapter;
	struct pci_dev *pdev;
	struct ifcvf_hw *vf;
	struct device *dev;
	int ret, i;

	ifcvf_mgmt_dev = container_of(mdev, struct ifcvf_vdpa_mgmt_dev, mdev);
	if (ifcvf_mgmt_dev->adapter)
		return -EOPNOTSUPP;

	pdev = ifcvf_mgmt_dev->pdev;
	dev = &pdev->dev;
	adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa,
				    dev, &ifc_vdpa_ops, name, false);
	if (IS_ERR(adapter)) {
		IFCVF_ERR(pdev, "Failed to allocate vDPA structure");
		return PTR_ERR(adapter);
	}

	ifcvf_mgmt_dev->adapter = adapter;
	pci_set_drvdata(pdev, ifcvf_mgmt_dev);

	vf = &adapter->vf;
	vf->dev_type = get_dev_type(pdev);
	vf->base = pcim_iomap_table(pdev);

	adapter->pdev = pdev;
	adapter->vdpa.dma_dev = &pdev->dev;

	ret = ifcvf_init_hw(vf, pdev);
	if (ret) {
		IFCVF_ERR(pdev, "Failed to init IFCVF hw\n");
		goto err;
	}

	for (i = 0; i < vf->nr_vring; i++)
		vf->vring[i].irq = -EINVAL;

	vf->hw_features = ifcvf_get_hw_features(vf);
	vf->config_size = ifcvf_get_config_size(vf);

	adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev;
	ret = _vdpa_register_device(&adapter->vdpa, vf->nr_vring);
	if (ret) {
		IFCVF_ERR(pdev, "Failed to register to vDPA bus");
		goto err;
	}

	return 0;

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