Re: [Bug] oops in usb_suspend_both with FTDI USB-serial-converter connected

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 3 May 2012, Huajun Li wrote:

> Hi all,
> Below calling sequence may cause the issue:
>     usb_suspend_both()
>          usb_suspend_interface()
>             ...
>             status = driver->suspend(intf, msg);
>             ----> Invalid reference (ftdi_sio does not implement this callback)

That is indeed the problem.

> Can following code fix the issue?
> ====================================
> diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
> index 9a56635..60aa897 100644
> --- a/drivers/usb/core/driver.c
> +++ b/drivers/usb/core/driver.c
> @@ -1676,6 +1676,10 @@ int usb_runtime_suspend(struct device *dev)
>         if (autosuspend_check(udev) != 0)
>                 return -EAGAIN;
> 
> +       device_lock(&udev->dev);
> +       unbind_no_pm_drivers_interfaces(udev);
> +       device_unlock(&udev->dev);
> +
>         status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);

But this is not the proper solution.  The following patch should fix 
things.  Frank, can you test it?

Alan Stern



Index: usb-3.4/drivers/usb/serial/usb-serial.c
===================================================================
--- usb-3.4.orig/drivers/usb/serial/usb-serial.c
+++ usb-3.4/drivers/usb/serial/usb-serial.c
@@ -1331,12 +1331,6 @@ static int usb_serial_register(struct us
 
 	if (!driver->description)
 		driver->description = driver->driver.name;
-	if (!driver->usb_driver) {
-		WARN(1, "Serial driver %s has no usb_driver\n",
-				driver->description);
-		return -EINVAL;
-	}
-	driver->usb_driver->supports_autosuspend = 1;
 
 	/* Add this device to our list of devices */
 	mutex_lock(&table_lock);
@@ -1371,7 +1365,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,
@@ -1390,11 +1384,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-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux