diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2005-11-20 00:56:31 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2005-11-20 00:56:31 -0500 |
commit | bd0ef2356cd85d39387be36fdf1f83a40075057f (patch) | |
tree | 590c7a005823ecc6836ee17a47fd9b43fcb6e85a /drivers/input | |
parent | e597f0c80de7e2ef840b28d111ec532988abc432 (diff) | |
download | op-kernel-dev-bd0ef2356cd85d39387be36fdf1f83a40075057f.zip op-kernel-dev-bd0ef2356cd85d39387be36fdf1f83a40075057f.tar.gz |
Input: handle failures in input_register_device()
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/input.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index c8ae2bb..bdd2a7f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -536,7 +536,7 @@ static struct attribute *input_dev_attrs[] = { NULL }; -static struct attribute_group input_dev_group = { +static struct attribute_group input_dev_attr_group = { .attrs = input_dev_attrs, }; @@ -717,35 +717,14 @@ struct input_dev *input_allocate_device(void) return dev; } -static void input_register_classdevice(struct input_dev *dev) -{ - static atomic_t input_no = ATOMIC_INIT(0); - const char *path; - - __module_get(THIS_MODULE); - - dev->dev = dev->cdev.dev; - - snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), - "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); - - path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL); - printk(KERN_INFO "input: %s as %s/%s\n", - dev->name ? dev->name : "Unspecified device", - path ? path : "", dev->cdev.class_id); - kfree(path); - - class_device_add(&dev->cdev); - sysfs_create_group(&dev->cdev.kobj, &input_dev_group); - sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); - sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); -} - int input_register_device(struct input_dev *dev) { + static atomic_t input_no = ATOMIC_INIT(0); struct input_handle *handle; struct input_handler *handler; struct input_device_id *id; + const char *path; + int error; if (!dev->dynalloc) { printk(KERN_WARNING "input: device %s is statically allocated, will not register\n" @@ -773,7 +752,32 @@ int input_register_device(struct input_dev *dev) INIT_LIST_HEAD(&dev->h_list); list_add_tail(&dev->node, &input_dev_list); - input_register_classdevice(dev); + dev->cdev.class = &input_class; + snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), + "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); + + error = class_device_add(&dev->cdev); + if (error) + return error; + + error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group); + if (error) + goto fail1; + + error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); + if (error) + goto fail2; + + error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); + if (error) + goto fail3; + + __module_get(THIS_MODULE); + + path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); + printk(KERN_INFO "input: %s as %s\n", + dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); + kfree(path); list_for_each_entry(handler, &input_handler_list, node) if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) @@ -784,6 +788,11 @@ int input_register_device(struct input_dev *dev) input_wakeup_procfs_readers(); return 0; + + fail3: sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); + fail2: sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); + fail1: class_device_del(&dev->cdev); + return error; } void input_unregister_device(struct input_dev *dev) @@ -805,7 +814,7 @@ void input_unregister_device(struct input_dev *dev) sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); - sysfs_remove_group(&dev->cdev.kobj, &input_dev_group); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); class_device_unregister(&dev->cdev); input_wakeup_procfs_readers(); |