Re: btusb autosuspend failure

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

 



> Here's a patch for the core which should make your change to the btusb 
> driver unnecessary.  However I'm not yet convinced this is the right 
> thing to do.
> 
> The patch also reverses the order in which interfaces are suspended, so 
> that the suspend and resume iterations will run in opposite orders.
> 
> Alan Stern
> 
> 
> 
> Index: usb-2.6/drivers/usb/core/driver.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/core/driver.c
> +++ usb-2.6/drivers/usb/core/driver.c
> @@ -300,7 +300,7 @@ static int usb_probe_interface(struct de
>  
>  	intf->condition = USB_INTERFACE_BINDING;
>  
> -	/* Bound interfaces are initially active.  They are
> +	/* Probed interfaces are initially active.  They are
>  	 * runtime-PM-enabled only if the driver has autosuspend support.
>  	 * They are sensitive to their children's power states.
>  	 */
> @@ -436,11 +436,11 @@ int usb_driver_claim_interface(struct us
>  
>  	iface->condition = USB_INTERFACE_BOUND;
>  
> -	/* Bound interfaces are initially active.  They are
> +	/* Claimed interfaces are initially inactive (suspended).  They are
>  	 * runtime-PM-enabled only if the driver has autosuspend support.
>  	 * They are sensitive to their children's power states.
>  	 */
> -	pm_runtime_set_active(dev);
> +	pm_runtime_set_suspended(dev);
>  	pm_suspend_ignore_children(dev, false);
>  	if (driver->supports_autosuspend)
>  		pm_runtime_enable(dev);
> @@ -1169,7 +1169,7 @@ done:
>  static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
>  {
>  	int			status = 0;
> -	int			i = 0;
> +	int			i = 0, n = 0;
>  	struct usb_interface	*intf;
>  
>  	if (udev->state == USB_STATE_NOTATTACHED ||
> @@ -1178,7 +1178,8 @@ static int usb_suspend_both(struct usb_d
>  
>  	/* Suspend all the interfaces and then udev itself */
>  	if (udev->actconfig) {
> -		for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
> +		n = udev->actconfig->desc.bNumInterfaces;
> +		for (i = n - 1; i >= 0; --i) {
>  			intf = udev->actconfig->interface[i];
>  			status = usb_suspend_interface(udev, intf, msg);
>  			if (status != 0)
> @@ -1191,7 +1192,7 @@ static int usb_suspend_both(struct usb_d
>  	/* If the suspend failed, resume interfaces that did get suspended */
>  	if (status != 0) {
>  		msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
> -		while (--i >= 0) {
> +		while (++i < n) {
>  			intf = udev->actconfig->interface[i];
>  			usb_resume_interface(udev, intf, msg, 0);
>  		}
> 

Works fine.

Debugged-and-tested-by: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx>

Best,
	Dominik
--
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