Commit 5cbe61c5 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

usb-serial: ftdi_sio: fix oops during autosuspend

This patch (as1550) fixes a bug in the usb-serial core that affects
the ftdi_sio driver and most likely others as well.  The core
implements suspend and resume routines, but it doesn't store pointers
to those routines in the usb_driver structures that it registers,
even though it does set those drivers' supports_autosuspend flag.  The
end result is that when one of these devices is autosuspended, we try
to call through a NULL pointer.

The patch fixes the problem by setting the suspend and resume method
pointers to the appropriate routines in the USB serial core, along
with the supports_autosuspend field, in each driver as it is
registered.

This should be back-ported to all the stable kernels that have the new
usb_serial_register_drivers() interface.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: default avatarFrank Schäfer <schaefer.frank@gmx.net>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 23063b37
...@@ -1336,7 +1336,6 @@ static int usb_serial_register(struct usb_serial_driver *driver) ...@@ -1336,7 +1336,6 @@ static int usb_serial_register(struct usb_serial_driver *driver)
driver->description); driver->description);
return -EINVAL; return -EINVAL;
} }
driver->usb_driver->supports_autosuspend = 1;
/* Add this device to our list of devices */ /* Add this device to our list of devices */
mutex_lock(&table_lock); mutex_lock(&table_lock);
...@@ -1371,7 +1370,7 @@ static void usb_serial_deregister(struct usb_serial_driver *device) ...@@ -1371,7 +1370,7 @@ static void usb_serial_deregister(struct usb_serial_driver *device)
* @serial_drivers: NULL-terminated array of pointers to drivers to be registered * @serial_drivers: NULL-terminated array of pointers to drivers to be registered
* *
* Registers @udriver and all the drivers in the @serial_drivers array. * Registers @udriver and all the drivers in the @serial_drivers array.
* Automatically fills in the .no_dynamic_id field in @udriver and * Automatically fills in the .no_dynamic_id and PM fields in @udriver and
* the .usb_driver field in each serial driver. * the .usb_driver field in each serial driver.
*/ */
int usb_serial_register_drivers(struct usb_driver *udriver, int usb_serial_register_drivers(struct usb_driver *udriver,
...@@ -1390,11 +1389,17 @@ int usb_serial_register_drivers(struct usb_driver *udriver, ...@@ -1390,11 +1389,17 @@ int usb_serial_register_drivers(struct usb_driver *udriver,
* the serial drivers are registered, because the probe would * the serial drivers are registered, because the probe would
* simply fail for lack of a matching serial driver. * simply fail for lack of a matching serial driver.
* Therefore save off udriver's id_table until we are all set. * Therefore save off udriver's id_table until we are all set.
*
* Suspend/resume support is implemented in the usb-serial core,
* so fill in the PM-related fields in udriver.
*/ */
saved_id_table = udriver->id_table; saved_id_table = udriver->id_table;
udriver->id_table = NULL; udriver->id_table = NULL;
udriver->no_dynamic_id = 1; udriver->no_dynamic_id = 1;
udriver->supports_autosuspend = 1;
udriver->suspend = usb_serial_suspend;
udriver->resume = usb_serial_resume;
rc = usb_register(udriver); rc = usb_register(udriver);
if (rc) if (rc)
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment