Skip to content

Commit

Permalink
Input: iforce - fix oops on device disconnect
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dmitry Torokhov committed Dec 25, 2009
1 parent 94ec26c commit 98b7fb0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 44 deletions.
26 changes: 5 additions & 21 deletions drivers/input/joystick/iforce/iforce-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ static int iforce_open(struct input_dev *dev)
return 0;
}

static void iforce_release(struct input_dev *dev)
static void iforce_close(struct input_dev *dev)
{
struct iforce *iforce = input_get_drvdata(dev);
int i;
Expand All @@ -230,28 +230,12 @@ static void iforce_release(struct input_dev *dev)
iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
}

switch (iforce->bus) {
#ifdef CONFIG_JOYSTICK_IFORCE_USB
case IFORCE_USB:
usb_kill_urb(iforce->irq);

/* The device was unplugged before the file
* was released */
if (iforce->usbdev == NULL) {
iforce_delete_device(iforce);
kfree(iforce);
}
break;
#endif
}
}

void iforce_delete_device(struct iforce *iforce)
{
switch (iforce->bus) {
#ifdef CONFIG_JOYSTICK_IFORCE_USB
case IFORCE_USB:
iforce_usb_delete(iforce);
usb_kill_urb(iforce->irq);
usb_kill_urb(iforce->out);
usb_kill_urb(iforce->ctrl);
break;
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_232
Expand Down Expand Up @@ -303,7 +287,7 @@ int iforce_init_device(struct iforce *iforce)

input_dev->name = "Unknown I-Force device";
input_dev->open = iforce_open;
input_dev->close = iforce_release;
input_dev->close = iforce_close;

/*
* On-device memory allocation.
Expand Down
28 changes: 7 additions & 21 deletions drivers/input/joystick/iforce/iforce-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,33 +186,19 @@ static int iforce_usb_probe(struct usb_interface *intf,
return err;
}

/* Called by iforce_delete() */
void iforce_usb_delete(struct iforce* iforce)
{
usb_kill_urb(iforce->irq);
usb_kill_urb(iforce->out);
usb_kill_urb(iforce->ctrl);

usb_free_urb(iforce->irq);
usb_free_urb(iforce->out);
usb_free_urb(iforce->ctrl);
}

static void iforce_usb_disconnect(struct usb_interface *intf)
{
struct iforce *iforce = usb_get_intfdata(intf);
int open = 0; /* FIXME! iforce->dev.handle->open; */

usb_set_intfdata(intf, NULL);
if (iforce) {
iforce->usbdev = NULL;
input_unregister_device(iforce->dev);

if (!open) {
iforce_delete_device(iforce);
kfree(iforce);
}
}
input_unregister_device(iforce->dev);

usb_free_urb(iforce->irq);
usb_free_urb(iforce->out);
usb_free_urb(iforce->ctrl);

kfree(iforce);
}

static struct usb_device_id iforce_usb_ids [] = {
Expand Down
2 changes: 0 additions & 2 deletions drivers/input/joystick/iforce/iforce.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,9 @@ void iforce_serial_xmit(struct iforce *iforce);

/* iforce-usb.c */
void iforce_usb_xmit(struct iforce *iforce);
void iforce_usb_delete(struct iforce *iforce);

/* iforce-main.c */
int iforce_init_device(struct iforce *iforce);
void iforce_delete_device(struct iforce *iforce);

/* iforce-packets.c */
int iforce_control_playback(struct iforce*, u16 id, unsigned int);
Expand Down

0 comments on commit 98b7fb0

Please sign in to comment.