[PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity

Wesley Cheng posted 31 patches 9 months ago
There is a newer version of this series
[PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Wesley Cheng 9 months ago
From: Mathias Nyman <mathias.nyman@linux.intel.com>

Introduce XHCI sideband, which manages the USB endpoints being requested by
a client driver.  This is used for when client drivers are attempting to
offload USB endpoints to another entity for handling USB transfers.  XHCI
sec intr will allow for drivers to fetch the required information about the
transfer ring, so the user can submit transfers independently.  Expose the
required APIs for drivers to register and request for a USB endpoint and to
manage XHCI secondary interrupters.

Driver renaming, multiple ring segment page linking, proper endpoint clean
up, and allowing module compilation added by Wesley Cheng to complete
original concept code by Mathias Nyman.

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/Kconfig          |   9 +
 drivers/usb/host/Makefile         |   4 +
 drivers/usb/host/xhci-sideband.c  | 429 ++++++++++++++++++++++++++++++
 drivers/usb/host/xhci.h           |   4 +
 include/linux/usb/xhci-sideband.h |  74 ++++++
 5 files changed, 520 insertions(+)
 create mode 100644 drivers/usb/host/xhci-sideband.c
 create mode 100644 include/linux/usb/xhci-sideband.h

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index d011d6c753ed..033a9a4b51fe 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -104,6 +104,15 @@ config USB_XHCI_RZV2M
 	  Say 'Y' to enable the support for the xHCI host controller
 	  found in Renesas RZ/V2M SoC.
 
+config USB_XHCI_SIDEBAND
+	bool "xHCI support for sideband"
+	help
+	  Say 'Y' to enable the support for the xHCI sideband capability.
+	  Provide a mechanism for a sideband datapath for payload associated
+	  with audio class endpoints. This allows for an audio DSP to use
+	  xHCI USB endpoints directly, allowing CPU to sleep while playing
+	  audio.
+
 config USB_XHCI_TEGRA
 	tristate "xHCI support for NVIDIA Tegra SoCs"
 	depends on PHY_TEGRA_XUSB
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index be4e5245c52f..4df946c05ba0 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -32,6 +32,10 @@ endif
 xhci-rcar-hcd-y				+= xhci-rcar.o
 xhci-rcar-hcd-$(CONFIG_USB_XHCI_RZV2M)	+= xhci-rzv2m.o
 
+ifneq ($(CONFIG_USB_XHCI_SIDEBAND),)
+	xhci-hcd-y		+= xhci-sideband.o
+endif
+
 obj-$(CONFIG_USB_PCI)	+= pci-quirks.o
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
new file mode 100644
index 000000000000..19c58ae60414
--- /dev/null
+++ b/drivers/usb/host/xhci-sideband.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * xHCI host controller sideband support
+ *
+ * Copyright (c) 2023-2025, Intel Corporation.
+ *
+ * Author: Mathias Nyman
+ */
+
+#include <linux/usb/xhci-sideband.h>
+#include <linux/dma-direct.h>
+
+#include "xhci.h"
+
+/* sideband internal helpers */
+static struct sg_table *
+xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring)
+{
+	struct xhci_segment *seg;
+	struct sg_table	*sgt;
+	unsigned int n_pages;
+	struct page **pages;
+	struct device *dev;
+	size_t sz;
+	int i;
+
+	dev = xhci_to_hcd(sb->xhci)->self.sysdev;
+	sz = ring->num_segs * TRB_SEGMENT_SIZE;
+	n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
+	pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL);
+	if (!pages)
+		return NULL;
+
+	sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+	if (!sgt) {
+		kvfree(pages);
+		return NULL;
+	}
+
+	seg = ring->first_seg;
+	if (!seg)
+		goto err;
+	/*
+	 * Rings can potentially have multiple segments, create an array that
+	 * carries page references to allocated segments.  Utilize the
+	 * sg_alloc_table_from_pages() to create the sg table, and to ensure
+	 * that page links are created.
+	 */
+	for (i = 0; i < ring->num_segs; i++) {
+		dma_get_sgtable(dev, sgt, seg->trbs, seg->dma,
+				TRB_SEGMENT_SIZE);
+		pages[i] = sg_page(sgt->sgl);
+		sg_free_table(sgt);
+		seg = seg->next;
+	}
+
+	if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL))
+		goto err;
+
+	/*
+	 * Save first segment dma address to sg dma_address field for the sideband
+	 * client to have access to the IOVA of the ring.
+	 */
+	sg_dma_address(sgt->sgl) = ring->first_seg->dma;
+
+	return sgt;
+
+err:
+	kvfree(pages);
+	kfree(sgt);
+
+	return NULL;
+}
+
+static void
+__xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *ep)
+{
+	/*
+	 * Issue a stop endpoint command when an endpoint is removed.
+	 * The stop ep cmd handler will handle the ring cleanup.
+	 */
+	xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL);
+
+	ep->sideband = NULL;
+	sb->eps[ep->ep_index] = NULL;
+}
+
+/* sideband api functions */
+
+/**
+ * xhci_sideband_add_endpoint - add endpoint to sideband access list
+ * @sb: sideband instance for this usb device
+ * @host_ep: usb host endpoint
+ *
+ * Adds an endpoint to the list of sideband accessed endpoints for this usb
+ * device.
+ * After an endpoint is added the sideband client can get the endpoint transfer
+ * ring buffer by calling xhci_sideband_endpoint_buffer()
+ *
+ * Return: 0 on success, negative error otherwise.
+ */
+int
+xhci_sideband_add_endpoint(struct xhci_sideband *sb,
+			   struct usb_host_endpoint *host_ep)
+{
+	struct xhci_virt_ep *ep;
+	unsigned int ep_index;
+
+	mutex_lock(&sb->mutex);
+	ep_index = xhci_get_endpoint_index(&host_ep->desc);
+	ep = &sb->vdev->eps[ep_index];
+
+	if (ep->ep_state & EP_HAS_STREAMS) {
+		mutex_unlock(&sb->mutex);
+		return -EINVAL;
+	}
+
+	/*
+	 * Note, we don't know the DMA mask of the audio DSP device, if its
+	 * smaller than for xhci it won't be able to access the endpoint ring
+	 * buffer. This could be solved by not allowing the audio class driver
+	 * to add the endpoint the normal way, but instead offload it immediately,
+	 * and let this function add the endpoint and allocate the ring buffer
+	 * with the smallest common DMA mask
+	 */
+	if (sb->eps[ep_index] || ep->sideband) {
+		mutex_unlock(&sb->mutex);
+		return -EBUSY;
+	}
+
+	ep->sideband = sb;
+	sb->eps[ep_index] = ep;
+	mutex_unlock(&sb->mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_add_endpoint);
+
+/**
+ * xhci_sideband_remove_endpoint - remove endpoint from sideband access list
+ * @sb: sideband instance for this usb device
+ * @host_ep: usb host endpoint
+ *
+ * Removes an endpoint from the list of sideband accessed endpoints for this usb
+ * device.
+ * sideband client should no longer touch the endpoint transfer buffer after
+ * calling this.
+ *
+ * Return: 0 on success, negative error otherwise.
+ */
+int
+xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
+			      struct usb_host_endpoint *host_ep)
+{
+	struct xhci_virt_ep *ep;
+	unsigned int ep_index;
+
+	mutex_lock(&sb->mutex);
+	ep_index = xhci_get_endpoint_index(&host_ep->desc);
+	ep = sb->eps[ep_index];
+
+	if (!ep || !ep->sideband || ep->sideband != sb) {
+		mutex_unlock(&sb->mutex);
+		return -ENODEV;
+	}
+
+	__xhci_sideband_remove_endpoint(sb, ep);
+	xhci_initialize_ring_info(ep->ring);
+	mutex_unlock(&sb->mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_remove_endpoint);
+
+int
+xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
+			    struct usb_host_endpoint *host_ep)
+{
+	struct xhci_virt_ep *ep;
+	unsigned int ep_index;
+
+	ep_index = xhci_get_endpoint_index(&host_ep->desc);
+	ep = sb->eps[ep_index];
+
+	if (!ep || !ep->sideband || ep->sideband != sb)
+		return -EINVAL;
+
+	return xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_stop_endpoint);
+
+/**
+ * xhci_sideband_get_endpoint_buffer - gets the endpoint transfer buffer address
+ * @sb: sideband instance for this usb device
+ * @host_ep: usb host endpoint
+ *
+ * Returns the address of the endpoint buffer where xHC controller reads queued
+ * transfer TRBs from. This is the starting address of the ringbuffer where the
+ * sideband client should write TRBs to.
+ *
+ * Caller needs to free the returned sg_table
+ *
+ * Return: struct sg_table * if successful. NULL otherwise.
+ */
+struct sg_table *
+xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
+				  struct usb_host_endpoint *host_ep)
+{
+	struct xhci_virt_ep *ep;
+	unsigned int ep_index;
+
+	ep_index = xhci_get_endpoint_index(&host_ep->desc);
+	ep = sb->eps[ep_index];
+
+	if (!ep || !ep->ring || !ep->sideband || ep->sideband != sb)
+		return NULL;
+
+	return xhci_ring_to_sgtable(sb, ep->ring);
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_get_endpoint_buffer);
+
+/**
+ * xhci_sideband_get_event_buffer - return the event buffer for this device
+ * @sb: sideband instance for this usb device
+ *
+ * If a secondary xhci interupter is set up for this usb device then this
+ * function returns the address of the event buffer where xHC writes
+ * the transfer completion events.
+ *
+ * Caller needs to free the returned sg_table
+ *
+ * Return: struct sg_table * if successful. NULL otherwise.
+ */
+struct sg_table *
+xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
+{
+	if (!sb || !sb->ir)
+		return NULL;
+
+	return xhci_ring_to_sgtable(sb, sb->ir->event_ring);
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
+
+/**
+ * xhci_sideband_create_interrupter - creates a new interrupter for this sideband
+ * @sb: sideband instance for this usb device
+ * @num_seg: number of event ring segments to allocate
+ * @ip_autoclear: IP autoclearing support such as MSI implemented
+ *
+ * Sets up a xhci interrupter that can be used for this sideband accessed usb
+ * device. Transfer events for this device can be routed to this interrupters
+ * event ring by setting the 'Interrupter Target' field correctly when queueing
+ * the transfer TRBs.
+ * Once this interrupter is created the interrupter target ID can be obtained
+ * by calling xhci_sideband_interrupter_id()
+ *
+ * Returns 0 on success, negative error otherwise
+ */
+int
+xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
+				 bool ip_autoclear, u32 imod_interval)
+{
+	int ret = 0;
+
+	if (!sb || !sb->xhci)
+		return -ENODEV;
+
+	mutex_lock(&sb->mutex);
+	if (sb->ir) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	sb->ir = xhci_create_secondary_interrupter(xhci_to_hcd(sb->xhci),
+						   num_seg, imod_interval);
+	if (!sb->ir) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sb->ir->ip_autoclear = ip_autoclear;
+
+out:
+	mutex_unlock(&sb->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
+
+/**
+ * xhci_sideband_remove_interrupter - remove the interrupter from a sideband
+ * @sb: sideband instance for this usb device
+ *
+ * Removes a registered interrupt for a sideband.  This would allow for other
+ * sideband users to utilize this interrupter.
+ */
+void
+xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
+{
+	if (!sb || !sb->ir)
+		return;
+
+	mutex_lock(&sb->mutex);
+	xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
+
+	sb->ir = NULL;
+	mutex_unlock(&sb->mutex);
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_remove_interrupter);
+
+/**
+ * xhci_sideband_interrupter_id - return the interrupter target id
+ * @sb: sideband instance for this usb device
+ *
+ * If a secondary xhci interrupter is set up for this usb device then this
+ * function returns the ID used by the interrupter. The sideband client
+ * needs to write this ID to the 'Interrupter Target' field of the transfer TRBs
+ * it queues on the endpoints transfer ring to ensure transfer completion event
+ * are written by xHC to the correct interrupter event ring.
+ *
+ * Returns interrupter id on success, negative error othgerwise
+ */
+int
+xhci_sideband_interrupter_id(struct xhci_sideband *sb)
+{
+	if (!sb || !sb->ir)
+		return -ENODEV;
+
+	return sb->ir->intr_num;
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_interrupter_id);
+
+/**
+ * xhci_sideband_register - register a sideband for a usb device
+ * @intf: usb interface associated with the sideband device
+ *
+ * Allows for clients to utilize XHCI interrupters and fetch transfer and event
+ * ring parameters for executing data transfers.
+ *
+ * Return: pointer to a new xhci_sideband instance if successful. NULL otherwise.
+ */
+struct xhci_sideband *
+xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct xhci_virt_device *vdev;
+	struct xhci_sideband *sb;
+
+	/*
+	 * Make sure the usb device is connected to a xhci controller.  Fail
+	 * registration if the type is anything other than  XHCI_SIDEBAND_VENDOR,
+	 * as this is the only type that is currently supported by xhci-sideband.
+	 */
+	if (!udev->slot_id || type != XHCI_SIDEBAND_VENDOR)
+		return NULL;
+
+	sb = kzalloc_node(sizeof(*sb), GFP_KERNEL, dev_to_node(hcd->self.sysdev));
+	if (!sb)
+		return NULL;
+
+	mutex_init(&sb->mutex);
+
+	/* check this device isn't already controlled via sideband */
+	spin_lock_irq(&xhci->lock);
+
+	vdev = xhci->devs[udev->slot_id];
+
+	if (!vdev || vdev->sideband) {
+		xhci_warn(xhci, "XHCI sideband for slot %d already in use\n",
+			  udev->slot_id);
+		spin_unlock_irq(&xhci->lock);
+		kfree(sb);
+		return NULL;
+	}
+
+	sb->xhci = xhci;
+	sb->vdev = vdev;
+	sb->intf = intf;
+	sb->type = type;
+	vdev->sideband = sb;
+
+	spin_unlock_irq(&xhci->lock);
+
+	return sb;
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_register);
+
+/**
+ * xhci_sideband_unregister - unregister sideband access to a usb device
+ * @sb: sideband instance to be unregistered
+ *
+ * Unregisters sideband access to a usb device and frees the sideband
+ * instance.
+ * After this the endpoint and interrupter event buffers should no longer
+ * be accessed via sideband. The xhci driver can now take over handling
+ * the buffers.
+ */
+void
+xhci_sideband_unregister(struct xhci_sideband *sb)
+{
+	struct xhci_hcd *xhci;
+	int i;
+
+	if (!sb)
+		return;
+
+	xhci = sb->xhci;
+
+	mutex_lock(&sb->mutex);
+	for (i = 0; i < EP_CTX_PER_DEV; i++)
+		if (sb->eps[i])
+			__xhci_sideband_remove_endpoint(sb, sb->eps[i]);
+	mutex_unlock(&sb->mutex);
+
+	xhci_sideband_remove_interrupter(sb);
+
+	spin_lock_irq(&xhci->lock);
+	sb->xhci = NULL;
+	sb->vdev->sideband = NULL;
+	spin_unlock_irq(&xhci->lock);
+
+	kfree(sb);
+}
+EXPORT_SYMBOL_GPL(xhci_sideband_unregister);
+MODULE_DESCRIPTION("xHCI sideband driver for secondary interrupter management");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 37860f1e3aba..39db228f0b84 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -701,6 +701,8 @@ struct xhci_virt_ep {
 	int			next_frame_id;
 	/* Use new Isoch TRB layout needed for extended TBC support */
 	bool			use_extended_tbc;
+	/* set if this endpoint is controlled via sideband access*/
+	struct xhci_sideband	*sideband;
 };
 
 enum xhci_overhead_type {
@@ -763,6 +765,8 @@ struct xhci_virt_device {
 	u16				current_mel;
 	/* Used for the debugfs interfaces. */
 	void				*debugfs_private;
+	/* set if this endpoint is controlled via sideband access*/
+	struct xhci_sideband	*sideband;
 };
 
 /*
diff --git a/include/linux/usb/xhci-sideband.h b/include/linux/usb/xhci-sideband.h
new file mode 100644
index 000000000000..4b382af892fa
--- /dev/null
+++ b/include/linux/usb/xhci-sideband.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * xHCI host controller sideband support
+ *
+ * Copyright (c) 2023-2025, Intel Corporation.
+ *
+ * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
+ */
+#ifndef __LINUX_XHCI_SIDEBAND_H
+#define __LINUX_XHCI_SIDEBAND_H
+
+#include <linux/scatterlist.h>
+#include <linux/usb.h>
+
+#define	EP_CTX_PER_DEV		31	/* FIXME defined twice, from xhci.h */
+
+struct xhci_sideband;
+
+enum xhci_sideband_type {
+	XHCI_SIDEBAND_AUDIO,
+	XHCI_SIDEBAND_VENDOR,
+};
+
+/**
+ * struct xhci_sideband - representation of a sideband accessed usb device.
+ * @xhci: The xhci host controller the usb device is connected to
+ * @vdev: the usb device accessed via sideband
+ * @eps: array of endpoints controlled via sideband
+ * @ir: event handling and buffer for sideband accessed device
+ * @type: xHCI sideband type
+ * @mutex: mutex for sideband operations
+ * @intf: USB sideband client interface
+ *
+ * FIXME usb device accessed via sideband Keeping track of sideband accessed usb devices.
+ */
+struct xhci_sideband {
+	struct xhci_hcd                 *xhci;
+	struct xhci_virt_device         *vdev;
+	struct xhci_virt_ep             *eps[EP_CTX_PER_DEV];
+	struct xhci_interrupter         *ir;
+	enum xhci_sideband_type		type;
+
+	/* Synchronizing xHCI sideband operations with client drivers operations */
+	struct mutex			mutex;
+
+	struct usb_interface		*intf;
+};
+
+struct xhci_sideband *
+xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type);
+void
+xhci_sideband_unregister(struct xhci_sideband *sb);
+int
+xhci_sideband_add_endpoint(struct xhci_sideband *sb,
+			   struct usb_host_endpoint *host_ep);
+int
+xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
+			      struct usb_host_endpoint *host_ep);
+int
+xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
+			    struct usb_host_endpoint *host_ep);
+struct sg_table *
+xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
+				  struct usb_host_endpoint *host_ep);
+struct sg_table *
+xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
+int
+xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
+				 bool ip_autoclear, u32 imod_interval);
+void
+xhci_sideband_remove_interrupter(struct xhci_sideband *sb);
+int
+xhci_sideband_interrupter_id(struct xhci_sideband *sb);
+#endif /* __LINUX_XHCI_SIDEBAND_H */
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Puma Hsu 8 months, 3 weeks ago
On Wed, Mar 19, 2025 at 8:55 AM Wesley Cheng <quic_wcheng@quicinc.com> wrote:
>
> From: Mathias Nyman <mathias.nyman@linux.intel.com>
>
> Introduce XHCI sideband, which manages the USB endpoints being requested by
> a client driver.  This is used for when client drivers are attempting to
> offload USB endpoints to another entity for handling USB transfers.  XHCI
> sec intr will allow for drivers to fetch the required information about the
> transfer ring, so the user can submit transfers independently.  Expose the
> required APIs for drivers to register and request for a USB endpoint and to
> manage XHCI secondary interrupters.
>
> Driver renaming, multiple ring segment page linking, proper endpoint clean
> up, and allowing module compilation added by Wesley Cheng to complete
> original concept code by Mathias Nyman.
>
> 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>

