Linux USB
 help / color / mirror / Atom feed
From: Wesley Cheng <quic_wcheng@quicinc.com>
To: <mathias.nyman@intel.com>, <gregkh@linuxfoundation.org>,
	<lgirdwood@gmail.com>, <broonie@kernel.org>, <perex@perex.cz>,
	<tiwai@suse.com>, <agross@kernel.org>, <andersson@kernel.org>,
	<konrad.dybcio@linaro.org>, <robh+dt@kernel.org>,
	<krzysztof.kozlowski+dt@linaro.org>, <conor+dt@kernel.org>,
	<srinivas.kandagatla@linaro.org>, <bgoswami@quicinc.com>,
	<Thinh.Nguyen@synopsys.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-usb@vger.kernel.org>,
	<alsa-devel@alsa-project.org>, <linux-arm-msm@vger.kernel.org>,
	<devicetree@vger.kernel.org>,
	Mathias Nyman <mathias.nyman@linux.intel.com>,
	Wesley Cheng <quic_wcheng@quicinc.com>
Subject: [PATCH v7 02/33] xhci: add helper to stop endpoint and wait for completion
Date: Thu, 21 Sep 2023 14:48:12 -0700	[thread overview]
Message-ID: <20230921214843.18450-3-quic_wcheng@quicinc.com> (raw)
In-Reply-To: <20230921214843.18450-1-quic_wcheng@quicinc.com>

From: Mathias Nyman <mathias.nyman@linux.intel.com>

Expose xhci_stop_endpoint_sync() which is a synchronous variant of
xhci_queue_stop_endpoint().  This is useful for client drivers that are
using the secondary interrupters, and need to stop/clean up the current
session.  The stop endpoint command handler will also take care of cleaning
up the ring.

Modifications to repurpose the new API into existing stop endpoint
sequences was implemented by Wesley Cheng.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Co-developed-by: Wesley Cheng <quic_wcheng@quicinc.com>
Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
---
 drivers/usb/host/xhci-hub.c | 29 +++---------------
 drivers/usb/host/xhci.c     | 60 +++++++++++++++++++++++++++----------
 drivers/usb/host/xhci.h     |  2 ++
 3 files changed, 50 insertions(+), 41 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0054d02239e2..2f7309bdc922 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -489,7 +489,6 @@ EXPORT_SYMBOL_GPL(xhci_find_slot_id_by_port);
 static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 {
 	struct xhci_virt_device *virt_dev;
-	struct xhci_command *cmd;
 	unsigned long flags;
 	int ret;
 	int i;
@@ -501,10 +500,6 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 
 	trace_xhci_stop_device(virt_dev);
 
-	cmd = xhci_alloc_command(xhci, true, GFP_NOIO);
-	if (!cmd)
-		return -ENOMEM;
-
 	spin_lock_irqsave(&xhci->lock, flags);
 	for (i = LAST_EP_INDEX; i > 0; i--) {
 		if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) {
@@ -521,7 +516,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 			if (!command) {
 				spin_unlock_irqrestore(&xhci->lock, flags);
 				ret = -ENOMEM;
-				goto cmd_cleanup;
+				goto out;
 			}
 
 			ret = xhci_queue_stop_endpoint(xhci, command, slot_id,
@@ -529,30 +524,14 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 			if (ret) {
 				spin_unlock_irqrestore(&xhci->lock, flags);
 				xhci_free_command(xhci, command);
-				goto cmd_cleanup;
+				goto out;
 			}
 		}
 	}
-	ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);
-	if (ret) {
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		goto cmd_cleanup;
-	}
-
-	xhci_ring_cmd_db(xhci);
 	spin_unlock_irqrestore(&xhci->lock, flags);
+	ret = xhci_stop_endpoint_sync(xhci, &virt_dev->eps[0], suspend);
 
-	/* Wait for last stop endpoint command to finish */
-	wait_for_completion(cmd->completion);
-
-	if (cmd->status == COMP_COMMAND_ABORTED ||
-	    cmd->status == COMP_COMMAND_RING_STOPPED) {
-		xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
-		ret = -ETIME;
-	}
-
-cmd_cleanup:
-	xhci_free_command(xhci, cmd);
+out:
 	return ret;
 }
 
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3fd2b58ee1d3..163d533d6200 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2758,6 +2758,46 @@ static int xhci_reserve_bandwidth(struct xhci_hcd *xhci,
 	return -ENOMEM;
 }
 
