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

usb: core: Add a function to get USB version independent periodic payload



Add usb_endpoint_max_periodic_payload() to obtain maximum payload bytes in
a service interval for isochronous and interrupt endpoints in a USB
version independent way.

Signed-off-by: default avatarRai, Amardeep <amardeep.rai@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>
Reviewed-by: default avatarHans de Goede <hansg@kernel.org>
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-5-sakari.ailus@linux.intel.com
parent 53d76c68
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -1110,6 +1110,35 @@ void usb_free_noncoherent(struct usb_device *dev, size_t size,
}
EXPORT_SYMBOL_GPL(usb_free_noncoherent);

/**
 * usb_endpoint_max_periodic_payload - Get maximum payload bytes per service
 *				       interval
 * @udev: The USB device
 * @ep: The endpoint
 *
 * Returns: the maximum number of bytes isochronous or interrupt endpoint @ep
 * can transfer during a service interval, or 0 for other endpoints.
 */
u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
				      const struct usb_host_endpoint *ep)
{
	if (!usb_endpoint_xfer_isoc(&ep->desc) &&
	    !usb_endpoint_xfer_int(&ep->desc))
		return 0;

	switch (udev->speed) {
	case USB_SPEED_SUPER_PLUS:
		if (USB_SS_SSP_ISOC_COMP(ep->ss_ep_comp.bmAttributes))
			return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval);
		fallthrough;
	case USB_SPEED_SUPER:
		return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
	default:
		return usb_endpoint_maxp(&ep->desc) * usb_endpoint_maxp_mult(&ep->desc);
	}
}
EXPORT_SYMBOL_GPL(usb_endpoint_max_periodic_payload);

/*
 * Notifications of device and interface registration
 */
+3 −0
Original line number Diff line number Diff line
@@ -2039,6 +2039,9 @@ static inline u16 usb_maxpacket(struct usb_device *udev, int pipe)
	return usb_endpoint_maxp(&ep->desc);
}

u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
				      const struct usb_host_endpoint *ep);

/* translate USB error codes to codes user space understands */
static inline int usb_translate_errors(int error_code)
{