Commit 0666a012 authored by Rai, Amardeep's avatar Rai, Amardeep Committed by Greg Kroah-Hartman
Browse files

usb: core: support eUSB2 double bandwidth large isoc URB frames



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.

Also usb_endpoint_maxp() returns a natural number so there's no need to
assume it could be < 0.

Signed-off-by: default avatarRai, Amardeep <amardeep.rai@intel.com>
Reviewed-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Co-developed-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Acked-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/20250820143824.551777-9-sakari.ailus@linux.intel.com
parent 0c670dc8
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -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,8 @@ 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 = usb_endpoint_is_hs_isoc_double(dev, ep);
	if (!max && !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 +469,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)
		/* 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 −0
Original line number Diff line number Diff line
@@ -1134,6 +1134,8 @@ u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
	case USB_SPEED_SUPER:
		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
	default:
		if (usb_endpoint_is_hs_isoc_double(udev, ep))
			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
		return usb_endpoint_maxp(&ep->desc) * usb_endpoint_maxp_mult(&ep->desc);
	}
}