mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lu Baolu <baolu.lu@linux.intel.com>
To: Mathias Nyman <mathias.nyman@linux.intel.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Lu Baolu <baolu.lu@linux.intel.com>
Subject: [PATCH 2/4] usb: xhci: remove CRR polling in xhci_abort_cmd_ring()
Date: Fri, 23 Dec 2016 14:52:56 +0800	[thread overview]
Message-ID: <1482475978-18203-3-git-send-email-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <1482475978-18203-1-git-send-email-baolu.lu@linux.intel.com>

xHCI driver aborts the command ring by setting CA (Command
Abort) bit in the command register. With this setting, host
should abort all command executions and generate a command
completion event with the completion code set to command
ring stopped. Software should time the completion of command
abort by checking the CRR (Command Ring Running) and waiting
for the command ring stopped event.

Current xhci_abort_cmd_ring() does this in the following
way: setting CA bit; busy polling CRR bit until it negates;
sleep and wait for the command ring stopped event. This is
not an efficient way since cpu cycles are wasted on polling
registers. This patch removes polling for CRR (Command Ring
Running). Wait for completion, and check CRR if completion
times out is enough.

Suggested-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 49 ++++++++++++++++++++++----------------------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e3bcf6d..5935dce 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -323,7 +323,6 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long *flags)
 {
 	unsigned long timeleft;
 	u64 temp_64;
-	int ret;
 
 	xhci_dbg(xhci, "Abort command ring\n");
 
@@ -333,34 +332,34 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long *flags)
 	xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
 			&xhci->op_regs->cmd_ring);
 
-	/* Section 4.6.1.2 of xHCI 1.0 spec says software should
-	 * time the completion od all xHCI commands, including
-	 * the Command Abort operation. If software doesn't see
-	 * CRR negated in a timely manner (e.g. longer than 5
-	 * seconds), then it should assume that the there are
-	 * larger problems with the xHC and assert HCRST.
-	 */
-	ret = xhci_handshake(&xhci->op_regs->cmd_ring,
-			CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
-	if (ret < 0) {
-		xhci_err(xhci,
-			 "Stop command ring failed, maybe the host is dead\n");
-		xhci->xhc_state |= XHCI_STATE_DYING;
-		xhci_halt(xhci);
-		return -ESHUTDOWN;
-	}
-	/*
-	 * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
-	 * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
-	 * but the completion event in never sent. Wait 2 secs (arbitrary
-	 * number) to handle those cases after negation of CMD_RING_RUNNING.
-	 */
 	spin_unlock_irqrestore(&xhci->lock, *flags);
 	timeleft = wait_for_completion_timeout(&xhci->cmd_ring_stop_completion,
-					       2 * HZ);
+					       XHCI_CMD_DEFAULT_TIMEOUT);
 	spin_lock_irqsave(&xhci->lock, *flags);
 	if (!timeleft) {
-		xhci_dbg(xhci, "No stop event for abort, ring start fail?\n");
+		/* Section 4.6.1.2 of xHCI 1.0 spec says software should
+		 * time the completion of all xHCI commands, including
+		 * the Command Abort operation. If software doesn't see
+		 * CRR negated in a timely manner (e.g. longer than 5
+		 * seconds), then it should assume that the there are
+		 * larger problems with the xHC and assert HCRST.
+		 */
+		temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+		if (temp_64 & CMD_RING_RUNNING) {
+			xhci_err(xhci,
+				 "Stop command ring failed, maybe the host is dead\n");
+			xhci->xhc_state |= XHCI_STATE_DYING;
+			xhci_halt(xhci);
+			return -ESHUTDOWN;
+		}
+
+		/*
+		 * Writing the CMD_RING_ABORT bit should cause a cmd
+		 * completion event, however on some hosts the bit is
+		 * correctly cleared but the completion event is never
+		 * sent.
+		 */
+		xhci_warn(xhci, "No stop event for abort, ring start fail?\n");
 		xhci_cleanup_command_queue(xhci);
 	} else {
 		xhci_handle_stopped_cmd_ring(xhci, xhci_next_queued_cmd(xhci));
-- 
2.1.4

  parent reply	other threads:[~2016-12-23  6:53 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-23  6:52 [PATCH 0/4] refactor command timeout handling Lu Baolu
2016-12-23  6:52 ` [PATCH 1/4] usb: xhci: remove unnecessary second abort try Lu Baolu
2016-12-23  6:52 ` Lu Baolu [this message]
2016-12-23  6:52 ` [PATCH 3/4] usb: xhci: add XHCI_MISS_CA_EVENT quirk bit Lu Baolu
2016-12-23  6:52 ` [PATCH 4/4] usb: xhci: warn on command timeout in stopped command ring Lu Baolu
2016-12-23  9:49   ` Sergei Shtylyov

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=1482475978-18203-3-git-send-email-baolu.lu@linux.intel.com \
    --to=baolu.lu@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@linux.intel.com \
    /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

Powered by JetHome