in vdpa_user/vduse_dev.c [1588:1656]
static int vduse_init(void)
{
int ret;
struct device *dev;
vduse_class = class_create(THIS_MODULE, "vduse");
if (IS_ERR(vduse_class))
return PTR_ERR(vduse_class);
vduse_class->devnode = vduse_devnode;
vduse_class->dev_groups = vduse_dev_groups;
ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse");
if (ret)
goto err_chardev_region;
/* /dev/vduse/control */
cdev_init(&vduse_ctrl_cdev, &vduse_ctrl_fops);
vduse_ctrl_cdev.owner = THIS_MODULE;
ret = cdev_add(&vduse_ctrl_cdev, vduse_major, 1);
if (ret)
goto err_ctrl_cdev;
dev = device_create(vduse_class, NULL, vduse_major, NULL, "control");
if (IS_ERR(dev)) {
ret = PTR_ERR(dev);
goto err_device;
}
/* /dev/vduse/$DEVICE */
cdev_init(&vduse_cdev, &vduse_dev_fops);
vduse_cdev.owner = THIS_MODULE;
ret = cdev_add(&vduse_cdev, MKDEV(MAJOR(vduse_major), 1),
VDUSE_DEV_MAX - 1);
if (ret)
goto err_cdev;
vduse_irq_wq = alloc_workqueue("vduse-irq",
WQ_HIGHPRI | WQ_SYSFS | WQ_UNBOUND, 0);
if (!vduse_irq_wq) {
ret = -ENOMEM;
goto err_wq;
}
ret = vduse_domain_init();
if (ret)
goto err_domain;
ret = vduse_mgmtdev_init();
if (ret)
goto err_mgmtdev;
return 0;
err_mgmtdev:
vduse_domain_exit();
err_domain:
destroy_workqueue(vduse_irq_wq);
err_wq:
cdev_del(&vduse_cdev);
err_cdev:
device_destroy(vduse_class, vduse_major);
err_device:
cdev_del(&vduse_ctrl_cdev);
err_ctrl_cdev:
unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
err_chardev_region:
class_destroy(vduse_class);
return ret;
}