mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
94ec26c855
commit
98b7fb0472
|
@ -210,7 +210,7 @@ static int iforce_open(struct input_dev *dev)
|
||||||
return 0;
|
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);
|
struct iforce *iforce = input_get_drvdata(dev);
|
||||||
int i;
|
int i;
|
||||||
|
@ -230,28 +230,12 @@ static void iforce_release(struct input_dev *dev)
|
||||||
iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
|
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) {
|
switch (iforce->bus) {
|
||||||
#ifdef CONFIG_JOYSTICK_IFORCE_USB
|
#ifdef CONFIG_JOYSTICK_IFORCE_USB
|
||||||
case 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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_JOYSTICK_IFORCE_232
|
#ifdef CONFIG_JOYSTICK_IFORCE_232
|
||||||
|
@ -303,7 +287,7 @@ int iforce_init_device(struct iforce *iforce)
|
||||||
|
|
||||||
input_dev->name = "Unknown I-Force device";
|
input_dev->name = "Unknown I-Force device";
|
||||||
input_dev->open = iforce_open;
|
input_dev->open = iforce_open;
|
||||||
input_dev->close = iforce_release;
|
input_dev->close = iforce_close;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On-device memory allocation.
|
* On-device memory allocation.
|
||||||
|
|
|
@ -186,33 +186,19 @@ static int iforce_usb_probe(struct usb_interface *intf,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by iforce_delete() */
|
static void iforce_usb_disconnect(struct usb_interface *intf)
|
||||||
void iforce_usb_delete(struct iforce* iforce)
|
|
||||||
{
|
{
|
||||||
usb_kill_urb(iforce->irq);
|
struct iforce *iforce = usb_get_intfdata(intf);
|
||||||
usb_kill_urb(iforce->out);
|
|
||||||
usb_kill_urb(iforce->ctrl);
|
usb_set_intfdata(intf, NULL);
|
||||||
|
|
||||||
|
input_unregister_device(iforce->dev);
|
||||||
|
|
||||||
usb_free_urb(iforce->irq);
|
usb_free_urb(iforce->irq);
|
||||||
usb_free_urb(iforce->out);
|
usb_free_urb(iforce->out);
|
||||||
usb_free_urb(iforce->ctrl);
|
usb_free_urb(iforce->ctrl);
|
||||||
}
|
|
||||||
|
|
||||||
static void iforce_usb_disconnect(struct usb_interface *intf)
|
kfree(iforce);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_device_id iforce_usb_ids [] = {
|
static struct usb_device_id iforce_usb_ids [] = {
|
||||||
|
|
|
@ -150,11 +150,9 @@ void iforce_serial_xmit(struct iforce *iforce);
|
||||||
|
|
||||||
/* iforce-usb.c */
|
/* iforce-usb.c */
|
||||||
void iforce_usb_xmit(struct iforce *iforce);
|
void iforce_usb_xmit(struct iforce *iforce);
|
||||||
void iforce_usb_delete(struct iforce *iforce);
|
|
||||||
|
|
||||||
/* iforce-main.c */
|
/* iforce-main.c */
|
||||||
int iforce_init_device(struct iforce *iforce);
|
int iforce_init_device(struct iforce *iforce);
|
||||||
void iforce_delete_device(struct iforce *iforce);
|
|
||||||
|
|
||||||
/* iforce-packets.c */
|
/* iforce-packets.c */
|
||||||
int iforce_control_playback(struct iforce*, u16 id, unsigned int);
|
int iforce_control_playback(struct iforce*, u16 id, unsigned int);
|
||||||
|
|
Loading…
Reference in New Issue