linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Eric Blau <eblau@eblau.com>
Cc: Alan Stern <stern@rowland.harvard.edu>,
	linux-usb@vger.kernel.org, Ivan Mironov <mironov.ivan@gmail.com>
Subject: [regression] USB power management failure to suspend / high CPU usage
Date: Wed, 20 Feb 2019 19:28:55 +0200	[thread overview]
Message-ID: <5d9aae37-36fb-7579-0a66-ce957d61c3f4@linux.intel.com> (raw)

On 14.2.2019 20.04, Eric Blau wrote:
> On Thu, Feb 14, 2019 at 9:56 AM Mathias Nyman
> <mathias.nyman@linux.intel.com> wrote:
>>
>>> Thanks for looking into this, Mathias. Now that you point this out, on
>>> older kernels where suspend and resume works, I noticed the following
>>> log messages emitted when resuming from suspend:
>>>
>>> Feb 06 18:58:05 eric-macbookpro kernel: usb usb2-port3: Cannot enable.
>>> Maybe the USB cable is bad?
>>
>> Attached a testpatch that should react to ports stuck in polling state,
>> and warm reset them.
>>
>> It doesn't limit the numbers of reset tries, or allow system suspend with ports
>> stuck in polling state, but I'd like to know how the MacBook reacts to it
>>
>> Can you test it with debugging enabled?
> 
> Hi Mathias,
> 
> Thanks for the patch. I tested it against 4.20.8 and got a couple
> successful suspends but on the third attempt I got the same failure
> again. I noticed after the first suspend/resume, the card reader
> showed as "Link:Compliance" but on later attempts it showed stuck in
> Polling again.
> 
> I've attached the logs with debugging enabled.
> 

Thanks, logs show that several resets won't recover the card reader.

I'm taking a different approach, USB3 ports in polling state should
automatically move to connected/enabled. So instead of preventing
suspend if a port is found in polling I'll let it try to finish link
training for some time, and then just continue with suspend if it fails.

Patch attached.

This won't fix the broken card reader, but should allow your MacBook to suspend.
After this we can start looking at fixing the card reader, Ivan Miranov sent some
proposal for this.

-Mathias

From 444cab4f41c79c5a04d1fc8939b450c89dc64768 Mon Sep 17 00:00:00 2001
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Wed, 20 Feb 2019 16:10:54 +0200
Subject: [PATCH 1/2] xhci: Don't let USB3 ports stuck in polling state prevent
 suspend

Commit 2f31a67f01a8 ("usb: xhci: Prevent bus suspend if a port connect
change or polling state is detected") was intended to prevent ports that
were still link training from being forced to U3 suspend state mid
enumeration.
This solved enumeration issues for devices with slow link training.

Turns out some devices are stuck in the link training/polling state,
and thus that patch will prevent suspend completely for these devices.
This is seen with USB3 card readers in some MacBooks.

Instead of preventing suspend, give some time to complete the link
training. On successful training the port will end up as connected
and enabled.
If port instead is stuck in link training the bus suspend will continue
suspending after 360ms (10 * 36ms) timeout (tPollingLFPSTimeout).

Original patch was sent to stable, this one should go there as well

Fixes: 2f31a67f01a8 ("usb: xhci: Prevent bus suspend if a port connect change or polling state is detected")
Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-hub.c | 19 ++++++++++++-------
 drivers/usb/host/xhci.h     |  8 ++++++++
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index e2eece6..96a7405 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1545,20 +1545,25 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 	port_index = max_ports;
 	while (port_index--) {
 		u32 t1, t2;
-
+		int retries = 10;
+retry:
 		t1 = readl(ports[port_index]->addr);
 		t2 = xhci_port_state_to_neutral(t1);
 		portsc_buf[port_index] = 0;
 
-		/* Bail out if a USB3 port has a new device in link training */
-		if ((hcd->speed >= HCD_USB3) &&
+		/*
+		 * Give a USB3 port in link training time to finish, but don't
+		 * prevent suspend as port might be stuck
+		 */
+		if ((hcd->speed >= HCD_USB3) && retries-- &&
 		    (t1 & PORT_PLS_MASK) == XDEV_POLLING) {
-			bus_state->bus_suspended = 0;
 			spin_unlock_irqrestore(&xhci->lock, flags);
-			xhci_dbg(xhci, "Bus suspend bailout, port in polling\n");
-			return -EBUSY;
+			msleep(XHCI_PORT_POLLING_LFPS_TIME);
+			spin_lock_irqsave(&xhci->lock, flags);
+			xhci_dbg(xhci, "port %d polling in bus suspend, waiting\n",
+				 port_index);
+			goto retry;
 		}
-
 		/* suspend ports in U0, or bail out for new connect changes */
 		if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) {
 			if ((t1 & PORT_CSC) && wake_enabled) {
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 652dc36..9334cde 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -452,6 +452,14 @@ struct xhci_op_regs {
  */
 #define XHCI_DEFAULT_BESL	4
 
+/*
+ * USB3 specification define a 360ms tPollingLFPSTiemout for USB3 ports
+ * to complete link training. usually link trainig completes much faster
+ * so check status 10 times with 36ms sleep in places we need to wait for
+ * polling to complete.
+ */
+#define XHCI_PORT_POLLING_LFPS_TIME  36
+
 /**
  * struct xhci_intr_reg - Interrupt Register Set
  * @irq_pending:	IMAN - Interrupt Management Register.  Used to enable
-- 
2.7.4


             reply	other threads:[~2019-02-20 17:28 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-20 17:28 Mathias Nyman [this message]
  -- strict thread matches above, loose matches on Subject: below --
2019-03-21 15:40 [regression] USB power management failure to suspend / high CPU usage Eric Blau
2019-03-21 14:54 Mathias Nyman
2019-03-21 13:32 Eric Blau
2019-03-04 15:53 Eric Blau
2019-03-04 15:15 Mathias Nyman
2019-02-25 22:11 Ivan Mironov
2019-02-22  1:05 Eric Blau
2019-02-14 14:57 Mathias Nyman

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=5d9aae37-36fb-7579-0a66-ce957d61c3f4@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=eblau@eblau.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=mironov.ivan@gmail.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).