Example #1
0
File: uio.c Project: 3null/linux
/**
 * uio_register_device - register a new userspace IO device
 * @owner:	module that creates the new device
 * @parent:	parent device
 * @info:	UIO device capabilities
 *
 * returns zero on success or a negative error code.
 */
int __uio_register_device(struct module *owner,
			  struct device *parent,
			  struct uio_info *info)
{
	struct uio_device *idev;
	int ret = 0;

	if (!parent || !info || !info->name || !info->version)
		return -EINVAL;

	info->uio_dev = NULL;

	idev = devm_kzalloc(parent, sizeof(*idev), GFP_KERNEL);
	if (!idev) {
		return -ENOMEM;
	}

	idev->owner = owner;
	idev->info = info;
	init_waitqueue_head(&idev->wait);
	atomic_set(&idev->event, 0);

	ret = uio_get_minor(idev);
	if (ret)
		return ret;

	idev->dev = device_create(&uio_class, parent,
				  MKDEV(uio_major, idev->minor), idev,
				  "uio%d", idev->minor);
	if (IS_ERR(idev->dev)) {
		printk(KERN_ERR "UIO: device register failed\n");
		ret = PTR_ERR(idev->dev);
		goto err_device_create;
	}

	ret = uio_dev_add_attributes(idev);
	if (ret)
		goto err_uio_dev_add_attributes;

	info->uio_dev = idev;

	if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
		ret = devm_request_irq(idev->dev, info->irq, uio_interrupt,
				  info->irq_flags, info->name, idev);
		if (ret)
			goto err_request_irq;
	}

	return 0;

err_request_irq:
	uio_dev_del_attributes(idev);
err_uio_dev_add_attributes:
	device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
err_device_create:
	uio_free_minor(idev);
	return ret;
}
Example #2
0
/**
 * uio_register_device - register a new userspace IO device
 * @owner:	module that creates the new device
 * @parent:	parent device
 * @info:	UIO device capabilities
 *
 * returns zero on success or a negative error code.
 */
int __uio_register_device(struct module *owner,
                          struct device *parent,
                          struct uio_info *info)
{
    struct uio_device *idev;
    int ret = 0;

    if (!parent || !info || !info->name || !info->version)
        return -EINVAL;

    info->uio_dev = NULL;

    idev = devm_kzalloc(parent, sizeof(*idev), GFP_KERNEL);
    if (!idev) {
        return -ENOMEM;
    }

    idev->owner = owner;
    idev->info = info;
    init_waitqueue_head(&idev->wait);
    atomic_set(&idev->event, 0);

    ret = uio_get_minor(idev);
    if (ret)
        return ret;

    idev->dev = device_create(&uio_class, parent,
                              MKDEV(uio_major, idev->minor), idev,
                              "uio%d", idev->minor);
    if (IS_ERR(idev->dev)) {
        printk(KERN_ERR "UIO: device register failed\n");
        ret = PTR_ERR(idev->dev);
        goto err_device_create;
    }

    ret = uio_dev_add_attributes(idev);
    if (ret)
        goto err_uio_dev_add_attributes;

    info->uio_dev = idev;

    if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
        /*
         * Note that we deliberately don't use devm_request_irq
         * here. The parent module can unregister the UIO device
         * and call pci_disable_msi, which requires that this
         * irq has been freed. However, the device may have open
         * FDs at the time of unregister and therefore may not be
         * freed until they are released.
         */
        ret = request_irq(info->irq, uio_interrupt,
                          info->irq_flags, info->name, idev);
        if (ret)
            goto err_request_irq;
    }

    return 0;

err_request_irq:
    uio_dev_del_attributes(idev);
err_uio_dev_add_attributes:
    device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
err_device_create:
    uio_free_minor(idev);
    return ret;
}