参照元†
返り値†
/**
* 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;
ret = init_uio_class();
if (ret)
return ret;
idev = kzalloc(sizeof(*idev), GFP_KERNEL);
if (!idev) {
ret = -ENOMEM;
goto err_kzalloc;
}
idev->owner = owner;
idev->info = info;
init_waitqueue_head(&idev->wait);
atomic_set(&idev->event, 0);
ret = uio_get_minor(idev);
if (ret)
goto err_get_minor;
idev->dev = device_create(uio_class->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 (idev->info->irq >= 0) {
ret = request_irq(idev->info->irq, uio_interrupt,
idev->info->irq_flags, idev->info->name, idev);
if (ret)
goto err_request_irq;
}
- ユーザ定義のデバイスが割り込みを使用するならば、
カーネルにハンドラを登録する。
- ただしユーザ定義のハンドラを直接登録するのではなく、
いったん uio_interrupt() を登録し、
uio_interrupt() 経由でユーザ定義のハンドラを呼び出す。
return 0;
err_request_irq:
uio_dev_del_attributes(idev);
err_uio_dev_add_attributes:
device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
err_device_create:
uio_free_minor(idev);
err_get_minor:
kfree(idev);
err_kzalloc:
uio_class_destroy();
return ret;
}
EXPORT_SYMBOL_GPL(__uio_register_device);
コメント†