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 | |
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')
-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 f6c688cae334..acc3a9efb00f 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 9f289d8f52c6..c0ad88369442 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 f2d91f4028ca..9f494b75848a 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); |