aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-12-25 01:37:49 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-12-25 01:38:11 -0500
commit98b7fb0472f828536a7786df6bd517322c0c17dc (patch)
tree9963828250cc0bbee2a771ee62604f483f047d25 /drivers/input/joystick
parent94ec26c855bc675259e4f1658673f458040affd7 (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.c26
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c28
-rw-r--r--drivers/input/joystick/iforce/iforce.h2
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
213static void iforce_release(struct input_dev *dev) 213static 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
249void 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() */
190void 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
201static void iforce_usb_disconnect(struct usb_interface *intf) 189static 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
218static struct usb_device_id iforce_usb_ids [] = { 204static 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 */
152void iforce_usb_xmit(struct iforce *iforce); 152void iforce_usb_xmit(struct iforce *iforce);
153void iforce_usb_delete(struct iforce *iforce);
154 153
155/* iforce-main.c */ 154/* iforce-main.c */
156int iforce_init_device(struct iforce *iforce); 155int iforce_init_device(struct iforce *iforce);
157void iforce_delete_device(struct iforce *iforce);
158 156
159/* iforce-packets.c */ 157/* iforce-packets.c */
160int iforce_control_playback(struct iforce*, u16 id, unsigned int); 158int iforce_control_playback(struct iforce*, u16 id, unsigned int);