[ 44/91] usb-serial: ftdi_sio: fix oops during autosuspend

From: Greg KH
Date: Sat May 26 2012 - 21:17:32 EST


3.4-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

commit 5cbe61c5aff0a8ada691eb8b07dbfb55c303f640 upstream.

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@xxxxxxxxxxxxxxxxxxx>
Reported-and-tested-by: Frank Schäfer <schaefer.frank@xxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/usb/serial/usb-serial.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1338,7 +1338,6 @@ static int usb_serial_register(struct us
driver->description);
return -EINVAL;
}
- driver->usb_driver->supports_autosuspend = 1;

/* Add this device to our list of devices */
mutex_lock(&table_lock);
@@ -1373,7 +1372,7 @@ static void usb_serial_deregister(struct
* @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,
@@ -1392,11 +1391,17 @@ int usb_serial_register_drivers(struct u
* 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;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/