linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bjorn Helgaas <helgaas@kernel.org>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Mathias Nyman <mathias.nyman@linux.intel.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Pierre de Villemereuil <flyos@mailoo.org>,
	Oliver Neukum <oneukum@suse.com>,
	USB list <linux-usb@vger.kernel.org>,
	linux-pci@vger.kernel.org,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Lukas Wunner <lukas@wunner.de>
Subject: Re: USB hot-plug not working (ASUS TP301UA-C4028T)
Date: Wed, 5 Oct 2016 13:54:01 -0500	[thread overview]
Message-ID: <20161005185401.GA30607@localhost> (raw)
In-Reply-To: <Pine.LNX.4.44L0.1610051030310.1880-100000@iolanthe.rowland.org>

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

  reply	other threads:[~2016-10-05 18:54 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161005185401.GA30607@localhost \
    --to=helgaas@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=flyos@mailoo.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=mathias.nyman@linux.intel.com \
    --cc=oneukum@suse.com \
    --cc=rafael.j.wysocki@intel.com \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).