linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] USB: Enable eUSB2 double isochronous bandwidth
@ 2025-06-16  9:37 Mathias Nyman
  2025-06-16  9:37 ` [PATCH 1/3] xhci: Add host support for eUSB2 double isochronous bandwidth devices Mathias Nyman
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Mathias Nyman @ 2025-06-16  9:37 UTC (permalink / raw)
  To: gregkh
  Cc: linux-usb, linux-media, laurent.pinchart, hdegoede, Thinh.Nguyen,
	Mathias Nyman

This series enables support for eUSB2 Double Isochronous IN Bandwidth
uvc devices specified in 'USB 2.0 Double Isochronous IN Bandwidth' ECN.

In short it adds support for new integrated USB2 webcams that can send
twice the data compared to conventional USB2 webcams.

These devices are identified by the device descriptor bcdUSB 0x0220
value. They have an additional eUSB2 Isochronous Endpoint Companion
Descriptor, and a zero max packet size in regular isoc endpoint
descriptor. Support for parsing that new descriptor was added in commit

c749f058b437 ("USB: core: Add eUSB2 descriptor and parsing in USB core")

This series adds support to uvc, usb core, and xhci to identify eUSB2
double isoc devices, and allow and set proper max packet, iso frame
desc sizes, bytes per interval, and other values in URBs and xHCI
endpoint contexts needed to support the double data rates for eUSB2
double isoc devices.

Patch 1/3 containing the xhci changes was previously sent as part of
other xhci features, but was dropped.
It now contains the USB_SPEED_HIGH check disussed with Thinh Nguyen.

Thanks
Mathias

Amardeep Rai (2):
  xhci: Add host support for eUSB2 double isochronous bandwidth devices
  USB: core: support eUSB2 double bandwidth large isoc URB frames

Tao Q Tao (1):
  media: uvcvideo: eUSB2 double isochronous bandwidth support

 drivers/media/usb/uvc/uvc_video.c |  5 +++
 drivers/usb/core/urb.c            | 18 +++++++--
 drivers/usb/host/xhci-caps.h      |  2 +
 drivers/usb/host/xhci-mem.c       | 62 ++++++++++++++++++++++++-------
 drivers/usb/host/xhci-ring.c      |  6 +--
 drivers/usb/host/xhci.c           | 16 +++++++-
 drivers/usb/host/xhci.h           | 20 ++++++++++
 7 files changed, 108 insertions(+), 21 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] xhci: Add host support for eUSB2 double isochronous bandwidth devices
  2025-06-16  9:37 [PATCH 0/3] USB: Enable eUSB2 double isochronous bandwidth Mathias Nyman
@ 2025-06-16  9:37 ` Mathias Nyman
  2025-06-16  9:37 ` [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames Mathias Nyman
  2025-06-16  9:37 ` [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support Mathias Nyman
  2 siblings, 0 replies; 9+ messages in thread
From: Mathias Nyman @ 2025-06-16  9:37 UTC (permalink / raw)
  To: gregkh
  Cc: linux-usb, linux-media, laurent.pinchart, hdegoede, Thinh.Nguyen,
	Amardeep Rai, Kannappan R, Sakari Ailus, Mathias Nyman

From: Amardeep Rai <amardeep.rai@intel.com>

Detect eUSB2 double isoc bw capable hosts and devices, and set the proper
xhci endpoint context values such as 'Mult', 'Max Burst Size', and 'Max
ESIT Payload' to enable the double isochronous bandwidth endpoints.

Intel xHC uses the endpoint context 'Mult' field for eUSB2 isoc
endpoints even if hosts supporting Large ESIT Payload Capability should
normally ignore the mult field.

Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
Co-developed-by: Kannappan R <r.kannappan@intel.com>
Signed-off-by: Kannappan R <r.kannappan@intel.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-caps.h |  2 ++
 drivers/usb/host/xhci-mem.c  | 62 ++++++++++++++++++++++++++++--------
 drivers/usb/host/xhci-ring.c |  6 ++--
 drivers/usb/host/xhci.c      | 16 +++++++++-
 drivers/usb/host/xhci.h      | 20 ++++++++++++
 5 files changed, 89 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/host/xhci-caps.h b/drivers/usb/host/xhci-caps.h
index 4b8ff4815644..723a56052439 100644
--- a/drivers/usb/host/xhci-caps.h
+++ b/drivers/usb/host/xhci-caps.h
@@ -89,3 +89,5 @@
 #define HCC2_GSC(p)             ((p) & (1 << 8))
 /* true: HC support Virtualization Based Trusted I/O Capability */
 #define HCC2_VTC(p)             ((p) & (1 << 9))
+/* true: HC support Double BW on a eUSB2 HS ISOC EP */
+#define HCC2_EUSB2_DIC(p)	((p) & (1 << 11))
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bd745a0f2f78..ff55173d815f 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1328,18 +1328,36 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
 	return interval;
 }
 
