[PATCH v4 3/4] USB: Add a function to obtain USB version independent maximum bpi value

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Rai, Amardeep" <amardeep.rai@xxxxxxxxx>

Add usb_endpoint_max_isoc_bpi() to obtain maximum bytes per interval for
isochronous endpoints in a USB version independent way.

Signed-off-by: Rai, Amardeep <amardeep.rai@xxxxxxxxx>
Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
Co-developed-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
Reviewed-by: Hans de Goede <hansg@xxxxxxxxxx>
---
 drivers/usb/core/usb.c | 32 ++++++++++++++++++++++++++++++++
 include/linux/usb.h    |  3 +++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index fca7735fc660..3e80a5b3e41b 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1110,6 +1110,38 @@ void usb_free_noncoherent(struct usb_device *dev, size_t size,
 }
 EXPORT_SYMBOL_GPL(usb_free_noncoherent);
 
+/**
+ * usb_endpoint_max_isoc_bpi - Get maximum isochronous transfer bytes per interval
+ * @dev: The USB device
+ * @ep: The endpoint
+ *
+ * Returns: the maximum number of bytes isochronous endpoint @endpoint can
+ * transfer in during a service interval, or 0 for non-isochronous endpoints.
+ */
+u32 usb_endpoint_max_isoc_bpi(struct usb_device *dev,
+			      const struct usb_host_endpoint *ep)
+{
+	if (usb_endpoint_type(&ep->desc) != USB_ENDPOINT_XFER_ISOC)
+		return 0;
+
+	switch (dev->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);
+	case USB_SPEED_HIGH:
+		if (ep->eusb2_isoc_ep_comp.bDescriptorType &&
+		    !usb_endpoint_maxp(&ep->desc) && usb_endpoint_dir_in(&ep->desc))
+			return le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval);
+		fallthrough;
+	default:
+		return usb_endpoint_maxp(&ep->desc) * usb_endpoint_maxp_mult(&ep->desc);
+	}
+}
+EXPORT_SYMBOL_GPL(usb_endpoint_max_isoc_bpi);
+
 /*
  * Notifications of device and interface registration
  */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 535ac37198a1..b38978abc3d6 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -2049,6 +2049,9 @@ static inline int usb_translate_errors(int error_code)
 	}
 }
 
+u32 usb_endpoint_max_isoc_bpi(struct usb_device *dev,
+			      const struct usb_host_endpoint *ep);
+
 /* Events from the usb core */
 #define USB_DEVICE_ADD		0x0001
 #define USB_DEVICE_REMOVE	0x0002
-- 
2.39.5





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux