diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-25 01:37:49 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-25 01:38:11 -0500 |
| commit | 98b7fb0472f828536a7786df6bd517322c0c17dc (patch) | |
| tree | 9963828250cc0bbee2a771ee62604f483f047d25 /drivers/input/joystick | |
| parent | 94ec26c855bc675259e4f1658673f458040affd7 (diff) | |
Input: iforce - fix oops on device disconnect
Do not try to free iforce device when we closing input device; disconnect
is the only place where it should be deleted.
Reported-by: Johannes Ebke <johannes.ebke@physik.uni-muenchen.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/joystick')
| -rw-r--r-- | drivers/input/joystick/iforce/iforce-main.c | 26 | ||||
| -rw-r--r-- | drivers/input/joystick/iforce/iforce-usb.c | 28 | ||||
| -rw-r--r-- | drivers/input/joystick/iforce/iforce.h | 2 |
3 files changed, 12 insertions, 44 deletions
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index f6c688cae33..acc3a9efb00 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
| @@ -210,7 +210,7 @@ static int iforce_open(struct input_dev *dev) | |||
| 210 | return 0; | 210 | return 0; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | static void iforce_release(struct input_dev *dev) | 213 | static void iforce_close(struct input_dev *dev) |
| 214 | { | 214 | { |
| 215 | struct iforce *iforce = input_get_drvdata(dev); | 215 | struct iforce *iforce = input_get_drvdata(dev); |
| 216 | int i; | 216 | int i; |
| @@ -232,26 +232,10 @@ static void iforce_release(struct input_dev *dev) | |||
| 232 | 232 | ||
| 233 | switch (iforce->bus) { | 233 | switch (iforce->bus) { |
| 234 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | 234 | #ifdef CONFIG_JOYSTICK_IFORCE_USB |
| 235 | case IFORCE_USB: | ||
| 236 | usb_kill_urb(iforce->irq); | ||
| 237 | |||
| 238 | /* The device was unplugged before the file | ||
| 239 | * was released */ | ||
| 240 | if (iforce->usbdev == NULL) { | ||
| 241 | iforce_delete_device(iforce); | ||
| 242 | kfree(iforce); | ||
| 243 | } | ||
| 244 | break; | ||
| 245 | #endif | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | void iforce_delete_device(struct iforce *iforce) | ||
| 250 | { | ||
| 251 | switch (iforce->bus) { | ||
| 252 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | ||
| 253 | case IFORCE_USB: | 235 | case IFORCE_USB: |
| 254 | iforce_usb_delete(iforce); | 236 | usb_kill_urb(iforce->irq); |
| 237 | usb_kill_urb(iforce->out); | ||
| 238 | usb_kill_urb(iforce->ctrl); | ||
| 255 | break; | 239 | break; |
| 256 | #endif | 240 | #endif |
| 257 | #ifdef CONFIG_JOYSTICK_IFORCE_232 | 241 | #ifdef CONFIG_JOYSTICK_IFORCE_232 |
| @@ -303,7 +287,7 @@ int iforce_init_device(struct iforce *iforce) | |||
| 303 | 287 | ||
| 304 | input_dev->name = "Unknown I-Force device"; | 288 | input_dev->name = "Unknown I-Force device"; |
| 305 | input_dev->open = iforce_open; | 289 | input_dev->open = iforce_open; |
| 306 | input_dev->close = iforce_release; | 290 | input_dev->close = iforce_close; |
| 307 | 291 | ||
| 308 | /* | 292 | /* |
| 309 | * On-device memory allocation. | 293 | * On-device memory allocation. |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 9f289d8f52c..c0ad8836944 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
| @@ -186,33 +186,19 @@ fail: | |||
| 186 | return err; | 186 | return err; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | /* Called by iforce_delete() */ | ||
| 190 | void iforce_usb_delete(struct iforce* iforce) | ||
| 191 | { | ||
| 192 | usb_kill_urb(iforce->irq); | ||
| 193 | usb_kill_urb(iforce->out); | ||
| 194 | usb_kill_urb(iforce->ctrl); | ||
| 195 | |||
| 196 | usb_free_urb(iforce->irq); | ||
| 197 | usb_free_urb(iforce->out); | ||
| 198 | usb_free_urb(iforce->ctrl); | ||
| 199 | } | ||
| 200 | |||
| 201 | static void iforce_usb_disconnect(struct usb_interface *intf) | 189 | static void iforce_usb_disconnect(struct usb_interface *intf) |
| 202 | { | 190 | { |
| 203 | struct iforce *iforce = usb_get_intfdata(intf); | 191 | struct iforce *iforce = usb_get_intfdata(intf); |
| 204 | int open = 0; /* FIXME! iforce->dev.handle->open; */ | ||
| 205 | 192 | ||
| 206 | usb_set_intfdata(intf, NULL); | 193 | usb_set_intfdata(intf, NULL); |
| 207 | if (iforce) { | ||
| 208 | iforce->usbdev = NULL; | ||
| 209 | input_unregister_device(iforce->dev); | ||
| 210 | 194 | ||
| 211 | if (!open) { | 195 | input_unregister_device(iforce->dev); |
| 212 | iforce_delete_device(iforce); | 196 | |
| 213 | kfree(iforce); | 197 | usb_free_urb(iforce->irq); |
| 214 | } | 198 | usb_free_urb(iforce->out); |
| 215 | } | 199 | usb_free_urb(iforce->ctrl); |
| 200 | |||
| 201 | kfree(iforce); | ||
| 216 | } | 202 | } |
| 217 | 203 | ||
| 218 | static struct usb_device_id iforce_usb_ids [] = { | 204 | static struct usb_device_id iforce_usb_ids [] = { |
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index f2d91f4028c..9f494b75848 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h | |||
| @@ -150,11 +150,9 @@ void iforce_serial_xmit(struct iforce *iforce); | |||
| 150 | 150 | ||
| 151 | /* iforce-usb.c */ | 151 | /* iforce-usb.c */ |
| 152 | void iforce_usb_xmit(struct iforce *iforce); | 152 | void iforce_usb_xmit(struct iforce *iforce); |
| 153 | void iforce_usb_delete(struct iforce *iforce); | ||
| 154 | 153 | ||
| 155 | /* iforce-main.c */ | 154 | /* iforce-main.c */ |
| 156 | int iforce_init_device(struct iforce *iforce); | 155 | int iforce_init_device(struct iforce *iforce); |
| 157 | void iforce_delete_device(struct iforce *iforce); | ||
| 158 | 156 | ||
| 159 | /* iforce-packets.c */ | 157 | /* iforce-packets.c */ |
| 160 | int iforce_control_playback(struct iforce*, u16 id, unsigned int); | 158 | int iforce_control_playback(struct iforce*, u16 id, unsigned int); |
