summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrhan aib Kavrakoglu <aibok42@gmail.com>2022-07-21 10:37:05 +0300
committerTormod Volden <debian.tormod@gmail.com>2023-01-21 11:26:11 +0100
commit9b42fdd78770a104e4e552153a20f2cb0e1acecf (patch)
treea69e8866cf59d2f91bfa1a54a81d0e4e6271b08b
parent94eb23991bc257ad9129e82983a7df8efa9b285e (diff)
downloadlibusb-9b42fdd78770a104e4e552153a20f2cb0e1acecf.tar.gz
core: Add libusb_get_max_alt_packet_size()
Closes #1167
-rw-r--r--libusb/core.c66
-rw-r--r--libusb/libusb-1.0.def2
-rw-r--r--libusb/libusb.h2
-rw-r--r--libusb/version_nano.h2
4 files changed, 71 insertions, 1 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 61b6564..3249152 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -414,6 +414,7 @@ if (cfg != desired)
* - libusb_get_device_speed()
* - libusb_get_iso_packet_buffer()
* - libusb_get_iso_packet_buffer_simple()
+ * - libusb_get_max_alt_packet_size()
* - libusb_get_max_iso_packet_size()
* - libusb_get_max_packet_size()
* - libusb_get_next_timeout()
@@ -1160,6 +1161,10 @@ static int get_endpoint_max_packet_size(libusb_device *dev,
* libusb_set_iso_packet_lengths() in order to set the length field of every
* isochronous packet in a transfer.
*
+ * This function only considers the first alternate setting of the interface.
+ * If the endpoint has different maximum packet sizes for different alternate
+ * settings, you probably want libusb_get_max_alt_packet_size() instead.
+ *
* Since v1.0.3.
*
* \param dev a device
@@ -1167,6 +1172,7 @@ static int get_endpoint_max_packet_size(libusb_device *dev,
* \returns the maximum packet size which can be sent/received on this endpoint
* \returns \ref LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
* \returns \ref LIBUSB_ERROR_OTHER on other failure
+ * \see libusb_get_max_alt_packet_size
*/
int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev,
unsigned char endpoint)
@@ -1196,6 +1202,66 @@ out:
}
/** \ingroup libusb_dev
+ * Calculate the maximum packet size which a specific endpoint is capable of
+ * sending or receiving in the duration of 1 microframe
+ *
+ * Only the active configuration is examined. The calculation is based on the
+ * wMaxPacketSize field in the endpoint descriptor as described in section
+ * 9.6.6 in the USB 2.0 specifications.
+ *
+ * If acting on an isochronous or interrupt endpoint, this function will
+ * multiply the value found in bits 0:10 by the number of transactions per
+ * microframe (determined by bits 11:12). Otherwise, this function just
+ * returns the numeric value found in bits 0:10. For USB 3.0 device, it
+ * will attempts to retrieve the Endpoint Companion Descriptor to return
+ * wBytesPerInterval.
+ *
+ * This function is useful for setting up isochronous transfers, for example
+ * you might pass the return value from this function to
+ * libusb_set_iso_packet_lengths() in order to set the length field of every
+ * isochronous packet in a transfer.
+ *
+ * Since v1.0.27.
+ *
+ * \param dev a device
+ * \param interface_number the <tt>bInterfaceNumber</tt> of the interface
+ * the endpoint belongs to
+ * \param alternate_setting the <tt>bAlternateSetting</tt> of the interface
+ * \param endpoint address of the endpoint in question
+ * \returns the maximum packet size which can be sent/received on this endpoint
+ * \returns \ref LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
+ * \returns \ref LIBUSB_ERROR_OTHER on other failure
+ * \see libusb_get_max_iso_packet_size
+ */
+int API_EXPORTED libusb_get_max_alt_packet_size(libusb_device *dev,
+ int interface_number, int alternate_setting, unsigned char endpoint)
+{
+ struct libusb_config_descriptor *config;
+ const struct libusb_endpoint_descriptor *ep;
+ int r;
+
+ r = libusb_get_active_config_descriptor(dev, &config);
+ if (r < 0) {
+ usbi_err(DEVICE_CTX(dev),
+ "could not retrieve active config descriptor");
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ ep = find_alt_endpoint(config, interface_number,
+ alternate_setting, endpoint);
+ if (!ep) {
+ r = LIBUSB_ERROR_NOT_FOUND;
+ goto out;
+ }
+
+ r = get_endpoint_max_packet_size(dev, ep);
+
+out:
+ libusb_free_config_descriptor(config);
+ return r;
+}
+
+/** \ingroup libusb_dev
* Increment the reference count of a device.
* \param dev the device to reference
* \returns the same device
diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def
index 0d41330..6d7caa7 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -84,6 +84,8 @@ EXPORTS
libusb_get_device_speed@4 = libusb_get_device_speed
libusb_get_interface_association_descriptors
libusb_get_interface_association_descriptors@12 = libusb_get_interface_association_descriptors
+ libusb_get_max_alt_packet_size
+ libusb_get_max_alt_packet_size@16 = libusb_get_max_alt_packet_size
libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
libusb_get_max_packet_size
diff --git a/libusb/libusb.h b/libusb/libusb.h
index ed54d91..e5243b9 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -1639,6 +1639,8 @@ int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev,
unsigned char endpoint);
int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev,
unsigned char endpoint);
+int LIBUSB_CALL libusb_get_max_alt_packet_size(libusb_device *dev,
+ int interface_number, int alternate_setting, unsigned char endpoint);
int LIBUSB_CALL libusb_get_interface_association_descriptors(libusb_device *dev,
uint8_t config_index, struct libusb_interface_association_descriptor_array **iad_array);
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index ee98827..2d80a81 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11774
+#define LIBUSB_NANO 11775