+/*
+ * Synchronous XHCI stop endpoint helper.  Issues the stop endpoint command and
+ * waits for the command completion before returning.
+ */
+int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, int suspend)
+{
+	struct xhci_command *command;
+	unsigned long flags;
+	int ret;
+
+	command = xhci_alloc_command(xhci, true, GFP_KERNEL);
+	if (!command)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&xhci->lock, flags);
+	ret = xhci_queue_stop_endpoint(xhci, command, ep->vdev->slot_id,
+				       ep->ep_index, suspend);
+	if (ret < 0) {
+		spin_unlock_irqrestore(&xhci->lock, flags);
+		goto out;
+	}
+
+	xhci_ring_cmd_db(xhci);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	ret = wait_for_completion_timeout(command->completion, msecs_to_jiffies(3000));
+	if (!ret)
+		xhci_warn(xhci, "%s: Unable to stop endpoint.\n",
+				__func__);
+
+	if (command->status == COMP_COMMAND_ABORTED ||
+	    command->status == COMP_COMMAND_RING_STOPPED) {
+		xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
+		ret = -ETIME;
+	}
+out:
+	xhci_free_command(xhci, command);
+
+	return ret;
+}
 
 /* Issue a configure endpoint command or evaluate context command
  * and wait for it to finish.
@@ -3078,7 +3118,7 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
 	struct xhci_virt_device *vdev;
 	struct xhci_virt_ep *ep;
 	struct xhci_input_control_ctx *ctrl_ctx;
-	struct xhci_command *stop_cmd, *cfg_cmd;
+	struct xhci_command *cfg_cmd;
 	unsigned int ep_index;
 	unsigned long flags;
 	u32 ep_flag;
@@ -3118,10 +3158,6 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
 	if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG)
 		return;
 
-	stop_cmd = xhci_alloc_command(xhci, true, GFP_NOWAIT);
-	if (!stop_cmd)
-		return;
-
 	cfg_cmd = xhci_alloc_command_with_ctx(xhci, true, GFP_NOWAIT);
 	if (!cfg_cmd)
 		goto cleanup;
@@ -3144,23 +3180,16 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
 		goto cleanup;
 	}
 
-	err = xhci_queue_stop_endpoint(xhci, stop_cmd, udev->slot_id,
-					ep_index, 0);
+	spin_unlock_irqrestore(&xhci->lock, flags);
+
+	err = xhci_stop_endpoint_sync(xhci, ep, 0);
 	if (err < 0) {
-		spin_unlock_irqrestore(&xhci->lock, flags);
-		xhci_free_command(xhci, cfg_cmd);
 		xhci_dbg(xhci, "%s: Failed to queue stop ep command, %d ",
 				__func__, err);
 		goto cleanup;
 	}
 
-	xhci_ring_cmd_db(xhci);
-	spin_unlock_irqrestore(&xhci->lock, flags);
-
-	wait_for_completion(stop_cmd->completion);
-
 	spin_lock_irqsave(&xhci->lock, flags);
-
 	/* config ep command clears toggle if add and drop ep flags are set */
 	ctrl_ctx = xhci_get_input_control_ctx(cfg_cmd->in_ctx);
 	if (!ctrl_ctx) {
@@ -3192,7 +3221,6 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
 
 	xhci_free_command(xhci, cfg_cmd);
 cleanup:
-	xhci_free_command(xhci, stop_cmd);
 	spin_lock_irqsave(&xhci->lock, flags);
 	if (ep->ep_state & EP_SOFT_CLEAR_TOGGLE)
 		ep->ep_state &= ~EP_SOFT_CLEAR_TOGGLE;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d706a27ec0a3..898b6434dc27 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2125,6 +2125,8 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
 void xhci_cleanup_command_queue(struct xhci_hcd *xhci);
 void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring);
 unsigned int count_trbs(u64 addr, u64 len);
+int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
+			    int suspend);
 
 /* xHCI roothub code */
 void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,

  parent reply	other threads:[~2023-09-21 21:49 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-21 21:48 [PATCH v7 00/33] Introduce QC USB SND audio offloading support Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 01/33] xhci: add support to allocate several interrupters Wesley Cheng
