]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] fix possible evdev usb mouse disconnect oops
authorDmitry Torokhov <dtor@mail.ru>
Fri, 24 Dec 2004 02:15:50 +0000 (18:15 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 24 Dec 2004 02:15:50 +0000 (18:15 -0800)
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: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/input/evdev.c
drivers/input/joydev.c
drivers/input/mousedev.c
drivers/input/tsdev.c

index 3737e5abc286cb6e6d1d3b0ace9d327ae0aa1398..39c497e5fafafc283988c7bcf6fd34ef81b86342 100644 (file)
@@ -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) {
index 3e47218e0d6a6942f48b49f5cd6d731805ee76d1..4fe982d63bedecf573620953a298d3b1e35c6c28 100644 (file)
@@ -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)
index bd1a6d98bde572fd939bdefb0c58751c54550c02..19dea5ed1dae68d69b1f4bdfc48bae365e310c3d 100644 (file)
@@ -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) {
index 18c37d8ac5d6f23cdebeebc74a2cf1fbd559c59c..9c00dbd39c6fa5457e0f759a0561c5716e721101 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $Id: tsdev.c,v 1.15 2002/04/10 16:50:19 jsimmons Exp $
  *
- *  Copyright (c) 2001 "Crazy" james Simmons 
+ *  Copyright (c) 2001 "Crazy" james Simmons
  *
  *  Compaq touchscreen protocol driver. The protocol emulated by this driver
  *  is obsolete; for new programs use the tslib library which can read directly
@@ -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);
 }
@@ -418,7 +416,7 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
                        S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
        devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
                        S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
-       class_simple_device_add(input_class, 
+       class_simple_device_add(input_class,
                                MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
                                dev->dev, "ts%d", minor);
 
@@ -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[] = {