Tested-by: Puma Hsu <pumahsu@google.com>

> ---
>  drivers/usb/host/Kconfig          |   9 +
>  drivers/usb/host/Makefile         |   4 +
>  drivers/usb/host/xhci-sideband.c  | 429 ++++++++++++++++++++++++++++++
>  drivers/usb/host/xhci.h           |   4 +
>  include/linux/usb/xhci-sideband.h |  74 ++++++
>  5 files changed, 520 insertions(+)
>  create mode 100644 drivers/usb/host/xhci-sideband.c
>  create mode 100644 include/linux/usb/xhci-sideband.h
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index d011d6c753ed..033a9a4b51fe 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -104,6 +104,15 @@ config USB_XHCI_RZV2M
>           Say 'Y' to enable the support for the xHCI host controller
>           found in Renesas RZ/V2M SoC.
>
> +config USB_XHCI_SIDEBAND
> +       bool "xHCI support for sideband"
> +       help
> +         Say 'Y' to enable the support for the xHCI sideband capability.
> +         Provide a mechanism for a sideband datapath for payload associated
> +         with audio class endpoints. This allows for an audio DSP to use
> +         xHCI USB endpoints directly, allowing CPU to sleep while playing
> +         audio.
> +
>  config USB_XHCI_TEGRA
>         tristate "xHCI support for NVIDIA Tegra SoCs"
>         depends on PHY_TEGRA_XUSB
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index be4e5245c52f..4df946c05ba0 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -32,6 +32,10 @@ endif
>  xhci-rcar-hcd-y                                += xhci-rcar.o
>  xhci-rcar-hcd-$(CONFIG_USB_XHCI_RZV2M) += xhci-rzv2m.o
>
> +ifneq ($(CONFIG_USB_XHCI_SIDEBAND),)
> +       xhci-hcd-y              += xhci-sideband.o
> +endif
> +
>  obj-$(CONFIG_USB_PCI)  += pci-quirks.o
>
>  obj-$(CONFIG_USB_EHCI_HCD)     += ehci-hcd.o
> diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
> new file mode 100644
> index 000000000000..19c58ae60414
> --- /dev/null
> +++ b/drivers/usb/host/xhci-sideband.c
> @@ -0,0 +1,429 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * xHCI host controller sideband support
> + *
> + * Copyright (c) 2023-2025, Intel Corporation.
> + *
> + * Author: Mathias Nyman
> + */
> +
> +#include <linux/usb/xhci-sideband.h>
> +#include <linux/dma-direct.h>
> +
> +#include "xhci.h"
> +
> +/* sideband internal helpers */
> +static struct sg_table *
> +xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring)
> +{
> +       struct xhci_segment *seg;
> +       struct sg_table *sgt;
> +       unsigned int n_pages;
> +       struct page **pages;
> +       struct device *dev;
> +       size_t sz;
> +       int i;
> +
> +       dev = xhci_to_hcd(sb->xhci)->self.sysdev;
> +       sz = ring->num_segs * TRB_SEGMENT_SIZE;
> +       n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
> +       pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL);
> +       if (!pages)
> +               return NULL;
> +
> +       sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
> +       if (!sgt) {
> +               kvfree(pages);
> +               return NULL;
> +       }
> +
> +       seg = ring->first_seg;
> +       if (!seg)
> +               goto err;
> +       /*
> +        * Rings can potentially have multiple segments, create an array that
> +        * carries page references to allocated segments.  Utilize the
> +        * sg_alloc_table_from_pages() to create the sg table, and to ensure
> +        * that page links are created.
> +        */
> +       for (i = 0; i < ring->num_segs; i++) {
> +               dma_get_sgtable(dev, sgt, seg->trbs, seg->dma,
> +                               TRB_SEGMENT_SIZE);
> +               pages[i] = sg_page(sgt->sgl);
> +               sg_free_table(sgt);
> +               seg = seg->next;
> +       }
> +
> +       if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL))
> +               goto err;
> +
> +       /*
> +        * Save first segment dma address to sg dma_address field for the sideband
> +        * client to have access to the IOVA of the ring.
> +        */
> +       sg_dma_address(sgt->sgl) = ring->first_seg->dma;
> +
> +       return sgt;
> +
> +err:
> +       kvfree(pages);
> +       kfree(sgt);
> +
> +       return NULL;
> +}
> +
> +static void
> +__xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *ep)
> +{
> +       /*
> +        * Issue a stop endpoint command when an endpoint is removed.
> +        * The stop ep cmd handler will handle the ring cleanup.
> +        */
> +       xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL);
> +
> +       ep->sideband = NULL;
> +       sb->eps[ep->ep_index] = NULL;
> +}
> +
> +/* sideband api functions */
> +
> +/**
> + * xhci_sideband_add_endpoint - add endpoint to sideband access list
> + * @sb: sideband instance for this usb device
> + * @host_ep: usb host endpoint
> + *
> + * Adds an endpoint to the list of sideband accessed endpoints for this usb
> + * device.
> + * After an endpoint is added the sideband client can get the endpoint transfer
> + * ring buffer by calling xhci_sideband_endpoint_buffer()
> + *
> + * Return: 0 on success, negative error otherwise.
> + */
> +int
> +xhci_sideband_add_endpoint(struct xhci_sideband *sb,
> +                          struct usb_host_endpoint *host_ep)
> +{
> +       struct xhci_virt_ep *ep;
> +       unsigned int ep_index;
> +
> +       mutex_lock(&sb->mutex);
> +       ep_index = xhci_get_endpoint_index(&host_ep->desc);
> +       ep = &sb->vdev->eps[ep_index];
> +
> +       if (ep->ep_state & EP_HAS_STREAMS) {
> +               mutex_unlock(&sb->mutex);
> +               return -EINVAL;
> +       }
> +
> +       /*
> +        * Note, we don't know the DMA mask of the audio DSP device, if its
> +        * smaller than for xhci it won't be able to access the endpoint ring
> +        * buffer. This could be solved by not allowing the audio class driver
> +        * to add the endpoint the normal way, but instead offload it immediately,
> +        * and let this function add the endpoint and allocate the ring buffer
> +        * with the smallest common DMA mask
> +        */
> +       if (sb->eps[ep_index] || ep->sideband) {
> +               mutex_unlock(&sb->mutex);
> +               return -EBUSY;
> +       }
> +
> +       ep->sideband = sb;
> +       sb->eps[ep_index] = ep;
> +       mutex_unlock(&sb->mutex);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_add_endpoint);
> +
> +/**
> + * xhci_sideband_remove_endpoint - remove endpoint from sideband access list
> + * @sb: sideband instance for this usb device
> + * @host_ep: usb host endpoint
> + *
> + * Removes an endpoint from the list of sideband accessed endpoints for this usb
> + * device.
> + * sideband client should no longer touch the endpoint transfer buffer after
> + * calling this.
> + *
> + * Return: 0 on success, negative error otherwise.
> + */
> +int
> +xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
> +                             struct usb_host_endpoint *host_ep)
> +{
> +       struct xhci_virt_ep *ep;
> +       unsigned int ep_index;
> +
> +       mutex_lock(&sb->mutex);
> +       ep_index = xhci_get_endpoint_index(&host_ep->desc);
> +       ep = sb->eps[ep_index];
> +
> +       if (!ep || !ep->sideband || ep->sideband != sb) {
> +               mutex_unlock(&sb->mutex);
> +               return -ENODEV;
> +       }
> +
> +       __xhci_sideband_remove_endpoint(sb, ep);
> +       xhci_initialize_ring_info(ep->ring);
> +       mutex_unlock(&sb->mutex);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_remove_endpoint);
> +
> +int
> +xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
> +                           struct usb_host_endpoint *host_ep)
> +{
> +       struct xhci_virt_ep *ep;
> +       unsigned int ep_index;
> +
> +       ep_index = xhci_get_endpoint_index(&host_ep->desc);
> +       ep = sb->eps[ep_index];
> +
> +       if (!ep || !ep->sideband || ep->sideband != sb)
> +               return -EINVAL;
> +
> +       return xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL);
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_stop_endpoint);
> +
> +/**
> + * xhci_sideband_get_endpoint_buffer - gets the endpoint transfer buffer address
> + * @sb: sideband instance for this usb device
> + * @host_ep: usb host endpoint
> + *
> + * Returns the address of the endpoint buffer where xHC controller reads queued
> + * transfer TRBs from. This is the starting address of the ringbuffer where the
> + * sideband client should write TRBs to.
> + *
> + * Caller needs to free the returned sg_table
> + *
> + * Return: struct sg_table * if successful. NULL otherwise.
> + */
> +struct sg_table *
> +xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
> +                                 struct usb_host_endpoint *host_ep)
> +{
> +       struct xhci_virt_ep *ep;
> +       unsigned int ep_index;
> +
> +       ep_index = xhci_get_endpoint_index(&host_ep->desc);
> +       ep = sb->eps[ep_index];
> +
> +       if (!ep || !ep->ring || !ep->sideband || ep->sideband != sb)
> +               return NULL;
> +
> +       return xhci_ring_to_sgtable(sb, ep->ring);
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_get_endpoint_buffer);
> +
> +/**
> + * xhci_sideband_get_event_buffer - return the event buffer for this device
> + * @sb: sideband instance for this usb device
> + *
> + * If a secondary xhci interupter is set up for this usb device then this
> + * function returns the address of the event buffer where xHC writes
> + * the transfer completion events.
> + *
> + * Caller needs to free the returned sg_table
> + *
> + * Return: struct sg_table * if successful. NULL otherwise.
> + */
> +struct sg_table *
> +xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
> +{
> +       if (!sb || !sb->ir)
> +               return NULL;
> +
> +       return xhci_ring_to_sgtable(sb, sb->ir->event_ring);
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
> +
> +/**
> + * xhci_sideband_create_interrupter - creates a new interrupter for this sideband
> + * @sb: sideband instance for this usb device
> + * @num_seg: number of event ring segments to allocate
> + * @ip_autoclear: IP autoclearing support such as MSI implemented
> + *
> + * Sets up a xhci interrupter that can be used for this sideband accessed usb
> + * device. Transfer events for this device can be routed to this interrupters
> + * event ring by setting the 'Interrupter Target' field correctly when queueing
> + * the transfer TRBs.
> + * Once this interrupter is created the interrupter target ID can be obtained
> + * by calling xhci_sideband_interrupter_id()
> + *
> + * Returns 0 on success, negative error otherwise
> + */
> +int
> +xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
> +                                bool ip_autoclear, u32 imod_interval)
> +{
> +       int ret = 0;
> +
> +       if (!sb || !sb->xhci)
> +               return -ENODEV;
> +
> +       mutex_lock(&sb->mutex);
> +       if (sb->ir) {
> +               ret = -EBUSY;
> +               goto out;
> +       }
> +
> +       sb->ir = xhci_create_secondary_interrupter(xhci_to_hcd(sb->xhci),
> +                                                  num_seg, imod_interval);
> +       if (!sb->ir) {
> +               ret = -ENOMEM;
> +               goto out;
> +       }
> +
> +       sb->ir->ip_autoclear = ip_autoclear;
> +
> +out:
> +       mutex_unlock(&sb->mutex);
> +
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
> +
> +/**
> + * xhci_sideband_remove_interrupter - remove the interrupter from a sideband
> + * @sb: sideband instance for this usb device
> + *
> + * Removes a registered interrupt for a sideband.  This would allow for other
> + * sideband users to utilize this interrupter.
> + */
> +void
> +xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
> +{
> +       if (!sb || !sb->ir)
> +               return;
> +
> +       mutex_lock(&sb->mutex);
> +       xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
> +
> +       sb->ir = NULL;
> +       mutex_unlock(&sb->mutex);
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_remove_interrupter);
> +
> +/**
> + * xhci_sideband_interrupter_id - return the interrupter target id
> + * @sb: sideband instance for this usb device
> + *
> + * If a secondary xhci interrupter is set up for this usb device then this
> + * function returns the ID used by the interrupter. The sideband client
> + * needs to write this ID to the 'Interrupter Target' field of the transfer TRBs
> + * it queues on the endpoints transfer ring to ensure transfer completion event
> + * are written by xHC to the correct interrupter event ring.
> + *
> + * Returns interrupter id on success, negative error othgerwise
> + */
> +int
> +xhci_sideband_interrupter_id(struct xhci_sideband *sb)
> +{
> +       if (!sb || !sb->ir)
> +               return -ENODEV;
> +
> +       return sb->ir->intr_num;
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_interrupter_id);
> +
> +/**
> + * xhci_sideband_register - register a sideband for a usb device
> + * @intf: usb interface associated with the sideband device
> + *
> + * Allows for clients to utilize XHCI interrupters and fetch transfer and event
> + * ring parameters for executing data transfers.
> + *
> + * Return: pointer to a new xhci_sideband instance if successful. NULL otherwise.
> + */
> +struct xhci_sideband *
> +xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type)
> +{
> +       struct usb_device *udev = interface_to_usbdev(intf);
> +       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
> +       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> +       struct xhci_virt_device *vdev;
> +       struct xhci_sideband *sb;
> +
> +       /*
> +        * Make sure the usb device is connected to a xhci controller.  Fail
> +        * registration if the type is anything other than  XHCI_SIDEBAND_VENDOR,
> +        * as this is the only type that is currently supported by xhci-sideband.
> +        */
> +       if (!udev->slot_id || type != XHCI_SIDEBAND_VENDOR)
> +               return NULL;
> +
> +       sb = kzalloc_node(sizeof(*sb), GFP_KERNEL, dev_to_node(hcd->self.sysdev));
> +       if (!sb)
> +               return NULL;
> +
> +       mutex_init(&sb->mutex);
> +
> +       /* check this device isn't already controlled via sideband */
> +       spin_lock_irq(&xhci->lock);
> +
> +       vdev = xhci->devs[udev->slot_id];
> +
> +       if (!vdev || vdev->sideband) {
> +               xhci_warn(xhci, "XHCI sideband for slot %d already in use\n",
> +                         udev->slot_id);
> +               spin_unlock_irq(&xhci->lock);
> +               kfree(sb);
> +               return NULL;
> +       }
> +
> +       sb->xhci = xhci;
> +       sb->vdev = vdev;
> +       sb->intf = intf;
> +       sb->type = type;
> +       vdev->sideband = sb;
> +
> +       spin_unlock_irq(&xhci->lock);
> +
> +       return sb;
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_register);
> +
> +/**
> + * xhci_sideband_unregister - unregister sideband access to a usb device
> + * @sb: sideband instance to be unregistered
> + *
> + * Unregisters sideband access to a usb device and frees the sideband
> + * instance.
> + * After this the endpoint and interrupter event buffers should no longer
> + * be accessed via sideband. The xhci driver can now take over handling
> + * the buffers.
> + */
> +void
> +xhci_sideband_unregister(struct xhci_sideband *sb)
> +{
> +       struct xhci_hcd *xhci;
> +       int i;
> +
> +       if (!sb)
> +               return;
> +
> +       xhci = sb->xhci;
> +
> +       mutex_lock(&sb->mutex);
> +       for (i = 0; i < EP_CTX_PER_DEV; i++)
> +               if (sb->eps[i])
> +                       __xhci_sideband_remove_endpoint(sb, sb->eps[i]);
> +       mutex_unlock(&sb->mutex);
> +
> +       xhci_sideband_remove_interrupter(sb);
> +
> +       spin_lock_irq(&xhci->lock);
> +       sb->xhci = NULL;
> +       sb->vdev->sideband = NULL;
> +       spin_unlock_irq(&xhci->lock);
> +
> +       kfree(sb);
> +}
> +EXPORT_SYMBOL_GPL(xhci_sideband_unregister);
> +MODULE_DESCRIPTION("xHCI sideband driver for secondary interrupter management");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 37860f1e3aba..39db228f0b84 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -701,6 +701,8 @@ struct xhci_virt_ep {
>         int                     next_frame_id;
>         /* Use new Isoch TRB layout needed for extended TBC support */
>         bool                    use_extended_tbc;
> +       /* set if this endpoint is controlled via sideband access*/
> +       struct xhci_sideband    *sideband;
>  };
>
>  enum xhci_overhead_type {
> @@ -763,6 +765,8 @@ struct xhci_virt_device {
>         u16                             current_mel;
>         /* Used for the debugfs interfaces. */
>         void                            *debugfs_private;
> +       /* set if this endpoint is controlled via sideband access*/
> +       struct xhci_sideband    *sideband;
>  };
>
>  /*
> diff --git a/include/linux/usb/xhci-sideband.h b/include/linux/usb/xhci-sideband.h
> new file mode 100644
> index 000000000000..4b382af892fa
> --- /dev/null
> +++ b/include/linux/usb/xhci-sideband.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * xHCI host controller sideband support
> + *
> + * Copyright (c) 2023-2025, Intel Corporation.
> + *
> + * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
> + */
> +#ifndef __LINUX_XHCI_SIDEBAND_H
> +#define __LINUX_XHCI_SIDEBAND_H
> +
> +#include <linux/scatterlist.h>
> +#include <linux/usb.h>
> +
> +#define        EP_CTX_PER_DEV          31      /* FIXME defined twice, from xhci.h */
> +
> +struct xhci_sideband;
> +
> +enum xhci_sideband_type {
> +       XHCI_SIDEBAND_AUDIO,
> +       XHCI_SIDEBAND_VENDOR,
> +};
> +
> +/**
> + * struct xhci_sideband - representation of a sideband accessed usb device.
> + * @xhci: The xhci host controller the usb device is connected to
> + * @vdev: the usb device accessed via sideband
> + * @eps: array of endpoints controlled via sideband
> + * @ir: event handling and buffer for sideband accessed device
> + * @type: xHCI sideband type
> + * @mutex: mutex for sideband operations
> + * @intf: USB sideband client interface
> + *
> + * FIXME usb device accessed via sideband Keeping track of sideband accessed usb devices.
> + */
> +struct xhci_sideband {
> +       struct xhci_hcd                 *xhci;
> +       struct xhci_virt_device         *vdev;
> +       struct xhci_virt_ep             *eps[EP_CTX_PER_DEV];
> +       struct xhci_interrupter         *ir;
> +       enum xhci_sideband_type         type;
> +
> +       /* Synchronizing xHCI sideband operations with client drivers operations */
> +       struct mutex                    mutex;
> +
> +       struct usb_interface            *intf;
> +};
> +
> +struct xhci_sideband *
> +xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type);
> +void
> +xhci_sideband_unregister(struct xhci_sideband *sb);
> +int
> +xhci_sideband_add_endpoint(struct xhci_sideband *sb,
> +                          struct usb_host_endpoint *host_ep);
> +int
> +xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
> +                             struct usb_host_endpoint *host_ep);
> +int
> +xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
> +                           struct usb_host_endpoint *host_ep);
> +struct sg_table *
> +xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
> +                                 struct usb_host_endpoint *host_ep);
> +struct sg_table *
> +xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
> +int
> +xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
> +                                bool ip_autoclear, u32 imod_interval);
> +void
> +xhci_sideband_remove_interrupter(struct xhci_sideband *sb);
> +int
> +xhci_sideband_interrupter_id(struct xhci_sideband *sb);
> +#endif /* __LINUX_XHCI_SIDEBAND_H */
>
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Puma Hsu 8 months, 3 weeks ago
Hi,