-/* The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps.
+/*
+ * xHCs without LEC use the "Mult" field in the endpoint context for SuperSpeed
+ * isoc eps, and High speed isoc eps that support bandwidth doubling. Standard
  * High speed endpoint descriptors can define "the number of additional
  * transaction opportunities per microframe", but that goes in the Max Burst
  * endpoint context field.
  */
-static u32 xhci_get_endpoint_mult(struct usb_device *udev,
-		struct usb_host_endpoint *ep)
+static u32 xhci_get_endpoint_mult(struct xhci_hcd *xhci,
+				  struct usb_device *udev,
+				  struct usb_host_endpoint *ep)
 {
-	if (udev->speed < USB_SPEED_SUPER ||
-			!usb_endpoint_xfer_isoc(&ep->desc))
+	bool lec;
+
+	/* xHCI 1.1 with LEC set does not use mult field, except intel eUSB2 */
+	lec = xhci->hci_version > 0x100 && HCC2_LEC(xhci->hcc_params2);
+
+	/* eUSB2 double isoc bw devices are the only USB2 devices using mult */
+	if (xhci_eusb2_is_isoc_bw_double(udev, ep)) {
+		if (!lec || xhci->quirks & XHCI_INTEL_HOST)
+			return 1;
+	}
+
+	/* Oherwise only isoc transfers on hosts without LEC uses mult field */
+	if (!usb_endpoint_xfer_isoc(&ep->desc) || lec)
 		return 0;
-	return ep->ss_ep_comp.bmAttributes;
+
+	if (udev->speed >= USB_SPEED_SUPER)
+		return ep->ss_ep_comp.bmAttributes;
+
+	return 0;
 }
 
 static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
@@ -1351,8 +1369,18 @@ static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
 
 	if (udev->speed == USB_SPEED_HIGH &&
 	    (usb_endpoint_xfer_isoc(&ep->desc) ||
-	     usb_endpoint_xfer_int(&ep->desc)))
-		return usb_endpoint_maxp_mult(&ep->desc) - 1;
+	     usb_endpoint_xfer_int(&ep->desc))) {
+		if (xhci_eusb2_is_isoc_bw_double(udev, ep))
+			/*
+			 * eUSB2 double isoc bw endpoints max packet field
+			 * service opportunity bits 12:11 are not valid, so set
+			 * the ctx burst to max service opportunity "2" as these
+			 * eps support transferring over 3072 bytes per interval
+			 */
+			return 2;
+		else
+			return usb_endpoint_maxp_mult(&ep->desc) - 1;
+	}
 
 	return 0;
 }
