mirror of https://gitee.com/openkylin/linux.git
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: Alan Stern <stern@rowland.harvard.edu> Reported-and-tested-by: Frank Schäfer <schaefer.frank@gmx.net> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
23063b378d
commit
5cbe61c5af
|
@ -1336,7 +1336,6 @@ static int usb_serial_register(struct usb_serial_driver *driver)
|
|||
driver->description);
|
||||
return -EINVAL;
|
||||
}
|
||||
driver->usb_driver->supports_autosuspend = 1;
|
||||
|
||||
/* Add this device to our list of devices */
|
||||
mutex_lock(&table_lock);
|
||||
|
@ -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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
* simply fail for lack of a matching serial driver.
|
||||
* 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;
|
||||
udriver->id_table = NULL;
|
||||
|
||||
udriver->no_dynamic_id = 1;
|
||||
udriver->supports_autosuspend = 1;
|
||||
udriver->suspend = usb_serial_suspend;
|
||||
udriver->resume = usb_serial_resume;
|
||||
rc = usb_register(udriver);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
Loading…
Reference in New Issue