Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162464750
D51225.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D51225.diff
View Options
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -548,7 +548,9 @@
enum libusb_speed libusb_get_device_speed(libusb_device * dev);
int libusb_clear_halt(libusb_device_handle *devh, uint8_t endpoint);
int libusb_get_max_packet_size(libusb_device * dev, uint8_t endpoint);
-int libusb_get_max_iso_packet_size(libusb_device * dev, uint8_t endpoint);
+int libusb_get_max_iso_packet_size(libusb_device *dev, uint8_t endpoint);
+int libusb_get_max_alt_packet_size(libusb_device *dev, int interface_number,
+ int alternate_setting, unsigned char endpoint);
libusb_device *libusb_ref_device(libusb_device * dev);
void libusb_unref_device(libusb_device * dev);
int libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle);
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -224,6 +224,12 @@
LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist and
LIBUSB_ERROR_OTHERS on other failure.
.Pp
+.Ft int
+.Fn libusb_get_max_alt_packet_size "libusb_device *dev" "int interface_number" "int alternate_setting" "unsigned char endpoint"
+Returns the maximum packet size which can be sent/received on this endpoint,
+LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist, or
+LIBUSB_ERROR_OTHER on other failure.
+.Pp
.Ft libusb_device *
.Fn libusb_ref_device "libusb_device *dev"
Increment the reference counter of the device
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -536,26 +536,17 @@
return (LIBUSB_SPEED_UNKNOWN);
}
-int
-libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint)
+static const libusb_endpoint_descriptor *
+libusb_get_endpoint_from_config(libusb_config_descriptor *pdconf,
+ uint8_t endpoint)
{
- struct libusb_config_descriptor *pdconf;
struct libusb_interface *pinf;
struct libusb_interface_descriptor *pdinf;
- struct libusb_endpoint_descriptor *pdend;
+ const struct libusb_endpoint_descriptor *pdend;
int i;
int j;
int k;
- int ret;
-
- if (dev == NULL)
- return (LIBUSB_ERROR_NO_DEVICE);
- ret = libusb_get_active_config_descriptor(dev, &pdconf);
- if (ret < 0)
- return (ret);
-
- ret = LIBUSB_ERROR_NOT_FOUND;
for (i = 0; i < pdconf->bNumInterfaces; i++) {
pinf = &pdconf->interface[i];
for (j = 0; j < pinf->num_altsetting; j++) {
@@ -563,39 +554,151 @@
for (k = 0; k < pdinf->bNumEndpoints; k++) {
pdend = &pdinf->endpoint[k];
if (pdend->bEndpointAddress == endpoint) {
- ret = pdend->wMaxPacketSize;
- goto out;
+ return (pdend);
}
}
}
}
-out:
+ return (NULL);
+}
+
+int
+libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint)
+{
+ struct libusb_config_descriptor *pdconf;
+ const struct libusb_endpoint_descriptor *pdend;
+ int ret;
+
+ if (dev == NULL)
+ return (LIBUSB_ERROR_OTHER);
+
+ ret = libusb_get_active_config_descriptor(dev, &pdconf);
+ if (ret < 0)
+ return (ret);
+
+ ret = LIBUSB_ERROR_NOT_FOUND;
+ if ((pdend = libusb_get_endpoint_from_config(pdconf, endpoint)) != NULL)
+ ret = pdend->wMaxPacketSize;
+
libusb_free_config_descriptor(pdconf);
return (ret);
}
+static int
+libusb_calculate_ep_size(libusb_device *dev,
+ const libusb_endpoint_descriptor *ep)
+{
+ struct libusb_ss_endpoint_companion_descriptor *ss_ep;
+ int multiplier;
+ int speed;
+ int ret = LIBUSB_ERROR_NOT_SUPPORTED;
+ enum libusb_endpoint_transfer_type type;
+
+ speed = libusb_get_device_speed(dev);
+ if (speed >= LIBUSB_SPEED_SUPER) {
+ ret = libusb_get_ss_endpoint_companion_descriptor(dev->ctx, ep,
+ &ss_ep);
+ if (ret == LIBUSB_SUCCESS) {
+ ret = ss_ep->wBytesPerInterval;
+ libusb_free_ss_endpoint_companion_descriptor(ss_ep);
+ }
+ }
+
+ /*
+ * reference:
+ * https://www.keil.com/pack/doc/mw/usb/html/_u_s_b__endpoint__descriptor.html
+ */
+ if (ret < 0) {
+ ret = ep->wMaxPacketSize;
+ switch (speed) {
+ case LIBUSB_SPEED_LOW:
+ case LIBUSB_SPEED_FULL:
+ break;
+ default:
+ type = ep->bmAttributes & 0x3;
+ if (type == LIBUSB_ENDPOINT_TRANSFER_TYPE_ISOCHRONOUS ||
+ type == LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT) {
+ multiplier = (1 + ((ret >> 11) & 3));
+ if (multiplier > 3)
+ multiplier = 3;
+ ret = (ret & 0x7FF) * multiplier;
+ }
+ break;
+ }
+ }
+
+ return (ret);
+}
+
int
libusb_get_max_iso_packet_size(libusb_device *dev, uint8_t endpoint)
{
- int multiplier;
+ struct libusb_config_descriptor *pdconf;
+ const struct libusb_endpoint_descriptor *pdend;
int ret;
- ret = libusb_get_max_packet_size(dev, endpoint);
+ if (dev == NULL)
+ return (LIBUSB_ERROR_OTHER);
- switch (libusb20_dev_get_speed(dev->os_priv)) {
- case LIBUSB20_SPEED_LOW:
- case LIBUSB20_SPEED_FULL:
- break;
- default:
- if (ret > -1) {
- multiplier = (1 + ((ret >> 11) & 3));
- if (multiplier > 3)
- multiplier = 3;
- ret = (ret & 0x7FF) * multiplier;
+ ret = libusb_get_active_config_descriptor(dev, &pdconf);
+ if (ret < 0)
+ return (LIBUSB_ERROR_OTHER);
+
+ pdend = libusb_get_endpoint_from_config(pdconf, endpoint);
+ if (pdend == NULL) {
+ libusb_free_config_descriptor(pdconf);
+ return (LIBUSB_ERROR_NOT_FOUND);
+ }
+
+ ret = libusb_calculate_ep_size(dev, pdend);
+ libusb_free_config_descriptor(pdconf);
+ return (ret);
+}
+
+int
+libusb_get_max_alt_packet_size(libusb_device *dev, int interface_number,
+ int alternate_setting, unsigned char endpoint)
+{
+ struct libusb_config_descriptor *pdconf;
+ struct libusb_interface *pinf;
+ struct libusb_interface_descriptor *pdinf;
+ const struct libusb_endpoint_descriptor *pdend = NULL;
+ const struct libusb_endpoint_descriptor *pdend_tmp;
+ int ret, i;
+
+ if (dev == NULL)
+ return (LIBUSB_ERROR_OTHER);
+
+ ret = libusb_get_active_config_descriptor(dev, &pdconf);
+ if (ret < 0)
+ return (LIBUSB_ERROR_OTHER);
+
+ if (pdconf->bNumInterfaces <= interface_number) {
+ libusb_free_config_descriptor(pdconf);
+ return (LIBUSB_ERROR_NOT_FOUND);
+ }
+ pinf = &pdconf->interface[interface_number];
+
+ if (pinf->num_altsetting <= alternate_setting) {
+ libusb_free_config_descriptor(pdconf);
+ return (LIBUSB_ERROR_NOT_FOUND);
+ }
+ pdinf = &pinf->altsetting[alternate_setting];
+
+ for (i = 0; i < pdinf->bNumEndpoints; ++i) {
+ pdend_tmp = &pdinf->endpoint[i];
+ if (pdend_tmp->bEndpointAddress == endpoint) {
+ pdend = pdend_tmp;
+ break;
}
- break;
}
+ if (pdend != NULL)
+ ret = libusb_calculate_ep_size(dev, pdend);
+ else
+ ret = LIBUSB_ERROR_NOT_FOUND;
+ libusb_free_config_descriptor(pdconf);
+
return (ret);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jul 14, 2:16 PM (8 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35067355
Default Alt Text
D51225.diff (6 KB)
Attached To
Mode
D51225: libusb: implement libusb_get_max_alt_packet_size
Attached
Detach File
Event Timeline
Log In to Comment