All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
       [not found] <57F4B9C5.60600@linux.intel.com>
@ 2016-10-05 14:45 ` Alan Stern
  2016-10-05 18:54   ` Bjorn Helgaas
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Stern @ 2016-10-05 14:45 UTC (permalink / raw
  To: Mathias Nyman
  Cc: Bjorn Helgaas, Pierre de Villemereuil, Oliver Neukum, USB list,
	linux-pci

[Adding Bjorn and linux-pci to the CC: list]

In short, Pierre's USB host controller doesn't send wakeup signals from
runtime suspend, because the firmware limits the runtime-suspend state
to D0 and the controller can't issue PME# from the D0 state.  In this
situation we would prefer to avoid suspending the controller at all,
rather than have it go into runtime suspend and then stop working.

On Wed, 5 Oct 2016, Mathias Nyman wrote:

> On 04.10.2016 17:11, Alan Stern wrote:
> > On Tue, 4 Oct 2016, Mathias Nyman wrote:
> >
> >> On 03.10.2016 23:54, Pierre de Villemereuil wrote:
> >>> Hi Mathias,
> >>>
> >>> Just to know: does that mean the firmware from Asus is faulty in here? Do you
> >>> think I should contact Asus about this?
> >>>
> >>
> >> Probably, _S0W, _DSM  and XFLT code for xHCI are useless in that ACPI DSDT firmware version.
> >>
> >> But we still want the driver to handle cases like this.
> >> Just wrote the patch.
> >> Adding Alan Stern to CC for PM sanity feedback on it:
> >>
> >> ---
> >>
> >> Author: Mathias Nyman <mathias.nyman@linux.intel.com>
> >> Date:   Tue Oct 4 13:07:59 2016 +0300
> >>
> >>       xhci: Prevent a non-responsive xhci suspend state.
> >>
> >>       ACPI may limit the lowest possible runtime suspend PCI D-state to D0.
> >>       If xHC is not capable of generating PME# events in D0 we end
> >>       up with a non-responsive runtime suspended host without PME# capability
> >>       and with interrupts disabled, unable to detect or wake up when a
> >>       new usb device is connected.
> >>
> >>       This was triggered on a ASUS TP301UA machine.
> >>
> >>       Reported-by: Pierre de Villemereuil <flyos@mailoo.org>
> >>       Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> >>
> >> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> >> index d7b0f97..08b021c 100644
> >> --- a/drivers/usb/host/xhci-pci.c
> >> +++ b/drivers/usb/host/xhci-pci.c
> >> @@ -396,6 +396,11 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
> >>           if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
> >>                   xhci_ssic_port_unused_quirk(hcd, true);
> >>
> >> +       /* Prevent a non-responsive PCI D0 state without PME# wake capability */
> >> +       if (pci_choose_state(pdev, PMSG_AUTO_SUSPEND) == PCI_D0)
> >> +               if (!pci_pme_capable(pdev, PCI_D0))
> >> +                       return -EBUSY;
> >> +
> >>           ret = xhci_suspend(xhci, do_wakeup);
> >>           if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED))
> >>                   xhci_ssic_port_unused_quirk(hcd, false);
> >
> > I've got three comments about this proposal.
> >
> > First, this logic should not apply during system suspend, only during
> > runtime suspend.  You don't want to abort putting a laptop to sleep
> > just because the xHCI controller can't generate wakeup signals.
> 
> Yes, I assume it would be ok change usb core to pass down something like
> pm_message_t to suspend_common() so that we could do this.
> hcd_pci_runetime_suspend()  -> suspend_common()  -> hcd->driver->pci_suspend()
> 
> Assuming this workaround should stay in xhci-pci.c

If necessary, it could be moved into hcd_pci_runtime_suspend().  But I 
would prefer to put it in the PCI core.

> > Second, this really has nothing to do with the D0 state.  The same
> > logic should apply to whatever state is chosen for runtime suspend: If
> > the controller can't generate PME# wakeup signals in that state then
> > the suspend should be aborted.
> 
> PCI code actually does this for us, it will walk down the D-states until
> it finds one that support PME#, but stop at D0 end return D0 even if D0
> does not support PME#.

That sounds like a bug.  Or rather, accepting D0 as the target state
when it doesn't support PME# is the bug.

> Unfortunately that is done in a static function in pci/pci.c.
> 
> static pci_power_t pci_target_state(struct pci_dev *dev)
> {
>          pci_power_t target_state = PCI_D3hot;
> 
> 	if (platform_pci_power_manageable(dev)) {
>                  /*
>                   * Call the platform to choose the target state of the device
>                   * and enable wake-up from this state if supported.
>                   */
>                  pci_power_t state = platform_pci_choose_state(dev);
> 
> 	        switch (state) {
> 	        case PCI_POWER_ERROR:
>                  case PCI_UNKNOWN:
>                          break;
>                  case PCI_D1:
>                  case PCI_D2:
>                          if (pci_no_d1d2(dev))
> 	                        break;
>                  default:
> 	                target_state = state;
>                  }
>          } else if (!dev->pm_cap) {
>                  target_state = PCI_D0;
>          } else if (device_may_wakeup(&dev->dev)) {
>                  /*
>                   * Find the deepest state from which the device can generate
>                   * wake-up events, make it the target state and enable device
>                   * to generate PME#.
>                   */
>                  if (dev->pme_support) {
>                          while (target_state
>                                && !(dev->pme_support & (1 << target_state)))
>                                  target_state--;
>                  }
>          }
> 
>          return target_state;
> }
> 
> The best I can do from xhci is call pci_choose_state() which will call
> platform_pci_choose_state(), but won't do the PME# checking and
> D-state decrement to D0 .
> 
> If pci_choose_state() returns D0 from a runtime suspend callback
> (and yes, should make sure its runtime suspend, not system suspend)
> I can pretty much assume pci_target_state will do the same.
> 
> >
> > Third, the same reasoning applies to every PCI device that relies on
> > PME#, not just to xHCI controllers.  Therefore the new code should be
> > added to drivers/pci/pci-driver.c:pci_pm_runtime_suspend(), not to
> > xhci-pci.c.
> 
> Yes, that would be the preferred solution.
> I was not sure we can do that. pci-driver.c pci_pm_runtime_suspend() will call
> pci_finish_runtime_suspend()
>    pci_target_state()        // returns D0,
>    pci_set_power_state()    // to D0, which is the state we probably are already in.
> 
> So it won't really do much. The device PCI device is disabled in usb hcd suspend
> hcd-pci.c:
> suspend_common()
>    ...
>    pci_disable_device(pci_dev)
> 
> Should we anyway disable runtime PM in PCI if the PCI device has wakeup enabled
> and the target state is D0 without PME# support?

