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: Rai, Amardeep <amardeep.rai@intel.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Co-developed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/20250820143824.551777-9-sakari.ailus@linux.intel.com
This commit is contained in:
Rai, Amardeep 2025-08-20 17:38:23 +03:00 committed by Greg Kroah-Hartman
parent 0c670dc882
commit 0666a012d2
2 changed files with 12 additions and 4 deletions

View File

@ -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)
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;

View File

@ -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);
}
}