Page MenuHomeFreeBSD

D51225.id158214.diff
No OneTemporary

D51225.id158214.diff

diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -117,6 +117,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,
@@ -496,7 +503,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_open(libusb_device * dev, libusb_device_handle ** devh);
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -185,6 +185,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
@@ -476,26 +476,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++) {
@@ -503,42 +494,139 @@
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)
+ return (LIBUSB_ERROR_NOT_FOUND);
+
+ ret = libusb_calculate_ep_size(dev, pdend);
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)
+ return (LIBUSB_ERROR_NOT_FOUND);
+ pinf = &pdconf->interface[interface_number];
+
+ if (pinf->num_altsetting <= alternate_setting)
+ return (LIBUSB_ERROR_NOT_FOUND);
+ pdinf = &pinf->altsetting[alternate_setting];
+
+ if (pdinf->bNumEndpoints <= endpoint)
+ return (LIBUSB_ERROR_NOT_FOUND);
+ pdend = &pdinf->endpoint[endpoint];
+
+ return libusb_calculate_ep_size(dev, pdend);
+}
+
libusb_device *
libusb_ref_device(libusb_device *dev)
{

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 2, 3:30 PM (18 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28414717
Default Alt Text
D51225.id158214.diff (6 KB)

Event Timeline