Re: Autosuspend and unbound interfaces

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

 



On Wed, 5 May 2010, Rob Duncan wrote:

> On May 5, 2010, at 2:24 PM, Alan Stern wrote:
> 
> > Note that there are no debugging printk's in
> > usb_autopm_put_interface_no_suspend() or
> > usb_autopm_get_interface_no_resume().  I guess I should add some.
> > Anyway, you'll want to see if they are getting called.
> 
> I added some tracing and they are not being called.
> 
> > If that doesn't show anything then you'll need to print out the values
> > of all the interfaces' dev.power.usage_count fields at some strategic
> > spots, like in usb_autoresume_device() and usb_autosuspend_device().
> 
> I also added some debug printing to usb_autosuspend_device() immediately
> after the existing log message.  I see pm_runtime_put_sync() return -EBUSY
> for the device (apparently because child_count > 0), but the usage_count
> for each of my interfaces is 0.
> 
> May  5 15:01:30 localhost kernel: usb 3-3: __pm_runtime_idle !pm_children_suspended power.usage_count=0 power.ignore_children=0 power.child_count=1
> May  5 15:01:30 localhost kernel: usb 3-3: usb_autosuspend_device: cnt 0 -> -16
> May  5 15:01:30 localhost kernel: usb 3-3: usb_autosuspend_device intf 0 usage_count=0
> May  5 15:01:30 localhost kernel: usb 3-3: usb_autosuspend_device intf 1 usage_count=0
> 
> It at appears that the device's child_count is incremented when
> usb_probe_interface() calls pm_runtime_set_active(), and is never
> decremented again.

Okay, I see what the problem is.  It's a subtle thing, involving the 
difference between the runtime PM state and the usage_count.  It also 
involves what the driver does: If it doesn't ever call 
usb_autopm_get_interface() or usb_autopm_put_interface(), should the 
device be autosuspended?

I guess it should.  This patch ought to fix the problem.

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
@@ -302,13 +302,15 @@ static int usb_probe_interface(struct de
 
 	intf->condition = USB_INTERFACE_BINDING;
 
-	/* 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.
+	/* If the driver does not have autosuspend support then we suppress
+	 * autosuspends by making its interfaces active and leaving them
+	 * runtime-PM-disabled, otherwise we do the reverse.  In either case,
+	 * the interfaces are sensitive to their children's power states.
 	 */
-	pm_runtime_set_active(dev);
 	pm_suspend_ignore_children(dev, false);
-	if (driver->supports_autosuspend)
+	if (!driver->supports_autosuspend)
+		pm_runtime_set_active(dev);
+	else
 		pm_runtime_enable(dev);
 
 	/* Carry out a deferred switch to altsetting 0 */
@@ -438,13 +440,15 @@ int usb_driver_claim_interface(struct us
 
 	iface->condition = USB_INTERFACE_BOUND;
 
-	/* 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.
+	/* If the driver does not have autosuspend support then we suppress
+	 * autosuspends by making its interfaces active and leaving them
+	 * runtime-PM-disabled, otherwise we do the reverse.  In either case,
+	 * the interfaces are sensitive to their children's power states.
 	 */
-	pm_runtime_set_suspended(dev);
 	pm_suspend_ignore_children(dev, false);
-	if (driver->supports_autosuspend)
+	if (!driver->supports_autosuspend)
+		pm_runtime_set_active(dev);
+	else
 		pm_runtime_enable(dev);
 
 	/* if interface was already added, bind now; else let

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