aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/input.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2006-06-26 01:48:36 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2006-06-26 01:48:36 -0400
commitf60d2b111cd55c335c2b70e50d66a612d2b10856 (patch)
tree95ec2063e270ad8f87ab07d507d4c20affacb2a5 /drivers/input/input.c
parent8a3cf456adbde8317a15fc038cfe82c630512f2e (diff)
Input: reset name, phys and uniq when unregistering
Name, phys and uniq are quite often constant strings in moules implementing particular input device. If a module unregisters input device and then gets unloaded, the device could still be present in memory (pinned via sysfs), but aforementioned members would point to some random memory. Set them all to NULL when unregistering so sysfs handlers won't try dereferencing them. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index b149c9434849..d3cdb139e962 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -29,6 +29,7 @@ MODULE_DESCRIPTION("Input core");
29MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
30 30
31EXPORT_SYMBOL(input_allocate_device); 31EXPORT_SYMBOL(input_allocate_device);
32EXPORT_SYMBOL(input_free_device);
32EXPORT_SYMBOL(input_register_device); 33EXPORT_SYMBOL(input_register_device);
33EXPORT_SYMBOL(input_unregister_device); 34EXPORT_SYMBOL(input_unregister_device);
34EXPORT_SYMBOL(input_register_handler); 35EXPORT_SYMBOL(input_register_handler);
@@ -872,6 +873,7 @@ struct input_dev *input_allocate_device(void)
872 dev->dynalloc = 1; 873 dev->dynalloc = 1;
873 dev->cdev.class = &input_class; 874 dev->cdev.class = &input_class;
874 class_device_initialize(&dev->cdev); 875 class_device_initialize(&dev->cdev);
876 mutex_init(&dev->mutex);
875 INIT_LIST_HEAD(&dev->h_list); 877 INIT_LIST_HEAD(&dev->h_list);
876 INIT_LIST_HEAD(&dev->node); 878 INIT_LIST_HEAD(&dev->node);
877 } 879 }
@@ -879,6 +881,18 @@ struct input_dev *input_allocate_device(void)
879 return dev; 881 return dev;
880} 882}
881 883
884void input_free_device(struct input_dev *dev)
885{
886 if (dev) {
887
888 mutex_lock(&dev->mutex);
889 dev->name = dev->phys = dev->uniq = NULL;
890 mutex_unlock(&dev->mutex);
891
892 input_put_device(dev);
893 }
894}
895
882int input_register_device(struct input_dev *dev) 896int input_register_device(struct input_dev *dev)
883{ 897{
884 static atomic_t input_no = ATOMIC_INIT(0); 898 static atomic_t input_no = ATOMIC_INIT(0);
@@ -895,7 +909,6 @@ int input_register_device(struct input_dev *dev)
895 return -EINVAL; 909 return -EINVAL;
896 } 910 }
897 911
898 mutex_init(&dev->mutex);
899 set_bit(EV_SYN, dev->evbit); 912 set_bit(EV_SYN, dev->evbit);
900 913
901 /* 914 /*
@@ -979,6 +992,10 @@ void input_unregister_device(struct input_dev *dev)
979 sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); 992 sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
980 class_device_unregister(&dev->cdev); 993 class_device_unregister(&dev->cdev);
981 994
995 mutex_lock(&dev->mutex);
996 dev->name = dev->phys = dev->uniq = NULL;
997 mutex_unlock(&dev->mutex);
998
982 input_wakeup_procfs_readers(); 999 input_wakeup_procfs_readers();
983} 1000}
984 1001