Page MenuHomeFreeBSD

D51225.id.diff
No OneTemporary

D51225.id.diff

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

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)

Event Timeline