Re: your mail

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

 



On Wed, 5 Nov 2014, Sebastian Andrzej Siewior wrote:

> On 11/04/2014 08:10 PM, Alan Stern wrote:
> > Now, maybe something went wrong somewhere.  Perhaps the kernel thought 
> > that after the system resume, the root hub was still in runtime 
> > suspend.  If that's true, we need to find out why and fix it.
> 
> This is what I have so far (I have no idea what is correct / wrong I
> just document what I figured out):
> - good case no wakeup active.
>   - usb_suspend() => choose_wakeup()
>    "if (udev->state == USB_STATE_SUSPENDED && w !=
>         udev->do_remote_wakeup)"
>     w is 0 and do_remote_wakeup is 1. This means pm_runtime_resume() is
>     invoked.
>   - device status goes RPM_SUSPENDED => RPM_RESUMING => RPM_ACTIVE
>   - after we are in usb_suspend_both() and udev->state is 7
>     (USB_STATE_CONFIGURED), hub_suspend() is beeing invoked.
>     The status urb is dequeued, RPM of usb1 is still RPM_ACTIVE
> 
> - in the bad case (wakeup active)
>   - usb_suspend => choose_wakeup()
>     - in the check above we do nothing because w and …do_remote_wakeup
>       is 1
>     - usb_suspend_both() does nothing because udev->state is 8
>       (USB_STATE_SUSPENDED) so we leave. RPM of both devices (hub and
>        usb1 is RPM_SUSPENDED)

All of that is good; that's the way it is supposed to work.

> 
> --- now get back out of suspend ---
> - usb_resume() is invoked with different RPM status.
> - hub_activate() is invoked. The status URB is enqueued again, RPM
>   remains unchanged.
> - aaaaand we are done

Ah.  In usb_resume(), what happened after usb_resume_both() returned?  
The code says this:

	status = usb_resume_both(udev, msg);
	if (status == 0) {
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
		unbind_marked_interfaces(udev);
	}

So if usb_resume_both() returns 0, the runtime PM status is supposed to 
get changed to RPM_ACTIVE by the pm_runtime_set_active() call.

> - we get a HUB event, khubd is kicked.
> - the hub invokes usb_autopm_get_interface() on the interface which is
>   suspended. The hub device is suspended and has
>   dev->power.no_callbacks set. Now:
>   - in the "good" case it sees that the parent (usb1) is still
>     RPM_ACTIVE so it sets the status of the status of hub to RPM_ACTIVE
>     and leaves without doing anything.
>   - in the bad case the ave RPM still set to RPM_SUSPENDED so we call
>     resume for usb1 again which leads to the second status URB enqueue

The status should be RPM_ACTIVE in both cases.

> So that is the history. I *think* that we shouldn't to hub_suspend() +
> hub_resume() without changing the RPM status (the choose_wakeup()
> difference). This might also fix the RPM status for usb1 which is in
> RPM_SUSPENDED while it should be active (shouldn't it?) since it has
> remote_wakeup active.

Can you figure out why the status didn't get changed to RPM_ACTIVE?

Alan Stern

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