We have implemented and verified the USB audio offloading feature with
the xhci sideband driver on our Google Pixel products. We would
appreciate it if this solution can be accepted. Thank you all for the
work!
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Greg KH 8 months, 3 weeks ago
On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> Hi,
> 
> We have implemented and verified the USB audio offloading feature with
> the xhci sideband driver on our Google Pixel products. We would
> appreciate it if this solution can be accepted. Thank you all for the
> work!
> 

Great, can you properly send a "Tested-by:" line for this against the
00/XX email so that it will be properly saved?

Also, I think a new version of the series is coming, can you test that
to verify it works properly?  We have to wait until after -rc1 is out
anyway.

thanks,

greg k-h
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Puma Hsu 8 months, 3 weeks ago
On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> > Hi,
> >
> > We have implemented and verified the USB audio offloading feature with
> > the xhci sideband driver on our Google Pixel products. We would
> > appreciate it if this solution can be accepted. Thank you all for the
> > work!
> >
>
> Great, can you properly send a "Tested-by:" line for this against the
> 00/XX email so that it will be properly saved?
>

We(Google Pixel) only use the xhci sideband related changes and two
changes in the sound card driver. For the details, what we actually
tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
Do I still send the "Tested-by:" line to 00/31 email? Or should I just
send the "Tested-by:" line to the 8 changes above? (I added
"Tested-by" line for this [01/31] first.)