@@ -1400,6 +1428,10 @@ static u32 xhci_get_max_esit_payload(struct usb_device *udev,
 	if (udev->speed >= USB_SPEED_SUPER)
 		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
 
+	/* High speed eUSB2 double isoc bw with over 3072 bytes per esit */
+	if (xhci_eusb2_is_isoc_bw_double(udev, ep))
+		return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
+
 	max_packet = usb_endpoint_maxp(&ep->desc);
 	max_burst = usb_endpoint_maxp_mult(&ep->desc);
 	/* A 0 in max burst means 1 transfer per ESIT */
@@ -1437,6 +1469,13 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
 
 	ring_type = usb_endpoint_type(&ep->desc);
 
+	/* Ensure host supports double isoc bandwidth for eUSB2 devices */
+	if (xhci_eusb2_is_isoc_bw_double(udev, ep) &&
+	    !HCC2_EUSB2_DIC(xhci->hcc_params2))	{
+		dev_dbg(&udev->dev, "Double Isoc Bandwidth not supported by xhci\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * Get values to fill the endpoint context, mostly from ep descriptor.
 	 * The average TRB buffer lengt for bulk endpoints is unclear as we
@@ -1456,8 +1495,8 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
 		}
 	}
 
-	mult = xhci_get_endpoint_mult(udev, ep);
-	max_packet = usb_endpoint_maxp(&ep->desc);
+	mult = xhci_get_endpoint_mult(xhci, udev, ep);
+	max_packet = xhci_usb_endpoint_maxp(udev, ep);
 	max_burst = xhci_get_endpoint_max_burst(udev, ep);
 	avg_trb_len = max_esit_payload;
 
@@ -1478,9 +1517,6 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
 	/* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */
 	if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
 		avg_trb_len = 8;
-	/* xhci 1.1 with LEC support doesn't use mult field, use RsvdZ */
-	if ((xhci->hci_version > 0x100) && HCC2_LEC(xhci->hcc_params2))
-		mult = 0;
 
 	/* Set up the endpoint ring */
 	virt_dev->eps[ep_index].new_ring =
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e038ad3375dc..2f59e7a91dda 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3543,7 +3543,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
 	if ((xhci->quirks & XHCI_MTK_HOST) && (xhci->hci_version < 0x100))
 		trb_buff_len = 0;
 
-	maxp = usb_endpoint_maxp(&urb->ep->desc);
+	maxp = xhci_usb_endpoint_maxp(urb->dev, urb->ep);
 	total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
 
 	/* Queueing functions don't count the current TRB into transferred */
@@ -3560,7 +3560,7 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len,
 	u32 new_buff_len;
 	size_t len;
 
-	max_pkt = usb_endpoint_maxp(&urb->ep->desc);
+	max_pkt = xhci_usb_endpoint_maxp(urb->dev, urb->ep);
 	unalign = (enqd_len + *trb_buff_len) % max_pkt;
 
 	/* we got lucky, last normal TRB data on segment is packet aligned */
@@ -4131,7 +4131,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		addr = start_addr + urb->iso_frame_desc[i].offset;
 		td_len = urb->iso_frame_desc[i].length;
 		td_remain_len = td_len;
-		max_pkt = usb_endpoint_maxp(&urb->ep->desc);
+		max_pkt = xhci_usb_endpoint_maxp(urb->dev, urb->ep);
 		total_pkt_count = DIV_ROUND_UP(td_len, max_pkt);
 
 		/* A zero-length transfer still involves at least one packet. */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 4e6dbd2375c3..c65e0e1fefcf 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1353,7 +1353,7 @@ static bool xhci_urb_temp_buffer_required(struct usb_hcd *hcd,
 	struct scatterlist *tail_sg;
 
 	tail_sg = urb->sg;
-	max_pkt = usb_endpoint_maxp(&urb->ep->desc);
+	max_pkt = xhci_usb_endpoint_maxp(urb->dev, urb->ep);
 
 	if (!urb->num_sgs)
 		return ret;
@@ -2941,6 +2941,20 @@ int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, int
 }
 EXPORT_SYMBOL_GPL(xhci_stop_endpoint_sync);
 
+/*
+ * xhci_usb_endpoint_maxp - get endpoint max packet size
+ * @host_ep: USB host endpoint to be checked
+ *
+ * Returns max packet from the correct descriptor
+ */
+int xhci_usb_endpoint_maxp(struct usb_device *udev,
+			   struct usb_host_endpoint *host_ep)
+{
+	if (xhci_eusb2_is_isoc_bw_double(udev, host_ep))
+		return le16_to_cpu(host_ep->eusb2_isoc_ep_comp.wMaxPacketSize);
+	return usb_endpoint_maxp(&host_ep->desc);
+}
+
 /* Issue a configure endpoint command or evaluate context command
  * and wait for it to finish.
  */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 49887a303e43..21cf1eacfc92 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1735,6 +1735,24 @@ static inline bool xhci_has_one_roothub(struct xhci_hcd *xhci)
 	       (!xhci->usb2_rhub.num_ports || !xhci->usb3_rhub.num_ports);
 }
 