First, the device_may_wakeup() test applies only to suspend suspend, 
not to runtime suspend.  The current PM design assumes that wakeup will 
always be enabled during runtime suspend (if the device supports it).

Second, there is a potential problem because some PCI devices have
other platform-based mechanisms for sending wakeup signals, instead of
using PME#.  Such devices probably don't support standard PCI wakeup at
all.  (A good example is the UHCI controllers on Intel's old chipsets.)
We don't want to prevent them from going into runtime suspend.

Now, maybe this isn't an issue -- I don't know enough about the details
of how the PCI core handles runtime suspend and how it coordinates with
the platform code.

Hopefully Bjorn can fill in the missing details.

Alan Stern


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-05 14:45 ` USB hot-plug not working (ASUS TP301UA-C4028T) Alan Stern
@ 2016-10-05 18:54   ` Bjorn Helgaas
  2016-10-05 20:41     ` Lukas Wunner
  0 siblings, 1 reply; 15+ messages in thread
From: Bjorn Helgaas @ 2016-10-05 18:54 UTC (permalink / raw
  To: Alan Stern
  Cc: Mathias Nyman, Bjorn Helgaas, Pierre de Villemereuil,
	Oliver Neukum, USB list, linux-pci, Rafael J. Wysocki,
	Lukas Wunner

[+cc Rafael, Lukas]

On Wed, Oct 05, 2016 at 10:45:22AM -0400, Alan Stern wrote:
> [Adding Bjorn and linux-pci to the CC: list]
> 
> In short, Pierre's USB host controller doesn't send wakeup signals from
> runtime suspend, because the firmware limits the runtime-suspend state
> to D0 and the controller can't issue PME# from the D0 state.  In this
> situation we would prefer to avoid suspending the controller at all,
> rather than have it go into runtime suspend and then stop working.
> 
> On Wed, 5 Oct 2016, Mathias Nyman wrote:
> 
> > On 04.10.2016 17:11, Alan Stern wrote:
> > > On Tue, 4 Oct 2016, Mathias Nyman wrote:
> > >
> > >> On 03.10.2016 23:54, Pierre de Villemereuil wrote:
> > >>> Hi Mathias,
> > >>>
> > >>> Just to know: does that mean the firmware from Asus is faulty in here? Do you
> > >>> think I should contact Asus about this?
> > >>>
> > >>
> > >> Probably, _S0W, _DSM  and XFLT code for xHCI are useless in that ACPI DSDT firmware version.
> > >>
> > >> But we still want the driver to handle cases like this.
> > >> Just wrote the patch.
> > >> Adding Alan Stern to CC for PM sanity feedback on it:
> > >>
> > >> ---
> > >>
> > >> Author: Mathias Nyman <mathias.nyman@linux.intel.com>
> > >> Date:   Tue Oct 4 13:07:59 2016 +0300
> > >>
> > >>       xhci: Prevent a non-responsive xhci suspend state.
> > >>
> > >>       ACPI may limit the lowest possible runtime suspend PCI D-state to D0.
> > >>       If xHC is not capable of generating PME# events in D0 we end
> > >>       up with a non-responsive runtime suspended host without PME# capability
> > >>       and with interrupts disabled, unable to detect or wake up when a
> > >>       new usb device is connected.
> > >>
> > >>       This was triggered on a ASUS TP301UA machine.
> > >>
> > >>       Reported-by: Pierre de Villemereuil <flyos@mailoo.org>
> > >>       Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> > >>
> > >> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> > >> index d7b0f97..08b021c 100644
> > >> --- a/drivers/usb/host/xhci-pci.c
> > >> +++ b/drivers/usb/host/xhci-pci.c
> > >> @@ -396,6 +396,11 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
> > >>           if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
> > >>                   xhci_ssic_port_unused_quirk(hcd, true);
> > >>
> > >> +       /* Prevent a non-responsive PCI D0 state without PME# wake capability */
> > >> +       if (pci_choose_state(pdev, PMSG_AUTO_SUSPEND) == PCI_D0)
> > >> +               if (!pci_pme_capable(pdev, PCI_D0))
> > >> +                       return -EBUSY;
> > >> +
> > >>           ret = xhci_suspend(xhci, do_wakeup);
> > >>           if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED))
> > >>                   xhci_ssic_port_unused_quirk(hcd, false);
> > >
> > > I've got three comments about this proposal.
> > >
> > > First, this logic should not apply during system suspend, only during
> > > runtime suspend.  You don't want to abort putting a laptop to sleep
> > > just because the xHCI controller can't generate wakeup signals.
> > 
> > Yes, I assume it would be ok change usb core to pass down something like
> > pm_message_t to suspend_common() so that we could do this.
> > hcd_pci_runetime_suspend()  -> suspend_common()  -> hcd->driver->pci_suspend()
> > 
> > Assuming this workaround should stay in xhci-pci.c
> 
> If necessary, it could be moved into hcd_pci_runtime_suspend().  But I 
> would prefer to put it in the PCI core.
> 
> > > Second, this really has nothing to do with the D0 state.  The same
> > > logic should apply to whatever state is chosen for runtime suspend: If
> > > the controller can't generate PME# wakeup signals in that state then
> > > the suspend should be aborted.
> > 
> > PCI code actually does this for us, it will walk down the D-states until
> > it finds one that support PME#, but stop at D0 end return D0 even if D0
> > does not support PME#.
> 
> That sounds like a bug.  Or rather, accepting D0 as the target state
> when it doesn't support PME# is the bug.
> 
> > Unfortunately that is done in a static function in pci/pci.c.
> > 
> > static pci_power_t pci_target_state(struct pci_dev *dev)
> > {
> >          pci_power_t target_state = PCI_D3hot;
> > 
> > 	if (platform_pci_power_manageable(dev)) {
> >                  /*
> >                   * Call the platform to choose the target state of the device
> >                   * and enable wake-up from this state if supported.
> >                   */
> >                  pci_power_t state = platform_pci_choose_state(dev);
> > 
> > 	        switch (state) {
> > 	        case PCI_POWER_ERROR:
> >                  case PCI_UNKNOWN:
> >                          break;
> >                  case PCI_D1:
> >                  case PCI_D2:
> >                          if (pci_no_d1d2(dev))
> > 	                        break;
> >                  default:
> > 	                target_state = state;
> >                  }
> >          } else if (!dev->pm_cap) {
> >                  target_state = PCI_D0;
> >          } else if (device_may_wakeup(&dev->dev)) {
> >                  /*
> >                   * Find the deepest state from which the device can generate
> >                   * wake-up events, make it the target state and enable device
> >                   * to generate PME#.
> >                   */
> >                  if (dev->pme_support) {
> >                          while (target_state
> >                                && !(dev->pme_support & (1 << target_state)))
> >                                  target_state--;
> >                  }
> >          }
> > 
> >          return target_state;
> > }
> > 
> > The best I can do from xhci is call pci_choose_state() which will call
> > platform_pci_choose_state(), but won't do the PME# checking and
> > D-state decrement to D0 .
> > 
> > If pci_choose_state() returns D0 from a runtime suspend callback
> > (and yes, should make sure its runtime suspend, not system suspend)
> > I can pretty much assume pci_target_state will do the same.
> > 
> > >
> > > Third, the same reasoning applies to every PCI device that relies on
> > > PME#, not just to xHCI controllers.  Therefore the new code should be
> > > added to drivers/pci/pci-driver.c:pci_pm_runtime_suspend(), not to
> > > xhci-pci.c.
> > 
> > Yes, that would be the preferred solution.
> > I was not sure we can do that. pci-driver.c pci_pm_runtime_suspend() will call
> > pci_finish_runtime_suspend()
> >    pci_target_state()        // returns D0,
> >    pci_set_power_state()    // to D0, which is the state we probably are already in.
> > 
> > So it won't really do much. The device PCI device is disabled in usb hcd suspend
> > hcd-pci.c:
> > suspend_common()
> >    ...
> >    pci_disable_device(pci_dev)
> > 
> > Should we anyway disable runtime PM in PCI if the PCI device has wakeup enabled
> > and the target state is D0 without PME# support?
> 
> First, the device_may_wakeup() test applies only to suspend suspend, 
> not to runtime suspend.  The current PM design assumes that wakeup will 
> always be enabled during runtime suspend (if the device supports it).
> 
> Second, there is a potential problem because some PCI devices have
> other platform-based mechanisms for sending wakeup signals, instead of
> using PME#.  Such devices probably don't support standard PCI wakeup at
> all.  (A good example is the UHCI controllers on Intel's old chipsets.)
> We don't want to prevent them from going into runtime suspend.
> 
> Now, maybe this isn't an issue -- I don't know enough about the details
> of how the PCI core handles runtime suspend and how it coordinates with
> the platform code.
> 
> Hopefully Bjorn can fill in the missing details.
> 
> Alan Stern
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-05 18:54   ` Bjorn Helgaas
@ 2016-10-05 20:41     ` Lukas Wunner
  2016-10-06  7:24       ` Oliver Neukum
  2016-10-06 14:42       ` Alan Stern
  0 siblings, 2 replies; 15+ messages in thread
From: Lukas Wunner @ 2016-10-05 20:41 UTC (permalink / raw
  To: Bjorn Helgaas
  Cc: Alan Stern, Mathias Nyman, Bjorn Helgaas, Pierre de Villemereuil,
	Oliver Neukum, USB list, linux-pci, Rafael J. Wysocki

On Wed, Oct 05, 2016 at 01:54:01PM -0500, Bjorn Helgaas wrote:
> On Wed, Oct 05, 2016 at 10:45:22AM -0400, Alan Stern wrote:
> > In short, Pierre's USB host controller doesn't send wakeup signals from
> > runtime suspend, because the firmware limits the runtime-suspend state
> > to D0 and the controller can't issue PME# from the D0 state.  In this
> > situation we would prefer to avoid suspending the controller at all,
> > rather than have it go into runtime suspend and then stop working.

As Alan has correctly pointed out below, there are PCI devices which
do not support PME but should still be runtime suspended, e.g. because
they have some non-standard mechanism to sideband signal wakeup or
because they can detect when they need to resume even if they're in
a low-power state.

AFAIUI, this device should not be runtime suspended at all because it
doesn't generate a PME interrupt and thus stays suspended forever.

The PCI core doesn't allow runtime PM by default.  Rather it calls
pm_runtime_forbid() when the device is added (see pci_pm_init(), called
indirectly from pci_device_add()).  PCI drivers need to explicitly call
pm_runtime_allow(), typically from their ->probe hook.

If this xHC cannot signal wakeup, it shouldn't allow runtime PM in the
first place.  Simple as that.

The USB core has a function usb_enable_autosuspend() which does nothing
else but call pm_runtime_allow().  This is called in a couple of places,
I guess the relevant caller here is drivers/usb/core/hub.c:hub_probe().
I'd suggest to amend that function so that runtime PM isn't allowed
if the host controller can't signal plug events from pci_target_state().

This approach is better than returning -EBUSY from the ->runtime_suspend
hook because the PM core doesn't waste CPU cycles by repeatedly calling
->runtime_suspend in vain, always getting -EBUSY back.

HTH,

Lukas

> > 
> > On Wed, 5 Oct 2016, Mathias Nyman wrote:
> > 
> > > On 04.10.2016 17:11, Alan Stern wrote:
> > > > On Tue, 4 Oct 2016, Mathias Nyman wrote:
> > > >
> > > >> On 03.10.2016 23:54, Pierre de Villemereuil wrote:
> > > >>> Hi Mathias,
> > > >>>
> > > >>> Just to know: does that mean the firmware from Asus is faulty in here? Do you
> > > >>> think I should contact Asus about this?
> > > >>>
> > > >>
> > > >> Probably, _S0W, _DSM  and XFLT code for xHCI are useless in that ACPI DSDT firmware version.
> > > >>
> > > >> But we still want the driver to handle cases like this.
> > > >> Just wrote the patch.
> > > >> Adding Alan Stern to CC for PM sanity feedback on it:
> > > >>
> > > >> ---
> > > >>
> > > >> Author: Mathias Nyman <mathias.nyman@linux.intel.com>
> > > >> Date:   Tue Oct 4 13:07:59 2016 +0300
> > > >>
> > > >>       xhci: Prevent a non-responsive xhci suspend state.
> > > >>
> > > >>       ACPI may limit the lowest possible runtime suspend PCI D-state to D0.
> > > >>       If xHC is not capable of generating PME# events in D0 we end
> > > >>       up with a non-responsive runtime suspended host without PME# capability
> > > >>       and with interrupts disabled, unable to detect or wake up when a
> > > >>       new usb device is connected.
> > > >>
> > > >>       This was triggered on a ASUS TP301UA machine.
> > > >>
> > > >>       Reported-by: Pierre de Villemereuil <flyos@mailoo.org>
> > > >>       Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> > > >>
> > > >> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> > > >> index d7b0f97..08b021c 100644
> > > >> --- a/drivers/usb/host/xhci-pci.c
> > > >> +++ b/drivers/usb/host/xhci-pci.c
> > > >> @@ -396,6 +396,11 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
> > > >>           if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
> > > >>                   xhci_ssic_port_unused_quirk(hcd, true);
> > > >>
> > > >> +       /* Prevent a non-responsive PCI D0 state without PME# wake capability */
> > > >> +       if (pci_choose_state(pdev, PMSG_AUTO_SUSPEND) == PCI_D0)
> > > >> +               if (!pci_pme_capable(pdev, PCI_D0))
> > > >> +                       return -EBUSY;
> > > >> +
> > > >>           ret = xhci_suspend(xhci, do_wakeup);
> > > >>           if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED))
> > > >>                   xhci_ssic_port_unused_quirk(hcd, false);
> > > >
> > > > I've got three comments about this proposal.
> > > >
> > > > First, this logic should not apply during system suspend, only during
> > > > runtime suspend.  You don't want to abort putting a laptop to sleep
> > > > just because the xHCI controller can't generate wakeup signals.
> > > 
> > > Yes, I assume it would be ok change usb core to pass down something like
> > > pm_message_t to suspend_common() so that we could do this.
> > > hcd_pci_runetime_suspend()  -> suspend_common()  -> hcd->driver->pci_suspend()
> > > 
> > > Assuming this workaround should stay in xhci-pci.c
> > 
> > If necessary, it could be moved into hcd_pci_runtime_suspend().  But I 
> > would prefer to put it in the PCI core.
> > 
> > > > Second, this really has nothing to do with the D0 state.  The same
> > > > logic should apply to whatever state is chosen for runtime suspend: If
> > > > the controller can't generate PME# wakeup signals in that state then
> > > > the suspend should be aborted.
> > > 
> > > PCI code actually does this for us, it will walk down the D-states until
> > > it finds one that support PME#, but stop at D0 end return D0 even if D0
> > > does not support PME#.
> > 
> > That sounds like a bug.  Or rather, accepting D0 as the target state
> > when it doesn't support PME# is the bug.
> > 
> > > Unfortunately that is done in a static function in pci/pci.c.
> > > 
> > > static pci_power_t pci_target_state(struct pci_dev *dev)
> > > {
> > >          pci_power_t target_state = PCI_D3hot;
> > > 
> > > 	if (platform_pci_power_manageable(dev)) {
> > >                  /*
> > >                   * Call the platform to choose the target state of the device
> > >                   * and enable wake-up from this state if supported.
> > >                   */
> > >                  pci_power_t state = platform_pci_choose_state(dev);
> > > 
> > > 	        switch (state) {
> > > 	        case PCI_POWER_ERROR:
> > >                  case PCI_UNKNOWN:
> > >                          break;
> > >                  case PCI_D1:
> > >                  case PCI_D2:
> > >                          if (pci_no_d1d2(dev))
> > > 	                        break;
> > >                  default:
> > > 	                target_state = state;
> > >                  }
> > >          } else if (!dev->pm_cap) {
> > >                  target_state = PCI_D0;
> > >          } else if (device_may_wakeup(&dev->dev)) {
> > >                  /*
> > >                   * Find the deepest state from which the device can generate
> > >                   * wake-up events, make it the target state and enable device
> > >                   * to generate PME#.
> > >                   */
> > >                  if (dev->pme_support) {
> > >                          while (target_state
> > >                                && !(dev->pme_support & (1 << target_state)))
> > >                                  target_state--;
> > >                  }
> > >          }
> > > 
> > >          return target_state;
> > > }
> > > 
> > > The best I can do from xhci is call pci_choose_state() which will call
> > > platform_pci_choose_state(), but won't do the PME# checking and
> > > D-state decrement to D0 .
> > > 
> > > If pci_choose_state() returns D0 from a runtime suspend callback
> > > (and yes, should make sure its runtime suspend, not system suspend)
> > > I can pretty much assume pci_target_state will do the same.
> > > 
> > > >
> > > > Third, the same reasoning applies to every PCI device that relies on
> > > > PME#, not just to xHCI controllers.  Therefore the new code should be
> > > > added to drivers/pci/pci-driver.c:pci_pm_runtime_suspend(), not to
> > > > xhci-pci.c.
> > > 
> > > Yes, that would be the preferred solution.
> > > I was not sure we can do that. pci-driver.c pci_pm_runtime_suspend() will call
> > > pci_finish_runtime_suspend()
> > >    pci_target_state()        // returns D0,
> > >    pci_set_power_state()    // to D0, which is the state we probably are already in.
> > > 
> > > So it won't really do much. The device PCI device is disabled in usb hcd suspend
> > > hcd-pci.c:
> > > suspend_common()
> > >    ...
> > >    pci_disable_device(pci_dev)
> > > 
> > > Should we anyway disable runtime PM in PCI if the PCI device has wakeup enabled
> > > and the target state is D0 without PME# support?
> > 
> > First, the device_may_wakeup() test applies only to suspend suspend, 
> > not to runtime suspend.  The current PM design assumes that wakeup will 
> > always be enabled during runtime suspend (if the device supports it).
> > 
> > Second, there is a potential problem because some PCI devices have
> > other platform-based mechanisms for sending wakeup signals, instead of
> > using PME#.  Such devices probably don't support standard PCI wakeup at
> > all.  (A good example is the UHCI controllers on Intel's old chipsets.)
> > We don't want to prevent them from going into runtime suspend.
> > 
> > Now, maybe this isn't an issue -- I don't know enough about the details
> > of how the PCI core handles runtime suspend and how it coordinates with
> > the platform code.
> > 
> > Hopefully Bjorn can fill in the missing details.
> > 
> > Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-05 20:41     ` Lukas Wunner
@ 2016-10-06  7:24       ` Oliver Neukum
  2016-10-06 14:42       ` Alan Stern
  1 sibling, 0 replies; 15+ messages in thread
From: Oliver Neukum @ 2016-10-06  7:24 UTC (permalink / raw
  To: Lukas Wunner
  Cc: Bjorn Helgaas, Bjorn Helgaas, Rafael J. Wysocki, Mathias Nyman,
	Pierre de Villemereuil, Alan Stern, linux-pci, USB list

On Wed, 2016-10-05 at 22:41 +0200, Lukas Wunner wrote:
> The PCI core doesn't allow runtime PM by default.  Rather it calls
> pm_runtime_forbid() when the device is added (see pci_pm_init(),
> called
> indirectly from pci_device_add()).  PCI drivers need to explicitly
> call
> pm_runtime_allow(), typically from their ->probe hook.
> 
> If this xHC cannot signal wakeup, it shouldn't allow runtime PM in the
> first place.  Simple as that.

Presumably it can generate PME, just not in D0. The XHCI driver
could, albeit with a slight layering violation, check
that specific combination. But why put the code for a potentially
common problem into xhci?

	Regards
		Oliver

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-05 20:41     ` Lukas Wunner
  2016-10-06  7:24       ` Oliver Neukum
@ 2016-10-06 14:42       ` Alan Stern
  2016-10-08 10:31         ` Lukas Wunner
  1 sibling, 1 reply; 15+ messages in thread
From: Alan Stern @ 2016-10-06 14:42 UTC (permalink / raw
  To: Lukas Wunner
  Cc: Bjorn Helgaas, Mathias Nyman, Bjorn Helgaas,
	Pierre de Villemereuil, Oliver Neukum, USB list, linux-pci,
	Rafael J. Wysocki

On Wed, 5 Oct 2016, Lukas Wunner wrote:

> On Wed, Oct 05, 2016 at 01:54:01PM -0500, Bjorn Helgaas wrote:
> > On Wed, Oct 05, 2016 at 10:45:22AM -0400, Alan Stern wrote:
> > > In short, Pierre's USB host controller doesn't send wakeup signals from
> > > runtime suspend, because the firmware limits the runtime-suspend state
> > > to D0 and the controller can't issue PME# from the D0 state.  In this
> > > situation we would prefer to avoid suspending the controller at all,
> > > rather than have it go into runtime suspend and then stop working.
> 
> As Alan has correctly pointed out below, there are PCI devices which
> do not support PME but should still be runtime suspended, e.g. because
> they have some non-standard mechanism to sideband signal wakeup or
> because they can detect when they need to resume even if they're in
> a low-power state.
> 
> AFAIUI, this device should not be runtime suspended at all because it
> doesn't generate a PME interrupt and thus stays suspended forever.

No, as Oliver said, the device can generate a PME# signal.  It just 
can't do so from D0, and the firmware doesn't allow it to go into a 
deeper power-savings state.

> The PCI core doesn't allow runtime PM by default.  Rather it calls
> pm_runtime_forbid() when the device is added (see pci_pm_init(), called
> indirectly from pci_device_add()).  PCI drivers need to explicitly call
> pm_runtime_allow(), typically from their ->probe hook.

No, pm_runtime_allow() is generally called by userspace, via writing 
to the .../power/control file in sysfs.  Most drivers do not use it; it 
is a policy mechanism.  And drivers can't use it to _enforce_ anything, 
since the user can always override the setting.

> If this xHC cannot signal wakeup, it shouldn't allow runtime PM in the
> first place.  Simple as that.
> 
> The USB core has a function usb_enable_autosuspend() which does nothing
> else but call pm_runtime_allow().  This is called in a couple of places,
> I guess the relevant caller here is drivers/usb/core/hub.c:hub_probe().
> I'd suggest to amend that function so that runtime PM isn't allowed
> if the host controller can't signal plug events from pci_target_state().

usb_enable_autosuspend() is intended mainly for use with USB hubs.  
There is a policy decision in the USB stack that runtime PM will by 
default be allowed for hubs but not for other devices.

In any case, usb_enable_autosuspend() can't be used for host
controllers.  A host controller is not a USB device -- in this case it
is a PCI device.

> This approach is better than returning -EBUSY from the ->runtime_suspend
> hook because the PM core doesn't waste CPU cycles by repeatedly calling
> ->runtime_suspend in vain, always getting -EBUSY back.

I still think this belongs in the PCI core -- except for the difficulty
of determining whether a device can use a non-PME method for wakeup
signalling.  If that issue has a good solution then the PCI core could 
call pm_runtime_get_noresume() for devices that are capable of 
generating wakeup signals but not in any D-state that the firmware will 
allow for runtime suspend.

Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-06 14:42       ` Alan Stern
@ 2016-10-08 10:31         ` Lukas Wunner
  2016-10-10 21:06           ` Pierre de Villemereuil
  2016-10-11 15:18           ` Alan Stern
  0 siblings, 2 replies; 15+ messages in thread
From: Lukas Wunner @ 2016-10-08 10:31 UTC (permalink / raw
  To: Alan Stern
  Cc: Bjorn Helgaas, Mathias Nyman, Pierre de Villemereuil,
	Oliver Neukum, USB list, linux-pci, Rafael J. Wysocki

On Thu, Oct 06, 2016 at 10:42:14AM -0400, Alan Stern wrote:
> On Wed, 5 Oct 2016, Lukas Wunner wrote:
> > On Wed, Oct 05, 2016 at 01:54:01PM -0500, Bjorn Helgaas wrote:
> > > On Wed, Oct 05, 2016 at 10:45:22AM -0400, Alan Stern wrote:
> > > > In short, Pierre's USB host controller doesn't send wakeup signals from
> > > > runtime suspend, because the firmware limits the runtime-suspend state
> > > > to D0 and the controller can't issue PME# from the D0 state.  In this
> > > > situation we would prefer to avoid suspending the controller at all,
> > > > rather than have it go into runtime suspend and then stop working.
> > 
> > As Alan has correctly pointed out below, there are PCI devices which
> > do not support PME but should still be runtime suspended, e.g. because
> > they have some non-standard mechanism to sideband signal wakeup or
> > because they can detect when they need to resume even if they're in
> > a low-power state.
> > 
> > AFAIUI, this device should not be runtime suspended at all because it
> > doesn't generate a PME interrupt and thus stays suspended forever.
> 
> No, as Oliver said, the device can generate a PME# signal.  It just 
> can't do so from D0, and the firmware doesn't allow it to go into a 
> deeper power-savings state.

Okay.

> 
> > The PCI core doesn't allow runtime PM by default.  Rather it calls
> > pm_runtime_forbid() when the device is added (see pci_pm_init(), called
> > indirectly from pci_device_add()).  PCI drivers need to explicitly call
> > pm_runtime_allow(), typically from their ->probe hook.
> 
> No, pm_runtime_allow() is generally called by userspace, via writing 
> to the .../power/control file in sysfs.  Most drivers do not use it; it 
> is a policy mechanism.  And drivers can't use it to _enforce_ anything, 
> since the user can always override the setting.

Okay, I stand corrected.

> 
> > If this xHC cannot signal wakeup, it shouldn't allow runtime PM in the
> > first place.  Simple as that.
> > 
> I still think this belongs in the PCI core -- except for the difficulty
> of determining whether a device can use a non-PME method for wakeup
> signalling.  If that issue has a good solution then the PCI core could 
> call pm_runtime_get_noresume() for devices that are capable of 
> generating wakeup signals but not in any D-state that the firmware will 
> allow for runtime suspend.

The PCI core already calls pm_runtime_get_sync() before invoking the
->probe hook of a driver (see local_pci_probe()).  Drivers need to
explicitly release a runtime ref to allow their device to suspend.
For xhci-pci, this seems to happen in usb_hcd_pci_probe():

	if (pci_dev_run_wake(dev))
		pm_runtime_put_noidle(&dev->dev);

So you could either modify the if-condition if you want to change the
behaviour for XHCI devices only, or if you want to change it in general,
add something like this to pci_dev_run_wake():

	/* PME capable in principle, but not from the intended sleep state */
	if (dev->pme_support && !pci_pme_capable(dev, pci_target_state(dev)))
		return false;

I've briefly looked over the callers of pci_dev_run_wake() and the above
seems safe but you should double-check them.

Best regards,

Lukas

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-08 10:31         ` Lukas Wunner
@ 2016-10-10 21:06           ` Pierre de Villemereuil
  2016-10-11 15:18           ` Alan Stern
  1 sibling, 0 replies; 15+ messages in thread
From: Pierre de Villemereuil @ 2016-10-10 21:06 UTC (permalink / raw
  To: Lukas Wunner
  Cc: Alan Stern, Bjorn Helgaas, Mathias Nyman, Oliver Neukum, USB list,
	linux-pci, Rafael J. Wysocki

Hi guys!

Thanks for your efforts for fixing this bug! (The workaround of 
loading the kernel with "usbcore.autosuspend=-1" works very fine for 
me now).

Meanwhile, Asus gave me the expected response:

"Hello Mr. De Villemereuil,

Thank you for having solicited the ASUS Technical Support.

A reading your email I understand that your PC has a problem with 
the firmware bios from linux report.

Unfortunately, Linux is not part of our areas and we are not trained 
on.

So we have no confirmation on the Linux of the report.

Thank you for your understanding and wish you a good day."

I attached the explanation from Mathias about what is going on, but 
apparently if a bug of THEIR firmware is discovered on Linux, they 
simply freak out and say they don't do Linux (kinda expected...). 

So, I guess they won't release a fix for that... Makes your effort 
even more relevant since they sell quite a lot of computers and 
motherboards.

Cheers,
Pierre.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-08 10:31         ` Lukas Wunner
  2016-10-10 21:06           ` Pierre de Villemereuil
@ 2016-10-11 15:18           ` Alan Stern
  2016-10-11 20:27             ` Pierre de Villemereuil
  2016-10-20 10:01             ` Lukas Wunner
  1 sibling, 2 replies; 15+ messages in thread
From: Alan Stern @ 2016-10-11 15:18 UTC (permalink / raw
  To: Lukas Wunner
  Cc: Bjorn Helgaas, Mathias Nyman, Pierre de Villemereuil,
	Oliver Neukum, USB list, linux-pci, Rafael J. Wysocki

On Sat, 8 Oct 2016, Lukas Wunner wrote:

> The PCI core already calls pm_runtime_get_sync() before invoking the
> ->probe hook of a driver (see local_pci_probe()).  Drivers need to
> explicitly release a runtime ref to allow their device to suspend.
> For xhci-pci, this seems to happen in usb_hcd_pci_probe():
> 
> 	if (pci_dev_run_wake(dev))
> 		pm_runtime_put_noidle(&dev->dev);
> 
> So you could either modify the if-condition if you want to change the
> behaviour for XHCI devices only, or if you want to change it in general,
> add something like this to pci_dev_run_wake():
> 
> 	/* PME capable in principle, but not from the intended sleep state */
> 	if (dev->pme_support && !pci_pme_capable(dev, pci_target_state(dev)))
> 		return false;
> 
> I've briefly looked over the callers of pci_dev_run_wake() and the above
> seems safe but you should double-check them.

That seems like a good suggestion.  The patch is below; Pierre, can you 
test it?  This should remove the need to set the USB autosuspend module 
parameter to -1.

Alan Stern



Index: usb-4.x/drivers/pci/pci.c
===================================================================
--- usb-4.x.orig/drivers/pci/pci.c
+++ usb-4.x/drivers/pci/pci.c
@@ -2064,6 +2064,10 @@ bool pci_dev_run_wake(struct pci_dev *de
 	if (!dev->pme_support)
 		return false;
 
+	/* PME-capable in principle, but not from the intended sleep state */
+	if (!pci_pme_capable(dev, pci_target_state(dev)))
+		return false;
+
 	while (bus->parent) {
 		struct pci_dev *bridge = bus->self;
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-11 15:18           ` Alan Stern
@ 2016-10-11 20:27             ` Pierre de Villemereuil
  2016-10-12 18:23               ` Alan Stern
  2016-10-20 10:01             ` Lukas Wunner
  1 sibling, 1 reply; 15+ messages in thread
From: Pierre de Villemereuil @ 2016-10-11 20:27 UTC (permalink / raw
  To: Alan Stern
  Cc: Lukas Wunner, Bjorn Helgaas, Mathias Nyman, Oliver Neukum,
	USB list, linux-pci, Rafael J. Wysocki

Hi!

I'm sorry, I'm not savvy enough to know what to do with this (I know=20
basics on how to code and compile, but I'm no dev). Could someone=20
guide me through it?

I gather this patch needs to be applied to some kernel module code=20
which needs to be compiled and reloaded into my current kernel,=20
right?

Sorry to let you down...

Cheers,
Pierre.

Le mardi 11 octobre 2016, 11:18:28 NZDT Alan Stern a =C3=A9crit :
> On Sat, 8 Oct 2016, Lukas Wunner wrote:
> > The PCI core already calls pm_runtime_get_sync() before invoking=20
the
> > ->probe hook of a driver (see local_pci_probe()).  Drivers need=20
to
> > explicitly release a runtime ref to allow their device to=20
suspend.
> >=20
> > For xhci-pci, this seems to happen in usb_hcd_pci_probe():
> > 	if (pci_dev_run_wake(dev))
> > =09
> > 		pm_runtime_put_noidle(&dev->dev);
> >=20
> > So you could either modify the if-condition if you want to=20
change the
> > behaviour for XHCI devices only, or if you want to change it in=20
general,
> >=20
> > add something like this to pci_dev_run_wake():
> > 	/* PME capable in principle, but not from the intended sleep=20
state */
> > 	if (dev->pme_support && !pci_pme_capable(dev,=20
pci_target_state(dev)))
> > =09
> > 		return false;
> >=20
> > I've briefly looked over the callers of pci_dev_run_wake() and=20
the above
> > seems safe but you should double-check them.
>=20
> That seems like a good suggestion.  The patch is below; Pierre,=20
can you
> test it?  This should remove the need to set the USB autosuspend=20
module
> parameter to -1.
>=20
> Alan Stern
>=20
>=20
>=20
> Index: usb-4.x/drivers/pci/pci.c
>=20
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- usb-4.x.orig/drivers/pci/pci.c
> +++ usb-4.x/drivers/pci/pci.c
> @@ -2064,6 +2064,10 @@ bool pci_dev_run_wake(struct pci_dev *de
>  	if (!dev->pme_support)
>  		return false;
>=20
> +	/* PME-capable in principle, but not from the intended sleep=20
state */
> +	if (!pci_pme_capable(dev, pci_target_state(dev)))
> +		return false;
> +
>  	while (bus->parent) {
>  		struct pci_dev *bridge =3D bus->self;

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-11 20:27             ` Pierre de Villemereuil
@ 2016-10-12 18:23               ` Alan Stern
  2016-10-13 20:58                 ` Pierre de Villemereuil
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Stern @ 2016-10-12 18:23 UTC (permalink / raw
  To: Pierre de Villemereuil
  Cc: Lukas Wunner, Bjorn Helgaas, Mathias Nyman, Oliver Neukum,
	USB list, linux-pci, Rafael J. Wysocki

On Wed, 12 Oct 2016, Pierre de Villemereuil wrote:

> Hi!
> 
> I'm sorry, I'm not savvy enough to know what to do with this (I know 
> basics on how to code and compile, but I'm no dev). Could someone 
> guide me through it?
> 
> I gather this patch needs to be applied to some kernel module code 
> which needs to be compiled and reloaded into my current kernel, 
> right?

More likely you'll have to rebuild an entire new kernel, not just a 
single module.

Search the support site for the distribution you are using.  It ought
to contain reasonably thorough instructions on how to build and install
your own version of their kernel.

Once you know how to do all that, I can tell you how the patch should
be applied -- that's the easy part.

Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-12 18:23               ` Alan Stern
@ 2016-10-13 20:58                 ` Pierre de Villemereuil
  2016-10-13 21:11                   ` Alan Stern
  0 siblings, 1 reply; 15+ messages in thread
From: Pierre de Villemereuil @ 2016-10-13 20:58 UTC (permalink / raw
  To: Alan Stern
  Cc: Lukas Wunner, Bjorn Helgaas, Mathias Nyman, Oliver Neukum,
	USB list, linux-pci, Rafael J. Wysocki

Hi!

I've branched the kernel package on the OpenSUSE Build Server, I'll=20
try to apply the patch there (this ought to be cleanest method).

Starting from the root of the kernel tarball, the patch should be=20
applied to drivers/pci/pci.c, am I right?

Cheers,
Pierre.


Le mercredi 12 octobre 2016, 14:23:35 NZDT Alan Stern a =C3=A9crit :
> On Wed, 12 Oct 2016, Pierre de Villemereuil wrote:
> > Hi!
> >=20
> > I'm sorry, I'm not savvy enough to know what to do with this (I=20
know
> > basics on how to code and compile, but I'm no dev). Could=20
someone
> > guide me through it?
> >=20
> > I gather this patch needs to be applied to some kernel module=20
code
> > which needs to be compiled and reloaded into my current kernel,
> > right?
>=20
> More likely you'll have to rebuild an entire new kernel, not just=20
a
> single module.
>=20
> Search the support site for the distribution you are using.  It=20
ought
> to contain reasonably thorough instructions on how to build and=20
install
> your own version of their kernel.
>=20
> Once you know how to do all that, I can tell you how the patch=20
should
> be applied -- that's the easy part.
>=20
> Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-13 20:58                 ` Pierre de Villemereuil
@ 2016-10-13 21:11                   ` Alan Stern
  2016-10-14 21:46                     ` Pierre de Villemereuil
  0 siblings, 1 reply; 15+ messages in thread
From: Alan Stern @ 2016-10-13 21:11 UTC (permalink / raw
  To: Pierre de Villemereuil
  Cc: Lukas Wunner, Bjorn Helgaas, Mathias Nyman, Oliver Neukum,
	USB list, linux-pci, Rafael J. Wysocki

On Fri, 14 Oct 2016, Pierre de Villemereuil wrote:

> Hi!
> 
> I've branched the kernel package on the OpenSUSE Build Server, I'll 
> try to apply the patch there (this ought to be cleanest method).
> 
> Starting from the root of the kernel tarball, the patch should be 
> applied to drivers/pci/pci.c, am I right?

You just cd to the top directory of the kernel source, and do

	patch -p1 <filename

where "filename" is the contents of the email message containing the 
patch.  Or if you want, since the patch is so small, you can simply 
edit the file by hand to add in the new lines.

Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-13 21:11                   ` Alan Stern
@ 2016-10-14 21:46                     ` Pierre de Villemereuil
  0 siblings, 0 replies; 15+ messages in thread
From: Pierre de Villemereuil @ 2016-10-14 21:46 UTC (permalink / raw
  To: Alan Stern
  Cc: Lukas Wunner, Bjorn Helgaas, Mathias Nyman, Oliver Neukum,
	USB list, linux-pci, Rafael J. Wysocki

Hi!

I've managed to build the patched kernel on OBS, install the package=20
and boot! \o/

And I can confirm that the patch indeed fix the issue!

The kernel was booted without the usb.autosuspend=3D-1 option, of=20
course.

Thank you guys!

Cheers,
Pierre.

Le jeudi 13 octobre 2016, 17:11:46 NZDT Alan Stern a =C3=A9crit :
> On Fri, 14 Oct 2016, Pierre de Villemereuil wrote:
> > Hi!
> >=20
> > I've branched the kernel package on the OpenSUSE Build Server,=20
I'll
> > try to apply the patch there (this ought to be cleanest method).
> >=20
> > Starting from the root of the kernel tarball, the patch should=20
be
> > applied to drivers/pci/pci.c, am I right?
>=20
> You just cd to the top directory of the kernel source, and do
>=20
> 	patch -p1 <filename
>=20
> where "filename" is the contents of the email message containing=20
the
> patch.  Or if you want, since the patch is so small, you can=20
simply
> edit the file by hand to add in the new lines.
>=20
> Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-11 15:18           ` Alan Stern
  2016-10-11 20:27             ` Pierre de Villemereuil
@ 2016-10-20 10:01             ` Lukas Wunner
  2016-10-20 13:57               ` Alan Stern
  1 sibling, 1 reply; 15+ messages in thread
From: Lukas Wunner @ 2016-10-20 10:01 UTC (permalink / raw
  To: Alan Stern
  Cc: Bjorn Helgaas, Mathias Nyman, Pierre de Villemereuil,
	Oliver Neukum, USB list, linux-pci, Rafael J. Wysocki

On Tue, Oct 11, 2016 at 11:18:28AM -0400, Alan Stern wrote:
> On Sat, 8 Oct 2016, Lukas Wunner wrote:
> > The PCI core already calls pm_runtime_get_sync() before invoking the
> > ->probe hook of a driver (see local_pci_probe()).  Drivers need to
> > explicitly release a runtime ref to allow their device to suspend.
> > For xhci-pci, this seems to happen in usb_hcd_pci_probe():
> > 
> > 	if (pci_dev_run_wake(dev))
> > 		pm_runtime_put_noidle(&dev->dev);
> > 
> > So you could either modify the if-condition if you want to change the
> > behaviour for XHCI devices only, or if you want to change it in general,
> > add something like this to pci_dev_run_wake():
> > 
> > 	/* PME capable in principle, but not from the intended sleep state */
> > 	if (dev->pme_support && !pci_pme_capable(dev, pci_target_state(dev)))
> > 		return false;
> > 
> > I've briefly looked over the callers of pci_dev_run_wake() and the above
> > seems safe but you should double-check them.
> 
> That seems like a good suggestion.  The patch is below; Pierre, can you 
> test it?  This should remove the need to set the USB autosuspend module 
> parameter to -1.

Alan, how do we proceed with this?  Are you going to submit a patch
(with commit message, tags and all) to linux-pci@ or would you prefer
me to do that?  I just went over the callers of pci_dev_run_wake()
once more and the patch still looks safe to me.

Thanks,

Lukas

> 
> Index: usb-4.x/drivers/pci/pci.c
> ===================================================================
> --- usb-4.x.orig/drivers/pci/pci.c
> +++ usb-4.x/drivers/pci/pci.c
> @@ -2064,6 +2064,10 @@ bool pci_dev_run_wake(struct pci_dev *de
>  	if (!dev->pme_support)
>  		return false;
>  
> +	/* PME-capable in principle, but not from the intended sleep state */
> +	if (!pci_pme_capable(dev, pci_target_state(dev)))
> +		return false;
> +
>  	while (bus->parent) {
>  		struct pci_dev *bridge = bus->self;
>  

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: USB hot-plug not working (ASUS TP301UA-C4028T)
  2016-10-20 10:01             ` Lukas Wunner
@ 2016-10-20 13:57               ` Alan Stern
  0 siblings, 0 replies; 15+ messages in thread
From: Alan Stern @ 2016-10-20 13:57 UTC (permalink / raw
  To: Lukas Wunner
  Cc: Bjorn Helgaas, Mathias Nyman, Pierre de Villemereuil,
	Oliver Neukum, USB list, linux-pci, Rafael J. Wysocki

On Thu, 20 Oct 2016, Lukas Wunner wrote:

> On Tue, Oct 11, 2016 at 11:18:28AM -0400, Alan Stern wrote:
> > On Sat, 8 Oct 2016, Lukas Wunner wrote:
> > > The PCI core already calls pm_runtime_get_sync() before invoking the
> > > ->probe hook of a driver (see local_pci_probe()).  Drivers need to
> > > explicitly release a runtime ref to allow their device to suspend.
> > > For xhci-pci, this seems to happen in usb_hcd_pci_probe():
> > > 
> > > 	if (pci_dev_run_wake(dev))
> > > 		pm_runtime_put_noidle(&dev->dev);
> > > 
> > > So you could either modify the if-condition if you want to change the
> > > behaviour for XHCI devices only, or if you want to change it in general,
> > > add something like this to pci_dev_run_wake():
> > > 
> > > 	/* PME capable in principle, but not from the intended sleep state */
> > > 	if (dev->pme_support && !pci_pme_capable(dev, pci_target_state(dev)))
> > > 		return false;
> > > 
> > > I've briefly looked over the callers of pci_dev_run_wake() and the above
> > > seems safe but you should double-check them.
> > 
> > That seems like a good suggestion.  The patch is below; Pierre, can you 
> > test it?  This should remove the need to set the USB autosuspend module 
> > parameter to -1.
> 
> Alan, how do we proceed with this?  Are you going to submit a patch
> (with commit message, tags and all) to linux-pci@ or would you prefer
> me to do that?  I just went over the callers of pci_dev_run_wake()
> once more and the patch still looks safe to me.

Thanks for checking.  I intend to submit it soon; there just hasn't 
been enough free time this week.  :-(

Alan Stern

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2016-10-20 13:57 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <57F4B9C5.60600@linux.intel.com>
2016-10-05 14:45 ` USB hot-plug not working (ASUS TP301UA-C4028T) Alan Stern
2016-10-05 18:54   ` Bjorn Helgaas
2016-10-05 20:41     ` Lukas Wunner
2016-10-06  7:24       ` Oliver Neukum
2016-10-06 14:42       ` Alan Stern
2016-10-08 10:31         ` Lukas Wunner
2016-10-10 21:06           ` Pierre de Villemereuil
2016-10-11 15:18           ` Alan Stern
2016-10-11 20:27             ` Pierre de Villemereuil
2016-10-12 18:23               ` Alan Stern
2016-10-13 20:58                 ` Pierre de Villemereuil
2016-10-13 21:11                   ` Alan Stern
2016-10-14 21:46                     ` Pierre de Villemereuil
2016-10-20 10:01             ` Lukas Wunner
2016-10-20 13:57               ` Alan Stern

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.