> Also, I think a new version of the series is coming, can you test that
> to verify it works properly?  We have to wait until after -rc1 is out
> anyway.
>

I think this v36 is the last version of the series as I discussed with
QCOM Wesley. And for sure I will test it if they do have a new
version.

Thanks
Puma
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Wesley Cheng 8 months, 3 weeks ago

On 3/27/2025 3:14 AM, Puma Hsu wrote:
> On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>>
>> On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
>>> Hi,
>>>
>>> We have implemented and verified the USB audio offloading feature with
>>> the xhci sideband driver on our Google Pixel products. We would
>>> appreciate it if this solution can be accepted. Thank you all for the
>>> work!
>>>
>>
>> Great, can you properly send a "Tested-by:" line for this against the
>> 00/XX email so that it will be properly saved?
>>
> 
> We(Google Pixel) only use the xhci sideband related changes and two
> changes in the sound card driver. For the details, what we actually
> tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> send the "Tested-by:" line to the 8 changes above? (I added
> "Tested-by" line for this [01/31] first.)
> 
>> Also, I think a new version of the series is coming, can you test that
>> to verify it works properly?  We have to wait until after -rc1 is out
>> anyway.
>>
> 
> I think this v36 is the last version of the series as I discussed with
> QCOM Wesley. And for sure I will test it if they do have a new
> version.
> 