+/*
+ * USB 2.0 specification, chapter 5.6.4 Isochronous Transfer Bus Access
+ * Constraint. A high speed endpoint can move up to 3072 bytes per microframe
+ * (or 192Mb/s).
+ */
+#define MAX_ISOC_XFER_SIZE_HS  3072
+
+static inline bool xhci_eusb2_is_isoc_bw_double(struct usb_device *udev,
+						struct usb_host_endpoint *ep)
+{
+	return le16_to_cpu(udev->descriptor.bcdUSB) == 0x220 &&
+		udev->speed == USB_SPEED_HIGH &&
+		usb_endpoint_xfer_isoc(&ep->desc) &&
+		le16_to_cpu(ep->desc.wMaxPacketSize) == 0 &&
+		le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval) >
+		MAX_ISOC_XFER_SIZE_HS;
+}
+
 #define xhci_dbg(xhci, fmt, args...) \
 	dev_dbg(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
 #define xhci_err(xhci, fmt, args...) \
@@ -1958,6 +1976,8 @@ void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
 			      struct xhci_interrupter *ir,
 			      bool clear_ehb);
 void xhci_add_interrupter(struct xhci_hcd *xhci, unsigned int intr_num);
+int xhci_usb_endpoint_maxp(struct usb_device *udev,
+			   struct usb_host_endpoint *host_ep);
 
 /* xHCI roothub code */
 void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames
  2025-06-16  9:37 [PATCH 0/3] USB: Enable eUSB2 double isochronous bandwidth Mathias Nyman
  2025-06-16  9:37 ` [PATCH 1/3] xhci: Add host support for eUSB2 double isochronous bandwidth devices Mathias Nyman
@ 2025-06-16  9:37 ` Mathias Nyman
  2025-06-16 14:07   ` Alan Stern
  2025-06-16  9:37 ` [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support Mathias Nyman
  2 siblings, 1 reply; 9+ messages in thread
From: Mathias Nyman @ 2025-06-16  9:37 UTC (permalink / raw)
  To: gregkh
  Cc: linux-usb, linux-media, laurent.pinchart, hdegoede, Thinh.Nguyen,
	Amardeep Rai, Sakari Ailus, Mathias Nyman

From: Amardeep Rai <amardeep.rai@intel.com>

eUSB2 double isochronous in bandwidth devices support up to 6 transactions
per microframe, and thus doubles the total bytes possible to receive per
microframe.

Support larger URB isoc frame sizes for eUSB2 double isoc in endpoints.

Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/core/urb.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 5e52a35486af..911091b92fd7 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -372,6 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 	struct usb_host_endpoint	*ep;
 	int				is_out;
 	unsigned int			allowed;
+	bool				is_eusb2_isoch_double;
 
 	if (!urb || !urb->complete)
 		return -EINVAL;
@@ -434,7 +435,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 		return -ENODEV;
 
 	max = usb_endpoint_maxp(&ep->desc);
-	if (max <= 0) {
+	is_eusb2_isoch_double = dev->speed == USB_SPEED_HIGH &&
+				xfertype == USB_ENDPOINT_XFER_ISOC &&
+				usb_endpoint_dir_in(&ep->desc) &&
+				le16_to_cpu(dev->descriptor.bcdUSB == 0x220) &&
+				le16_to_cpu(ep->desc.wMaxPacketSize == 0);
+	if (max < 0 || (max == 0 && !is_eusb2_isoch_double)) {
 		dev_dbg(&dev->dev,
 			"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
 			usb_endpoint_num(&ep->desc), is_out ? "out" : "in",
@@ -467,9 +473,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 			max = le32_to_cpu(isoc_ep_comp->dwBytesPerInterval);
 		}
 
-		/* "high bandwidth" mode, 1-3 packets/uframe? */
-		if (dev->speed == USB_SPEED_HIGH)
-			max *= usb_endpoint_maxp_mult(&ep->desc);
+		/* High speed, 1-3 packets/uframe, max 6 for eUSB2 double bw */
+		if (dev->speed == USB_SPEED_HIGH) {
+			if (is_eusb2_isoch_double)
+				max = le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
+			else
+				max *= usb_endpoint_maxp_mult(&ep->desc);
+		}
 
 		if (urb->number_of_packets <= 0)
 			return -EINVAL;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support
  2025-06-16  9:37 [PATCH 0/3] USB: Enable eUSB2 double isochronous bandwidth Mathias Nyman
  2025-06-16  9:37 ` [PATCH 1/3] xhci: Add host support for eUSB2 double isochronous bandwidth devices Mathias Nyman
  2025-06-16  9:37 ` [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames Mathias Nyman
@ 2025-06-16  9:37 ` Mathias Nyman
  2025-06-16  9:43   ` Laurent Pinchart
  2 siblings, 1 reply; 9+ messages in thread
From: Mathias Nyman @ 2025-06-16  9:37 UTC (permalink / raw)
  To: gregkh
  Cc: linux-usb, linux-media, laurent.pinchart, hdegoede, Thinh.Nguyen,
	Tao Q Tao, Amardeep Rai, Sakari Ailus, Mathias Nyman

From: Tao Q Tao <tao.q.tao@intel.com>

Add eUSB2 support to check total number of bytes, isochronous endpoint
will transfer every service interval(SI).

Co-developed-by: Amardeep Rai <amardeep.rai@intel.com>
Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
Signed-off-by: Tao Q Tao <tao.q.tao@intel.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/media/usb/uvc/uvc_video.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index e3567aeb0007..a888f84208c6 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1906,6 +1906,11 @@ u16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep)
 	case USB_SPEED_SUPER:
 	case USB_SPEED_SUPER_PLUS:
 		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
+	case USB_SPEED_HIGH:
+		psize = usb_endpoint_maxp(&ep->desc);
+		if (psize == 0 && le16_to_cpu(dev->descriptor.bcdUSB) == 0x220)
+			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
+		fallthrough;
 	default:
 		psize = usb_endpoint_maxp(&ep->desc);
 		psize *= usb_endpoint_maxp_mult(&ep->desc);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support
  2025-06-16  9:37 ` [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support Mathias Nyman
@ 2025-06-16  9:43   ` Laurent Pinchart
  2025-06-16 13:05     ` Mathias Nyman
  0 siblings, 1 reply; 9+ messages in thread
From: Laurent Pinchart @ 2025-06-16  9:43 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: gregkh, linux-usb, linux-media, hdegoede, Thinh.Nguyen, Tao Q Tao,
	Amardeep Rai, Sakari Ailus

Hi Mathias,

Thank you for the patch.

On Mon, Jun 16, 2025 at 12:37:30PM +0300, Mathias Nyman wrote:
> From: Tao Q Tao <tao.q.tao@intel.com>
> 
> Add eUSB2 support to check total number of bytes, isochronous endpoint
> will transfer every service interval(SI).
> 
> Co-developed-by: Amardeep Rai <amardeep.rai@intel.com>
> Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
> Signed-off-by: Tao Q Tao <tao.q.tao@intel.com>
> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> ---
>  drivers/media/usb/uvc/uvc_video.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> index e3567aeb0007..a888f84208c6 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -1906,6 +1906,11 @@ u16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep)
>  	case USB_SPEED_SUPER:
>  	case USB_SPEED_SUPER_PLUS:
>  		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
> +	case USB_SPEED_HIGH:
> +		psize = usb_endpoint_maxp(&ep->desc);
> +		if (psize == 0 && le16_to_cpu(dev->descriptor.bcdUSB) == 0x220)
> +			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
> +		fallthrough;

Instead of adding yet another case here, and eventually in a bunch of
other drivers, could we centralize retrieval of the maximum bpi value in
a helper function provided by the USB core ?

>  	default:
>  		psize = usb_endpoint_maxp(&ep->desc);
>  		psize *= usb_endpoint_maxp_mult(&ep->desc);

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support
  2025-06-16  9:43   ` Laurent Pinchart
@ 2025-06-16 13:05     ` Mathias Nyman
  2025-06-16 13:22       ` Laurent Pinchart
  0 siblings, 1 reply; 9+ messages in thread
From: Mathias Nyman @ 2025-06-16 13:05 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: gregkh, linux-usb, linux-media, hdegoede, Thinh.Nguyen, Tao Q Tao,
	Amardeep Rai, Sakari Ailus

On 16.6.2025 12.43, Laurent Pinchart wrote:
> Hi Mathias,
> 
> Thank you for the patch.
> 
> On Mon, Jun 16, 2025 at 12:37:30PM +0300, Mathias Nyman wrote:
>> From: Tao Q Tao <tao.q.tao@intel.com>
>>
>> Add eUSB2 support to check total number of bytes, isochronous endpoint
>> will transfer every service interval(SI).
>>
>> Co-developed-by: Amardeep Rai <amardeep.rai@intel.com>
>> Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
>> Signed-off-by: Tao Q Tao <tao.q.tao@intel.com>
>> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
>> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
>> ---
>>   drivers/media/usb/uvc/uvc_video.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
>> index e3567aeb0007..a888f84208c6 100644
>> --- a/drivers/media/usb/uvc/uvc_video.c
>> +++ b/drivers/media/usb/uvc/uvc_video.c
>> @@ -1906,6 +1906,11 @@ u16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep)
>>   	case USB_SPEED_SUPER:
>>   	case USB_SPEED_SUPER_PLUS:
>>   		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
>> +	case USB_SPEED_HIGH:
>> +		psize = usb_endpoint_maxp(&ep->desc);
>> +		if (psize == 0 && le16_to_cpu(dev->descriptor.bcdUSB) == 0x220)
>> +			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
>> +		fallthrough;
> 
> Instead of adding yet another case here, and eventually in a bunch of
> other drivers, could we centralize retrieval of the maximum bpi value in
> a helper function provided by the USB core ?

Sounds reasonable to me.
I'm not sure if any other drivers will need it as this feature seems to be made
specifically for integrated webcams, but things evolve.

Thanks
Mathias



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support
  2025-06-16 13:05     ` Mathias Nyman
@ 2025-06-16 13:22       ` Laurent Pinchart
  0 siblings, 0 replies; 9+ messages in thread
From: Laurent Pinchart @ 2025-06-16 13:22 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: gregkh, linux-usb, linux-media, hdegoede, Thinh.Nguyen, Tao Q Tao,
	Amardeep Rai, Sakari Ailus

On Mon, Jun 16, 2025 at 04:05:54PM +0300, Mathias Nyman wrote:
> On 16.6.2025 12.43, Laurent Pinchart wrote:
> > On Mon, Jun 16, 2025 at 12:37:30PM +0300, Mathias Nyman wrote:
> >> From: Tao Q Tao <tao.q.tao@intel.com>
> >>
> >> Add eUSB2 support to check total number of bytes, isochronous endpoint
> >> will transfer every service interval(SI).
> >>
> >> Co-developed-by: Amardeep Rai <amardeep.rai@intel.com>
> >> Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
> >> Signed-off-by: Tao Q Tao <tao.q.tao@intel.com>
> >> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> >> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> >> ---
> >>   drivers/media/usb/uvc/uvc_video.c | 5 +++++
> >>   1 file changed, 5 insertions(+)
> >>
> >> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> >> index e3567aeb0007..a888f84208c6 100644
> >> --- a/drivers/media/usb/uvc/uvc_video.c
> >> +++ b/drivers/media/usb/uvc/uvc_video.c
> >> @@ -1906,6 +1906,11 @@ u16 uvc_endpoint_max_bpi(struct usb_device *dev, struct usb_host_endpoint *ep)
> >>   	case USB_SPEED_SUPER:
> >>   	case USB_SPEED_SUPER_PLUS:
> >>   		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
> >> +	case USB_SPEED_HIGH:
> >> +		psize = usb_endpoint_maxp(&ep->desc);
> >> +		if (psize == 0 && le16_to_cpu(dev->descriptor.bcdUSB) == 0x220)
> >> +			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
> >> +		fallthrough;
> > 
> > Instead of adding yet another case here, and eventually in a bunch of
> > other drivers, could we centralize retrieval of the maximum bpi value in
> > a helper function provided by the USB core ?
> 
> Sounds reasonable to me.
> I'm not sure if any other drivers will need it as this feature seems to be made
> specifically for integrated webcams, but things evolve.

Even if eUSB2 doesn't get used by other devices, I think centralizing
the whole max bpi calculation will be useful to handle the different
USB_SPEED_*.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames
  2025-06-16  9:37 ` [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames Mathias Nyman
@ 2025-06-16 14:07   ` Alan Stern
  2025-06-16 15:36     ` Mathias Nyman
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Stern @ 2025-06-16 14:07 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: gregkh, linux-usb, linux-media, laurent.pinchart, hdegoede,
	Thinh.Nguyen, Amardeep Rai, Sakari Ailus

On Mon, Jun 16, 2025 at 12:37:29PM +0300, Mathias Nyman wrote:
> From: Amardeep Rai <amardeep.rai@intel.com>
> 
> eUSB2 double isochronous in bandwidth devices support up to 6 transactions
> per microframe, and thus doubles the total bytes possible to receive per
> microframe.
> 
> Support larger URB isoc frame sizes for eUSB2 double isoc in endpoints.
> 
> Signed-off-by: Amardeep Rai <amardeep.rai@intel.com>
> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> ---
>  drivers/usb/core/urb.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
> index 5e52a35486af..911091b92fd7 100644
> --- a/drivers/usb/core/urb.c
> +++ b/drivers/usb/core/urb.c
> @@ -372,6 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
>  	struct usb_host_endpoint	*ep;
>  	int				is_out;
>  	unsigned int			allowed;
> +	bool				is_eusb2_isoch_double;
>  
>  	if (!urb || !urb->complete)
>  		return -EINVAL;
> @@ -434,7 +435,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
>  		return -ENODEV;
>  
>  	max = usb_endpoint_maxp(&ep->desc);
> -	if (max <= 0) {
> +	is_eusb2_isoch_double = dev->speed == USB_SPEED_HIGH &&
> +				xfertype == USB_ENDPOINT_XFER_ISOC &&
> +				usb_endpoint_dir_in(&ep->desc) &&
> +				le16_to_cpu(dev->descriptor.bcdUSB == 0x220) &&
> +				le16_to_cpu(ep->desc.wMaxPacketSize == 0);
> +	if (max < 0 || (max == 0 && !is_eusb2_isoch_double)) {

Minor point: It's impossible to have max < 0 here, because 
usb_endpoint_maxp() always returns a non-negative value (the return 
value is &'ed with 0x07ff).  That part of the test can be removed.

Alan Stern

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames
  2025-06-16 14:07   ` Alan Stern
@ 2025-06-16 15:36     ` Mathias Nyman
  0 siblings, 0 replies; 9+ messages in thread
From: Mathias Nyman @ 2025-06-16 15:36 UTC (permalink / raw)
  To: Alan Stern
  Cc: gregkh, linux-usb, linux-media, laurent.pinchart, hdegoede,
	Thinh.Nguyen, Amardeep Rai, Sakari Ailus


>> @@ -434,7 +435,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
>>   		return -ENODEV;
>>   
>>   	max = usb_endpoint_maxp(&ep->desc);
>> -	if (max <= 0) {
>> +	is_eusb2_isoch_double = dev->speed == USB_SPEED_HIGH &&
>> +				xfertype == USB_ENDPOINT_XFER_ISOC &&
>> +				usb_endpoint_dir_in(&ep->desc) &&
>> +				le16_to_cpu(dev->descriptor.bcdUSB == 0x220) &&
>> +				le16_to_cpu(ep->desc.wMaxPacketSize == 0);
>> +	if (max < 0 || (max == 0 && !is_eusb2_isoch_double)) {
> 
> Minor point: It's impossible to have max < 0 here, because
> usb_endpoint_maxp() always returns a non-negative value (the return
> value is &'ed with 0x07ff).  That part of the test can be removed.
> 
> Alan Stern
> 

Thanks, will fix this for v2
-Mathias

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-06-16 15:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-16  9:37 [PATCH 0/3] USB: Enable eUSB2 double isochronous bandwidth Mathias Nyman
2025-06-16  9:37 ` [PATCH 1/3] xhci: Add host support for eUSB2 double isochronous bandwidth devices Mathias Nyman
2025-06-16  9:37 ` [PATCH 2/3] USB: core: support eUSB2 double bandwidth large isoc URB frames Mathias Nyman
2025-06-16 14:07   ` Alan Stern
2025-06-16 15:36     ` Mathias Nyman
2025-06-16  9:37 ` [PATCH 3/3] media: uvcvideo: eUSB2 double isochronous bandwidth support Mathias Nyman
2025-06-16  9:43   ` Laurent Pinchart
2025-06-16 13:05     ` Mathias Nyman
2025-06-16 13:22       ` Laurent Pinchart

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).