2023-09-28 10:31   ` Mathias Nyman
2023-10-02 20:07     ` Wesley Cheng
2023-10-04 14:02       ` Mathias Nyman
2023-10-04 18:35         ` Wesley Cheng
2023-10-04 23:42           ` Wesley Cheng
2023-09-21 21:48 ` Wesley Cheng [this message]
2023-09-28 13:31   ` [PATCH v7 02/33] xhci: add helper to stop endpoint and wait for completion Mathias Nyman
2023-09-28 22:10     ` Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 03/33] xhci: sideband: add initial api to register a sideband entity Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 04/33] usb: host: xhci-mem: Cleanup pending secondary event ring events Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 05/33] usb: host: xhci-mem: Allow for interrupter clients to choose specific index Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 06/33] ASoC: Add SOC USB APIs for adding an USB backend Wesley Cheng
2023-09-27 14:48   ` Mark Brown
2023-09-27 19:57     ` Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 07/33] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add USB_RX port Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 08/33] ASoC: qcom: qdsp6: Introduce USB AFE port to q6dsp Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 09/33] ASoC: qdsp6: q6afe: Increase APR timeout Wesley Cheng
2023-09-27 14:50   ` Mark Brown
2023-09-27 20:01     ` Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 10/33] ASoC: qcom: qdsp6: Add USB backend ASoC driver for Q6 Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 11/33] ALSA: usb-audio: Introduce USB SND platform op callbacks Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 12/33] ALSA: usb-audio: Export USB SND APIs for modules Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 13/33] dt-bindings: usb: dwc3: Limit num-hc-interrupters definition Wesley Cheng
2023-09-25 15:32   ` Rob Herring
2023-09-21 21:48 ` [PATCH v7 14/33] dt-bindings: usb: xhci: Add " Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 15/33] usb: dwc3: Specify maximum number of XHCI interrupters Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 16/33] usb: host: xhci-plat: Set XHCI max interrupters if property is present Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 17/33] ALSA: usb-audio: qcom: Add USB QMI definitions Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 18/33] ALSA: usb-audio: qcom: Introduce QC USB SND offloading support Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 19/33] ALSA: usb-audio: Check for support for requested audio format Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 20/33] ASoC: usb: Add PCM format check API for USB backend Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 21/33] ASoC: qcom: qdsp6: Ensure PCM format is supported by USB audio device Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 22/33] ALSA: usb-audio: Prevent starting of audio stream if in use Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 23/33] ASoC: dt-bindings: Add Q6USB backend Wesley Cheng
2023-09-25 15:34   ` Rob Herring
2023-09-21 21:48 ` [PATCH v7 24/33] ASoC: dt-bindings: Update example for enabling USB offload on SM8250 Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 25/33] ASoC: qcom: qdsp6: q6afe: Split USB AFE dev_token param into separate API Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 26/33] ALSA: usb-audio: qcom: Populate PCM and USB chip information Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 27/33] ASoC: qcom: qdsp6: Add support to track available USB PCM devices Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 28/33] ASoC: qcom: qdsp6: Add SND kcontrol to select offload device Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 29/33] ASoC: qcom: qdsp6: Add SND kcontrol for fetching offload status Wesley Cheng
2023-09-27 15:02   ` Mark Brown
2023-09-27 20:10     ` Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 30/33] ASoC: qcom: qdsp6: Add headphone jack for offload connection status Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 31/33] ALSA: usb-audio: qcom: Use card and PCM index from QMI request Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 32/33] ALSA: usb-audio: Allow for rediscovery of connected USB SND devices Wesley Cheng
2023-09-21 21:48 ` [PATCH v7 33/33] ASoC: usb: Rediscover USB SND devices on USB port add Wesley Cheng
2023-09-27 15:04 ` [PATCH v7 00/33] Introduce QC USB SND audio offloading support Mark Brown
2023-09-27 15:46   ` Greg KH

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=20230921214843.18450-3-quic_wcheng@quicinc.com \
    --to=quic_wcheng@quicinc.com \
    --cc=Thinh.Nguyen@synopsys.com \
    --cc=agross@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=andersson@kernel.org \
    --cc=bgoswami@quicinc.com \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=mathias.nyman@linux.intel.com \
    --cc=perex@perex.cz \
    --cc=robh+dt@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=tiwai@suse.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