Hi Puma,

I'm discussing with Stephan on the QC specific stuff, so the common changes
won't change on v37.  Please provide your tested-by tags for each commit,
so I can carry them accordingly on the next submission.  If I do end up
making changes to any of the common patches, I will remove your tested by
tag, which means you might have to test it again.

Thanks
Wesley Cheng

Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Jung Daehwan 8 months, 2 weeks ago
On Thu, Mar 27, 2025 at 09:12:12AM -0700, Wesley Cheng wrote:
> 
> 
> On 3/27/2025 3:14 AM, Puma Hsu wrote:
> > On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> >>
> >> On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> >>> Hi,
> >>>
> >>> We have implemented and verified the USB audio offloading feature with
> >>> the xhci sideband driver on our Google Pixel products. We would
> >>> appreciate it if this solution can be accepted. Thank you all for the
> >>> work!
> >>>
> >>
> >> Great, can you properly send a "Tested-by:" line for this against the
> >> 00/XX email so that it will be properly saved?
> >>
> > 
> > We(Google Pixel) only use the xhci sideband related changes and two
> > changes in the sound card driver. For the details, what we actually
> > tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> > Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> > send the "Tested-by:" line to the 8 changes above? (I added
> > "Tested-by" line for this [01/31] first.)
> > 
> >> Also, I think a new version of the series is coming, can you test that
> >> to verify it works properly?  We have to wait until after -rc1 is out
> >> anyway.
> >>
> > 
> > I think this v36 is the last version of the series as I discussed with
> > QCOM Wesley. And for sure I will test it if they do have a new
> > version.
> > 
> 
> Hi Puma,
> 
> I'm discussing with Stephan on the QC specific stuff, so the common changes
> won't change on v37.  Please provide your tested-by tags for each commit,
> so I can carry them accordingly on the next submission.  If I do end up
> making changes to any of the common patches, I will remove your tested by
> tag, which means you might have to test it again.
> 
> Thanks
> Wesley Cheng
> 
> 
> 

