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]

 



Am 03.05.2012 16:46, schrieb Alan Stern:
> 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;
>
Huajun, Alan, many thanks for taking a look at this.
Alan, your patch works perfectly !

Regards,
Frank Schäfer

--
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