int mlx5_vdpa_alloc_resources()

in mlx5/core/resources.c [246:305]


int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
{
	u64 offset = MLX5_CAP64_DEV_VDPA_EMULATION(mvdev->mdev, doorbell_bar_offset);
	struct mlx5_vdpa_resources *res = &mvdev->res;
	struct mlx5_core_dev *mdev = mvdev->mdev;
	u64 kick_addr;
	int err;

	if (res->valid) {
		mlx5_vdpa_warn(mvdev, "resources already allocated\n");
		return -EINVAL;
	}
	mutex_init(&mvdev->mr.mkey_mtx);
	res->uar = mlx5_get_uars_page(mdev);
	if (IS_ERR(res->uar)) {
		err = PTR_ERR(res->uar);
		goto err_uars;
	}

	err = create_uctx(mvdev, &res->uid);
	if (err)
		goto err_uctx;

	err = alloc_pd(mvdev, &res->pdn, res->uid);
	if (err)
		goto err_pd;

	err = get_null_mkey(mvdev, &res->null_mkey);
	if (err)
		goto err_key;

	kick_addr = mdev->bar_addr + offset;
	res->phys_kick_addr = kick_addr;

	res->kick_addr = ioremap(kick_addr, PAGE_SIZE);
	if (!res->kick_addr) {
		err = -ENOMEM;
		goto err_key;
	}

	err = init_ctrl_vq(mvdev);
	if (err)
		goto err_ctrl;

	res->valid = true;

	return 0;

err_ctrl:
	iounmap(res->kick_addr);
err_key:
	dealloc_pd(mvdev, res->pdn, res->uid);
err_pd:
	destroy_uctx(mvdev, res->uid);
err_uctx:
	mlx5_put_uars_page(mdev, res->uar);
err_uars:
	mutex_destroy(&mvdev->mr.mkey_mtx);
	return err;
}