Hi Wesley,

Thanks for your effort to upstream usb audio offload.
I've also used your patchset like Puma.
([01], [02], [03], [04], [05], [06], [08], and [12])

It works well on Exynos. Please let me know if you need also
"Tested-by:" on our side.

Best Regards,
Jung Daehwan
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Greg KH 8 months, 2 weeks ago
On Tue, Apr 01, 2025 at 11:23:36AM +0900, Jung Daehwan wrote:
> On Thu, Mar 27, 2025 at 09:12:12AM -0700, Wesley Cheng wrote:
> > 
> > 
> > On 3/27/2025 3:14 AM, Puma Hsu wrote:
> > > On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> > >>
> > >> On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> > >>> Hi,
> > >>>
> > >>> We have implemented and verified the USB audio offloading feature with
> > >>> the xhci sideband driver on our Google Pixel products. We would
> > >>> appreciate it if this solution can be accepted. Thank you all for the
> > >>> work!
> > >>>
> > >>
> > >> Great, can you properly send a "Tested-by:" line for this against the
> > >> 00/XX email so that it will be properly saved?
> > >>
> > > 
> > > We(Google Pixel) only use the xhci sideband related changes and two
> > > changes in the sound card driver. For the details, what we actually
> > > tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> > > Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> > > send the "Tested-by:" line to the 8 changes above? (I added
> > > "Tested-by" line for this [01/31] first.)
> > > 
> > >> Also, I think a new version of the series is coming, can you test that
> > >> to verify it works properly?  We have to wait until after -rc1 is out
> > >> anyway.
> > >>
> > > 
> > > I think this v36 is the last version of the series as I discussed with
> > > QCOM Wesley. And for sure I will test it if they do have a new
> > > version.
> > > 
> > 
> > Hi Puma,
> > 
> > I'm discussing with Stephan on the QC specific stuff, so the common changes
> > won't change on v37.  Please provide your tested-by tags for each commit,
> > so I can carry them accordingly on the next submission.  If I do end up
> > making changes to any of the common patches, I will remove your tested by
> > tag, which means you might have to test it again.
> > 
> > Thanks
> > Wesley Cheng
> > 
> > 
> > 
> 
> Hi Wesley,
> 
> Thanks for your effort to upstream usb audio offload.
> I've also used your patchset like Puma.
> ([01], [02], [03], [04], [05], [06], [08], and [12])
> 
> It works well on Exynos. Please let me know if you need also
> "Tested-by:" on our side.

