Commit 98113cc0 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Linus Torvalds

[PATCH] fix possible evdev usb mouse disconnect oops

evdev, joydev, mousedev, tsdev - remove class device and devfs entry when
hardware driver disconnects instead of waiting for the last user to drop off. 
This way hardware drivers can be unloaded at any time.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 12129e6c
......@@ -91,8 +91,6 @@ static int evdev_flush(struct file * file)
static void evdev_free(struct evdev *evdev)
{
devfs_remove("input/event%d", evdev->minor);
class_simple_device_remove(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
evdev_table[evdev->minor] = NULL;
kfree(evdev);
}
......@@ -441,6 +439,8 @@ static void evdev_disconnect(struct input_handle *handle)
{
struct evdev *evdev = handle->private;
class_simple_device_remove(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
devfs_remove("input/event%d", evdev->minor);
evdev->exist = 0;
if (evdev->open) {
......
......@@ -143,9 +143,7 @@ static int joydev_fasync(int fd, struct file *file, int on)
static void joydev_free(struct joydev *joydev)
{
devfs_remove("input/js%d", joydev->minor);
joydev_table[joydev->minor] = NULL;
class_simple_device_remove(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
kfree(joydev);
}
......@@ -466,6 +464,8 @@ static void joydev_disconnect(struct input_handle *handle)
{
struct joydev *joydev = handle->private;
class_simple_device_remove(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
devfs_remove("input/js%d", joydev->minor);
joydev->exist = 0;
if (joydev->open)
......
......@@ -329,8 +329,6 @@ static int mousedev_fasync(int fd, struct file *file, int on)
static void mousedev_free(struct mousedev *mousedev)
{
devfs_remove("input/mouse%d", mousedev->minor);
class_simple_device_remove(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
mousedev_table[mousedev->minor] = NULL;
kfree(mousedev);
}
......@@ -640,6 +638,8 @@ static void mousedev_disconnect(struct input_handle *handle)
{
struct mousedev *mousedev = handle->private;
class_simple_device_remove(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
devfs_remove("input/mouse%d", mousedev->minor);
mousedev->exist = 0;
if (mousedev->open) {
......
......@@ -177,8 +177,6 @@ static int tsdev_open(struct inode *inode, struct file *file)
static void tsdev_free(struct tsdev *tsdev)
{
devfs_remove("input/ts%d", tsdev->minor);
class_simple_device_remove(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
tsdev_table[tsdev->minor] = NULL;
kfree(tsdev);
}
......@@ -429,6 +427,9 @@ static void tsdev_disconnect(struct input_handle *handle)
{
struct tsdev *tsdev = handle->private;
class_simple_device_remove(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
devfs_remove("input/ts%d", tsdev->minor);
devfs_remove("input/tsraw%d", tsdev->minor);
tsdev->exist = 0;
if (tsdev->open) {
......@@ -436,7 +437,6 @@ static void tsdev_disconnect(struct input_handle *handle)
wake_up_interruptible(&tsdev->wait);
} else
tsdev_free(tsdev);
devfs_remove("input/tsraw%d", tsdev->minor);
}
static struct input_device_id tsdev_ids[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment