Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142890028
D51225.id.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.id.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
@@ -119,6 +119,13 @@
#define LIBUSB_TRANSFER_TYPE_MASK 0x03
+enum libusb_endpoint_transfer_type {
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_CONTROL = 0,
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_ISOCHRONOUS = 1,
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK = 2,
+ LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT = 3,
+};
+
enum libusb_transfer_type {
LIBUSB_TRANSFER_TYPE_CONTROL = 0,
LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1,
@@ -515,7 +522,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
@@ -198,6 +198,13 @@
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 packet on success,
+LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist and
+LIBUSB_ERROR_OTHERS on other failure.
+For iso and interrupt packet, it will multiply the multiplixer as the standard described.
+.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
@@ -526,26 +526,17 @@
return (LIBUSB_SPEED_UNKNOWN);
}
-int
-libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint)
+static 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;
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++) {
@@ -553,39 +544,147 @@
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;
+ struct libusb_endpoint_descriptor *pdend;
+ 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;
+ 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, libusb_endpoint_descriptor *ep)
+{
+ struct libusb_ss_endpoint_companion_descriptor *ss_ep;
+ int multiplier;
+ int speed;
+ int ret = 0;
+ 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)
+ return (ret);
+ 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 (libusb20_dev_get_speed(dev->os_priv)) {
+ case LIBUSB20_SPEED_LOW:
+ case LIBUSB20_SPEED_FULL:
+ break;
+ default:
+ type = ep->bmAttributes & 0x3;
+ if (ret > -1 &&
+ (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;
+ struct libusb_endpoint_descriptor *pdend;
int ret;
- ret = libusb_get_max_packet_size(dev, endpoint);
+ if (dev == NULL)
+ return (LIBUSB_ERROR_NO_DEVICE);
- 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;
- }
- break;
+ ret = libusb_get_active_config_descriptor(dev, &pdconf);
+ if (ret < 0)
+ return (ret);
+
+ 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;
+ struct libusb_endpoint_descriptor *pdend;
+ int ret;
+
+ if (dev == NULL)
+ return (LIBUSB_ERROR_NO_DEVICE);
+
+ ret = libusb_get_active_config_descriptor(dev, &pdconf);
+ if (ret < 0)
+ return (ret);
+
+ 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];
+
+ if (pdinf->bNumEndpoints <= endpoint) {
+ libusb_free_config_descriptor(pdconf);
+ return (LIBUSB_ERROR_NOT_FOUND);
}
+ pdend = &pdinf->endpoint[endpoint];
+ ret = libusb_calculate_ep_size(dev, pdend);
+ libusb_free_config_descriptor(pdconf);
+
return (ret);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 25, 12:23 PM (2 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27940306
Default Alt Text
D51225.id.diff (6 KB)
Attached To
Mode
D51225: libusb: implement libusb_get_max_alt_packet_size
Attached
Detach File
Event Timeline
Log In to Comment