Yes please.
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Jung Daehwan 8 months, 2 weeks ago
On Tue, Apr 01, 2025 at 07:55:13AM +0100, Greg KH wrote:
> On Tue, Apr 01, 2025 at 11:23:36AM +0900, Jung Daehwan wrote:
> > On Thu, Mar 27, 2025 at 09:12:12AM -0700, Wesley Cheng wrote:
> > > 
> > > 
> > > On 3/27/2025 3:14 AM, Puma Hsu wrote:
> > > > On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> > > >>
> > > >> On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> > > >>> Hi,
> > > >>>
> > > >>> We have implemented and verified the USB audio offloading feature with
> > > >>> the xhci sideband driver on our Google Pixel products. We would
> > > >>> appreciate it if this solution can be accepted. Thank you all for the
> > > >>> work!
> > > >>>
> > > >>
> > > >> Great, can you properly send a "Tested-by:" line for this against the
> > > >> 00/XX email so that it will be properly saved?
> > > >>
> > > > 
> > > > We(Google Pixel) only use the xhci sideband related changes and two
> > > > changes in the sound card driver. For the details, what we actually
> > > > tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> > > > Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> > > > send the "Tested-by:" line to the 8 changes above? (I added
> > > > "Tested-by" line for this [01/31] first.)
> > > > 
> > > >> Also, I think a new version of the series is coming, can you test that
> > > >> to verify it works properly?  We have to wait until after -rc1 is out
> > > >> anyway.
> > > >>
> > > > 
> > > > I think this v36 is the last version of the series as I discussed with
> > > > QCOM Wesley. And for sure I will test it if they do have a new
> > > > version.
> > > > 
> > > 
> > > Hi Puma,
> > > 
> > > I'm discussing with Stephan on the QC specific stuff, so the common changes
> > > won't change on v37.  Please provide your tested-by tags for each commit,
> > > so I can carry them accordingly on the next submission.  If I do end up
> > > making changes to any of the common patches, I will remove your tested by
> > > tag, which means you might have to test it again.
> > > 
> > > Thanks
> > > Wesley Cheng
> > > 
> > > 
> > > 
> > 
> > Hi Wesley,
> > 
> > Thanks for your effort to upstream usb audio offload.
> > I've also used your patchset like Puma.
> > ([01], [02], [03], [04], [05], [06], [08], and [12])
> > 
> > It works well on Exynos. Please let me know if you need also
> > "Tested-by:" on our side.
> 
> Yes please.
>

Tested-by: Daehwan Jung <dh10.jung@samsung.com>
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Puma Hsu 8 months, 3 weeks ago
On Fri, Mar 28, 2025 at 12:12 AM Wesley Cheng <quic_wcheng@quicinc.com> wrote:
>
> On 3/27/2025 3:14 AM, Puma Hsu wrote:
> > On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> >>
> >> On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> >>> Hi,
> >>>
> >>> We have implemented and verified the USB audio offloading feature with
> >>> the xhci sideband driver on our Google Pixel products. We would
> >>> appreciate it if this solution can be accepted. Thank you all for the
> >>> work!
> >>>
> >>
> >> Great, can you properly send a "Tested-by:" line for this against the
> >> 00/XX email so that it will be properly saved?
> >>
> >
> > We(Google Pixel) only use the xhci sideband related changes and two
> > changes in the sound card driver. For the details, what we actually
> > tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> > Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> > send the "Tested-by:" line to the 8 changes above? (I added
> > "Tested-by" line for this [01/31] first.)
> >
> >> Also, I think a new version of the series is coming, can you test that
> >> to verify it works properly?  We have to wait until after -rc1 is out
> >> anyway.
> >>
> >
> > I think this v36 is the last version of the series as I discussed with
> > QCOM Wesley. And for sure I will test it if they do have a new
> > version.
> >
>
> Hi Puma,
>
> I'm discussing with Stephan on the QC specific stuff, so the common changes
> won't change on v37.  Please provide your tested-by tags for each commit,
> so I can carry them accordingly on the next submission.  If I do end up
> making changes to any of the common patches, I will remove your tested by
> tag, which means you might have to test it again.
>

Thank you Wesley, I will add Tested-by for the commits, and I will
track your next new version.

Thanks
Puma
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Greg KH 8 months, 3 weeks ago
On Thu, Mar 27, 2025 at 06:14:00PM +0800, Puma Hsu wrote:
> On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> > > Hi,
> > >
> > > We have implemented and verified the USB audio offloading feature with
> > > the xhci sideband driver on our Google Pixel products. We would
> > > appreciate it if this solution can be accepted. Thank you all for the
> > > work!
> > >
> >
> > Great, can you properly send a "Tested-by:" line for this against the
> > 00/XX email so that it will be properly saved?
> >
> 
> We(Google Pixel) only use the xhci sideband related changes and two
> changes in the sound card driver. For the details, what we actually
> tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> send the "Tested-by:" line to the 8 changes above? (I added
> "Tested-by" line for this [01/31] first.)

Send it to the commits that you used if you only used portions.

But that feels odd, why are you only using portions here?  Why not the
whole thing?  Are you going to have to revert portions of this series in
order for your device to work properly?

> > Also, I think a new version of the series is coming, can you test that
> > to verify it works properly?  We have to wait until after -rc1 is out
> > anyway.
> >
> 
> I think this v36 is the last version of the series as I discussed with
> QCOM Wesley. And for sure I will test it if they do have a new
> version.

See:
	https://lore.kernel.org/r/ee95520b-cdcc-4e10-a70e-683993cafe36@quicinc.com
for where the need for a new version is discussed.

thanks,

greg k-h
Re: [PATCH v36 01/31] xhci: sideband: add initial api to register a secondary interrupter entity
Posted by Puma Hsu 8 months, 3 weeks ago
On Thu, Mar 27, 2025 at 6:48 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Thu, Mar 27, 2025 at 06:14:00PM +0800, Puma Hsu wrote:
> > On Thu, Mar 27, 2025 at 3:02 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> > >
> > > On Thu, Mar 27, 2025 at 02:27:00PM +0800, Puma Hsu wrote:
> > > > Hi,
> > > >
> > > > We have implemented and verified the USB audio offloading feature with
> > > > the xhci sideband driver on our Google Pixel products. We would
> > > > appreciate it if this solution can be accepted. Thank you all for the
> > > > work!
> > > >
> > >
> > > Great, can you properly send a "Tested-by:" line for this against the
> > > 00/XX email so that it will be properly saved?
> > >
> >
> > We(Google Pixel) only use the xhci sideband related changes and two
> > changes in the sound card driver. For the details, what we actually
> > tested are patch [01], [02], [03], [04], [05], [06], [08], and [12].
> > Do I still send the "Tested-by:" line to 00/31 email? Or should I just
> > send the "Tested-by:" line to the 8 changes above? (I added
> > "Tested-by" line for this [01/31] first.)
>
> Send it to the commits that you used if you only used portions.
>
> But that feels odd, why are you only using portions here?  Why not the
> whole thing?  Are you going to have to revert portions of this series in
> order for your device to work properly?
>

Google Pixels use Tensor instead of QCOM chip, so we won't enable
QCOM specific drivers from this series(i.g. patch [14~31]). What we
need from this series are common xhci stuff and portions of alsa. We
won't build QCOM driver even if this series is all merged, so we don't
have to revert anything.


> > > Also, I think a new version of the series is coming, can you test that
> > > to verify it works properly?  We have to wait until after -rc1 is out
> > > anyway.
> > >
> >
> > I think this v36 is the last version of the series as I discussed with
> > QCOM Wesley. And for sure I will test it if they do have a new
> > version.
>
> See:
>         https://lore.kernel.org/r/ee95520b-cdcc-4e10-a70e-683993cafe36@quicinc.com
> for where the need for a new version is discussed.
>

Thank you for the information. It looks like QCOM specific, but I will
track and test if there was any change for common xhci in the new
version.

Thanks
Puma