diff options
-rw-r--r-- | examples/xusb.c | 25 | ||||
-rw-r--r-- | libusb/core.c | 2 | ||||
-rw-r--r-- | libusb/descriptor.c | 228 | ||||
-rw-r--r-- | libusb/io.c | 4 | ||||
-rw-r--r-- | libusb/libusb.h | 5 | ||||
-rw-r--r-- | libusb/os/darwin_usb.c | 2 | ||||
-rw-r--r-- | libusb/os/emscripten_webusb.cpp | 7 | ||||
-rw-r--r-- | libusb/os/events_posix.c | 8 | ||||
-rw-r--r-- | libusb/os/linux_usbfs.c | 13 | ||||
-rw-r--r-- | libusb/os/sunos_usb.c | 2 | ||||
-rw-r--r-- | libusb/os/windows_winusb.c | 9 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
12 files changed, 175 insertions, 132 deletions
diff --git a/examples/xusb.c b/examples/xusb.c index 83e5525..1ee4639 100644 --- a/examples/xusb.c +++ b/examples/xusb.c @@ -770,11 +770,11 @@ static void print_sublink_speed_attribute(struct libusb_ssplus_sublink_attribute static const char exponent[] = " KMG"; printf(" id=%u speed=%u%cbs %s %s SuperSpeed%s", ss_attr->ssid, - ss_attr->mantisa, + ss_attr->mantissa, (exponent[ss_attr->exponent]), (ss_attr->type == LIBUSB_SSPLUS_ATTR_TYPE_ASYM)? "Asym" : "Sym", (ss_attr->direction == LIBUSB_SSPLUS_ATTR_DIR_TX)? "TX" : "RX", - (ss_attr->protocol == LIBUSB_SSPLUS_ATTR_PROT_SSPLUS)? "+": "" ); + (ss_attr->protocol == LIBUSB_SSPLUS_ATTR_PROT_SSPLUS)? "Plus": "" ); } static void print_device_cap(struct libusb_bos_dev_capability_descriptor *dev_cap) @@ -854,7 +854,6 @@ static int test_device(uint16_t vid, uint16_t pid) libusb_device_handle *handle; libusb_device *dev; uint8_t bus, port_path[8]; - struct libusb_bos_descriptor *bos_desc; struct libusb_config_descriptor *conf_desc; const struct libusb_endpoint_descriptor *endpoint; int i, j, k, r; @@ -908,14 +907,18 @@ static int test_device(uint16_t vid, uint16_t pid) string_index[1] = dev_desc.iProduct; string_index[2] = dev_desc.iSerialNumber; - printf("\nReading BOS descriptor: "); - if (libusb_get_bos_descriptor(handle, &bos_desc) == LIBUSB_SUCCESS) { - printf("%d caps\n", bos_desc->bNumDeviceCaps); - for (i = 0; i < bos_desc->bNumDeviceCaps; i++) - print_device_cap(bos_desc->dev_capability[i]); - libusb_free_bos_descriptor(bos_desc); - } else { - printf("no descriptor\n"); + if (dev_desc.bcdUSB >= 0x0201) { + struct libusb_bos_descriptor *bos_desc; + + printf("\nReading BOS descriptor: "); + if (libusb_get_bos_descriptor(handle, &bos_desc) == LIBUSB_SUCCESS) { + printf("%d caps\n", bos_desc->bNumDeviceCaps); + for (i = 0; i < bos_desc->bNumDeviceCaps; i++) + print_device_cap(bos_desc->dev_capability[i]); + libusb_free_bos_descriptor(bos_desc); + } else { + printf("no descriptor\n"); + } } printf("\nReading first configuration descriptor:\n"); diff --git a/libusb/core.c b/libusb/core.c index 010201c..7461737 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -954,7 +954,7 @@ int API_EXPORTED libusb_get_port_numbers(libusb_device *dev, if (port_numbers_len <= 0) return LIBUSB_ERROR_INVALID_PARAM; - // HCDs can be listed as devices with port #0 + /* HCDs can be listed as devices with port #0 */ while((dev) && (dev->port_number != 0)) { if (--i < 0) { usbi_warn(ctx, "port numbers array is too small"); diff --git a/libusb/descriptor.c b/libusb/descriptor.c index b72f558..9d90944 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -30,54 +30,18 @@ * for detected devices */ -#define READ_LE16(p) ((uint16_t) \ - (((uint16_t)((p)[1]) << 8) | \ - ((uint16_t)((p)[0])))) - -#define READ_LE32(p) ((uint32_t) \ - (((uint32_t)((p)[3]) << 24) | \ - ((uint32_t)((p)[2]) << 16) | \ - ((uint32_t)((p)[1]) << 8) | \ - ((uint32_t)((p)[0])))) - -static void parse_descriptor(const void *source, const char *descriptor, void *dest) +static inline uint16_t ReadLittleEndian16(const uint8_t p[2]) { - const uint8_t *sp = source; - uint8_t *dp = dest; - char field_type; - - while (*descriptor) { - field_type = *descriptor++; - switch (field_type) { - case 'b': /* 8-bit byte */ - *dp++ = *sp++; - break; - case 'w': /* 16-bit word, convert from little endian to CPU */ - dp += ((uintptr_t)dp & 1); /* Align to 16-bit word boundary */ - - *((uint16_t *)dp) = READ_LE16(sp); - sp += 2; - dp += 2; - break; - case 'd': /* 32-bit word, convert from little endian to CPU (4-byte align dst before write). */ - dp += 4 - ((uintptr_t)dp & 3); /* Align to 32-bit word boundary */ + return (uint16_t)p[1] << 8 | + (uint16_t)p[0]; +} - *((uint32_t *)dp) = READ_LE32(sp); - sp += 4; - dp += 4; - break; - case 'i': /* 32-bit word, convert from little endian to CPU (no dst alignment before write) */ - *((uint32_t *)dp) = READ_LE32(sp); - sp += 4; - dp += 4; - break; - case 'u': /* 16 byte UUID */ - memcpy(dp, sp, 16); - sp += 16; - dp += 16; - break; - } - } +static inline uint32_t ReadLittleEndian32(const uint8_t p[4]) +{ + return (uint32_t)p[3] << 24 | + (uint32_t)p[2] << 16 | + (uint32_t)p[1] << 8 | + (uint32_t)p[0]; } static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) @@ -92,7 +56,6 @@ static int parse_endpoint(struct libusb_context *ctx, const uint8_t *begin; void *extra; int parsed = 0; - int len; if (size < DESC_HEADER_LENGTH) { usbi_err(ctx, "short endpoint descriptor read %d/%d", @@ -114,10 +77,16 @@ static int parse_endpoint(struct libusb_context *ctx, return parsed; } - if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE) - parse_descriptor(buffer, "bbbbwbbb", endpoint); - else - parse_descriptor(buffer, "bbbbwb", endpoint); + endpoint->bLength = buffer[0]; + endpoint->bDescriptorType = buffer[1]; + endpoint->bEndpointAddress = buffer[2]; + endpoint->bmAttributes = buffer[3]; + endpoint->wMaxPacketSize = ReadLittleEndian16(&buffer[4]); + endpoint->bInterval = buffer[6]; + if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE) { + endpoint->bRefresh = buffer[7]; + endpoint->bSynchAddress = buffer[8]; + } buffer += header->bLength; size -= header->bLength; @@ -153,7 +122,7 @@ static int parse_endpoint(struct libusb_context *ctx, /* Copy any unknown descriptors into a storage area for drivers */ /* to later parse */ - len = (int)(buffer - begin); + ptrdiff_t len = buffer - begin; if (len <= 0) return parsed; @@ -163,7 +132,7 @@ static int parse_endpoint(struct libusb_context *ctx, memcpy(extra, begin, (size_t)len); endpoint->extra = extra; - endpoint->extra_length = len; + endpoint->extra_length = (int)len; return parsed; } @@ -196,7 +165,6 @@ static void clear_interface(struct libusb_interface *usb_interface) static int parse_interface(libusb_context *ctx, struct libusb_interface *usb_interface, const uint8_t *buffer, int size) { - int len; int r; int parsed = 0; int interface_number = -1; @@ -217,7 +185,15 @@ static int parse_interface(libusb_context *ctx, usb_interface->altsetting = altsetting; ifp = altsetting + usb_interface->num_altsetting; - parse_descriptor(buffer, "bbbbbbbbb", ifp); + ifp->bLength = buffer[0]; + ifp->bDescriptorType = buffer[1]; + ifp->bInterfaceNumber = buffer[2]; + ifp->bAlternateSetting = buffer[3]; + ifp->bNumEndpoints = buffer[4]; + ifp->bInterfaceClass = buffer[5]; + ifp->bInterfaceSubClass = buffer[6]; + ifp->bInterfaceProtocol = buffer[7]; + ifp->iInterface = buffer[8]; if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) { usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)", ifp->bDescriptorType, LIBUSB_DT_INTERFACE); @@ -282,7 +258,7 @@ static int parse_interface(libusb_context *ctx, /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ - len = (int)(buffer - begin); + ptrdiff_t len = buffer - begin; if (len > 0) { void *extra = malloc((size_t)len); @@ -293,7 +269,7 @@ static int parse_interface(libusb_context *ctx, memcpy(extra, begin, (size_t)len); ifp->extra = extra; - ifp->extra_length = len; + ifp->extra_length = (int)len; } if (ifp->bNumEndpoints > 0) { @@ -363,7 +339,14 @@ static int parse_configuration(struct libusb_context *ctx, return LIBUSB_ERROR_IO; } - parse_descriptor(buffer, "bbwbbbbb", config); + config->bLength = buffer[0]; + config->bDescriptorType = buffer[1]; + config->wTotalLength = ReadLittleEndian16(&buffer[2]); + config->bNumInterfaces = buffer[4]; + config->bConfigurationValue = buffer[5]; + config->iConfiguration = buffer[6]; + config->bmAttributes = buffer[7]; + config->MaxPower = buffer[8]; if (config->bDescriptorType != LIBUSB_DT_CONFIG) { usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)", config->bDescriptorType, LIBUSB_DT_CONFIG); @@ -390,7 +373,6 @@ static int parse_configuration(struct libusb_context *ctx, size -= config->bLength; for (i = 0; i < config->bNumInterfaces; i++) { - int len; const uint8_t *begin; /* Skip over the rest of the Class Specific or Vendor */ @@ -426,7 +408,7 @@ static int parse_configuration(struct libusb_context *ctx, /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ - len = (int)(buffer - begin); + ptrdiff_t len = buffer - begin; if (len > 0) { uint8_t *extra = realloc((void *)config->extra, (size_t)(config->extra_length + len)); @@ -438,10 +420,10 @@ static int parse_configuration(struct libusb_context *ctx, memcpy(extra + config->extra_length, begin, (size_t)len); config->extra = extra; - config->extra_length += len; + config->extra_length += (int)len; } - r = parse_interface(ctx, usb_interface + i, buffer, size); + r = parse_interface(ctx, usb_interface + i, buffer, (int)size); if (r < 0) goto err; if (r == 0) { @@ -712,14 +694,14 @@ int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor( const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp) { - struct usbi_descriptor_header *header; + const struct usbi_descriptor_header *header; const uint8_t *buffer = endpoint->extra; int size = endpoint->extra_length; *ep_comp = NULL; while (size >= DESC_HEADER_LENGTH) { - header = (struct usbi_descriptor_header *)buffer; + header = (const struct usbi_descriptor_header *)buffer; if (header->bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) { if (header->bLength < DESC_HEADER_LENGTH) { usbi_err(ctx, "invalid descriptor length %u", @@ -742,7 +724,11 @@ int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor( *ep_comp = malloc(sizeof(**ep_comp)); if (!*ep_comp) return LIBUSB_ERROR_NO_MEM; - parse_descriptor(buffer, "bbbbw", *ep_comp); + (*ep_comp)->bLength = buffer[0]; + (*ep_comp)->bDescriptorType = buffer[1]; + (*ep_comp)->bMaxBurst = buffer[2]; + (*ep_comp)->bmAttributes = buffer[3]; + (*ep_comp)->wBytesPerInterval = ReadLittleEndian16(&buffer[4]); return LIBUSB_SUCCESS; } return LIBUSB_ERROR_NOT_FOUND; @@ -795,7 +781,10 @@ static int parse_bos(struct libusb_context *ctx, if (!_bos) return LIBUSB_ERROR_NO_MEM; - parse_descriptor(buffer, "bbwb", _bos); + _bos->bLength = buffer[0]; + _bos->bDescriptorType = buffer[1]; + _bos->wTotalLength = ReadLittleEndian16(&buffer[2]); + _bos->bNumDeviceCaps = buffer[4]; buffer += _bos->bLength; size -= _bos->bLength; @@ -945,7 +934,10 @@ int API_EXPORTED libusb_get_usb_2_0_extension_descriptor( if (!_usb_2_0_extension) return LIBUSB_ERROR_NO_MEM; - parse_descriptor(dev_cap, "bbbd", _usb_2_0_extension); + _usb_2_0_extension->bLength = dev_cap->bLength; + _usb_2_0_extension->bDescriptorType = dev_cap->bDescriptorType; + _usb_2_0_extension->bDevCapabilityType = dev_cap->bDevCapabilityType; + _usb_2_0_extension->bmAttributes = ReadLittleEndian32(dev_cap->dev_capability_data); *usb_2_0_extension = _usb_2_0_extension; return LIBUSB_SUCCESS; @@ -1000,15 +992,22 @@ int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor( if (!_ss_usb_device_cap) return LIBUSB_ERROR_NO_MEM; - parse_descriptor(dev_cap, "bbbbwbbw", _ss_usb_device_cap); + _ss_usb_device_cap->bLength = dev_cap->bLength; + _ss_usb_device_cap->bDescriptorType = dev_cap->bDescriptorType; + _ss_usb_device_cap->bDevCapabilityType = dev_cap->bDevCapabilityType; + _ss_usb_device_cap->bmAttributes = dev_cap->dev_capability_data[0]; + _ss_usb_device_cap->wSpeedSupported = ReadLittleEndian16(&dev_cap->dev_capability_data[1]); + _ss_usb_device_cap->bFunctionalitySupport = dev_cap->dev_capability_data[3]; + _ss_usb_device_cap->bU1DevExitLat = dev_cap->dev_capability_data[4]; + _ss_usb_device_cap->bU2DevExitLat = ReadLittleEndian16(&dev_cap->dev_capability_data[5]); *ss_usb_device_cap = _ss_usb_device_cap; return LIBUSB_SUCCESS; } -// We use this private struct ony to parse a superspeed+ device capability -// descriptor according to section 9.6.2.5 of the USB 3.1 specification. -// We don't expose it. +/* We use this private struct only to parse a SuperSpeedPlus device capability + descriptor according to section 9.6.2.5 of the USB 3.1 specification. + We don't expose it. */ struct internal_ssplus_capability_descriptor { uint8_t bLength; uint8_t bDescriptorType; @@ -1026,10 +1025,10 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor( { struct libusb_ssplus_usb_device_capability_descriptor *_ssplus_cap; - // Use a private struct to re-use our descriptor parsing system. + /* Use a private struct to reuse our descriptor parsing system. */ struct internal_ssplus_capability_descriptor parsedDescriptor; - // Some size/type checks to make sure everything is in order + /* Some size/type checks to make sure everything is in order */ if (dev_cap->bDevCapabilityType != LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY) { usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)", dev_cap->bDevCapabilityType, @@ -1041,36 +1040,41 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor( return LIBUSB_ERROR_IO; } - // We can only parse the non-variable size part of the SuperSpeedPlus descriptor. The attributes - // have to be read "manually". - parse_descriptor(dev_cap, "bbbbiww", &parsedDescriptor); + const uint8_t* dev_capability_data = dev_cap->dev_capability_data; + parsedDescriptor.bLength = dev_cap->bLength; + parsedDescriptor.bDescriptorType = dev_cap->bDescriptorType; + parsedDescriptor.bDevCapabilityType = dev_cap->bDevCapabilityType; + parsedDescriptor.bReserved = dev_capability_data[0]; + parsedDescriptor.bmAttributes = ReadLittleEndian32(&dev_capability_data[1]); + parsedDescriptor.wFunctionalitySupport = ReadLittleEndian16(&dev_capability_data[5]); + parsedDescriptor.wReserved = ReadLittleEndian16(&dev_capability_data[7]); uint8_t numSublikSpeedAttributes = (parsedDescriptor.bmAttributes & 0xF) + 1; _ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute)); if (!_ssplus_cap) return LIBUSB_ERROR_NO_MEM; - // Parse bmAttributes + /* Parse bmAttributes */ _ssplus_cap->numSublinkSpeedAttributes = numSublikSpeedAttributes; _ssplus_cap->numSublinkSpeedIDs = ((parsedDescriptor.bmAttributes & 0xF0) >> 4) + 1; - // Parse wFunctionalitySupport + /* Parse wFunctionalitySupport */ _ssplus_cap->ssid = parsedDescriptor.wFunctionalitySupport & 0xF; _ssplus_cap->minRxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0x0F00) >> 8; _ssplus_cap->minTxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0xF000) >> 12; - // Check that we have enough to read all the sublink attributes + /* Check that we have enough to read all the sublink attributes */ if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + _ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t)) { usbi_err(ctx, "short ssplus capability descriptor, unable to read sublinks: Not enough data"); return LIBUSB_ERROR_IO; } - // Read the attributes + /* Read the attributes */ uint8_t* base = ((uint8_t*)dev_cap) + LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE; for(uint8_t i = 0 ; i < _ssplus_cap->numSublinkSpeedAttributes ; i++) { - uint32_t attr = READ_LE32(base + i * sizeof(uint32_t)); + uint32_t attr = ReadLittleEndian32(base + i * sizeof(uint32_t)); _ssplus_cap->sublinkSpeedAttributes[i].ssid = attr & 0x0f; - _ssplus_cap->sublinkSpeedAttributes[i].mantisa = attr >> 16; + _ssplus_cap->sublinkSpeedAttributes[i].mantissa = attr >> 16; _ssplus_cap->sublinkSpeedAttributes[i].exponent = (attr >> 4) & 0x3 ; _ssplus_cap->sublinkSpeedAttributes[i].type = attr & 0x40 ? LIBUSB_SSPLUS_ATTR_TYPE_ASYM : LIBUSB_SSPLUS_ATTR_TYPE_SYM; _ssplus_cap->sublinkSpeedAttributes[i].direction = attr & 0x80 ? LIBUSB_SSPLUS_ATTR_DIR_TX : LIBUSB_SSPLUS_ATTR_DIR_RX; @@ -1138,7 +1142,11 @@ int API_EXPORTED libusb_get_container_id_descriptor(libusb_context *ctx, if (!_container_id) return LIBUSB_ERROR_NO_MEM; - parse_descriptor(dev_cap, "bbbbu", _container_id); + _container_id->bLength = dev_cap->bLength; + _container_id->bDescriptorType = dev_cap->bDescriptorType; + _container_id->bDevCapabilityType = dev_cap->bDevCapabilityType; + _container_id->bReserved = dev_cap->dev_capability_data[0]; + memcpy(_container_id->ContainerID, &dev_cap->dev_capability_data[1], 16); *container_id = _container_id; return LIBUSB_SUCCESS; @@ -1194,13 +1202,17 @@ int API_EXPORTED libusb_get_platform_descriptor(libusb_context *ctx, if (!_platform_descriptor) return LIBUSB_ERROR_NO_MEM; - parse_descriptor(dev_cap, "bbbbu", _platform_descriptor); + _platform_descriptor->bLength = dev_cap->bLength; + _platform_descriptor->bDescriptorType = dev_cap->bDescriptorType; + _platform_descriptor->bDevCapabilityType = dev_cap->bDevCapabilityType; + _platform_descriptor->bReserved = dev_cap->dev_capability_data[0]; + memcpy(_platform_descriptor->PlatformCapabilityUUID, &(dev_cap->dev_capability_data[1]), 16); - /* Capability data is located after reserved byte and 128-bit UUID */ + /* Capability data is located after reserved byte and 16 byte UUID */ uint8_t* capability_data = dev_cap->dev_capability_data + 1 + 16; /* Capability data length is total descriptor length minus initial fields */ - size_t capability_data_length = _platform_descriptor->bLength - (16 + 4); + size_t capability_data_length = dev_cap->bLength - (3 + 1 + 16); memcpy(_platform_descriptor->CapabilityData, capability_data, capability_data_length); @@ -1312,15 +1324,21 @@ static int parse_iad_array(struct libusb_context *ctx, return LIBUSB_ERROR_IO; } - // First pass: Iterate through desc list, count number of IADs + /* First pass: Iterate through desc list, count number of IADs */ iad_array->length = 0; while (consumed < size) { - parse_descriptor(buf, "bb", &header); - if (header.bLength < 2) { + header.bLength = buf[0]; + header.bDescriptorType = buf[1]; + if (header.bLength < DESC_HEADER_LENGTH) { usbi_err(ctx, "invalid descriptor bLength %d", header.bLength); return LIBUSB_ERROR_IO; } + else if (header.bLength > size) { + usbi_warn(ctx, "short config descriptor read %d/%u", + size, header.bLength); + return LIBUSB_ERROR_IO; + } if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION) iad_array->length++; buf += header.bLength; @@ -1335,16 +1353,30 @@ static int parse_iad_array(struct libusb_context *ctx, iad_array->iad = iad; - // Second pass: Iterate through desc list, fill IAD structures - consumed = 0; + /* Second pass: Iterate through desc list, fill IAD structures */ + int remaining = size; i = 0; - while (consumed < size) { - parse_descriptor(buffer, "bb", &header); - if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION) - parse_descriptor(buffer, "bbbbbbbb", &iad[i++]); - buffer += header.bLength; - consumed += header.bLength; - } + do { + header.bLength = buffer[0]; + header.bDescriptorType = buffer[1]; + if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION && (remaining >= LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE)) { + iad[i].bLength = buffer[0]; + iad[i].bDescriptorType = buffer[1]; + iad[i].bFirstInterface = buffer[2]; + iad[i].bInterfaceCount = buffer[3]; + iad[i].bFunctionClass = buffer[4]; + iad[i].bFunctionSubClass = buffer[5]; + iad[i].bFunctionProtocol = buffer[6]; + iad[i].iFunction = buffer[7]; + i++; + } + + remaining -= header.bLength; + if (remaining < DESC_HEADER_LENGTH) { + break; + } + buffer += header.bLength; + } while (1); } return LIBUSB_SUCCESS; diff --git a/libusb/io.c b/libusb/io.c index 0b2aaf6..fa26ffa 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -2045,7 +2045,7 @@ int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) return 0; } -// NB: flying_transfers_lock must be held when calling this +/* NB: flying_transfers_lock must be held when calling this */ static void handle_timeout(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = @@ -2061,7 +2061,7 @@ static void handle_timeout(struct usbi_transfer *itransfer) "async cancel failed %d", r); } -// NB: flying_transfers_lock must be held when calling this +/* NB: flying_transfers_lock must be held when calling this */ static void handle_timeouts_locked(struct libusb_context *ctx) { struct timespec systime; diff --git a/libusb/libusb.h b/libusb/libusb.h index 2353f4c..a407838 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -335,6 +335,7 @@ enum libusb_descriptor_type { #define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6 #define LIBUSB_DT_BOS_SIZE 5 #define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3 +#define LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE 8 /* BOS descriptor sizes */ #define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 @@ -565,7 +566,7 @@ enum libusb_bos_type { /** Platform descriptor */ LIBUSB_BT_PLATFORM_DESCRIPTOR = 0x05, - /* SuperSpeed+ device capability */ + /* SuperSpeedPlus device capability */ LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY = 0x0A, }; @@ -1051,7 +1052,7 @@ struct libusb_ssplus_sublink_attribute { /** This field defines the mantissa that shall be applied to the exponent when calculating the maximum bit rate. */ - uint16_t mantisa; + uint16_t mantissa; }; /** \ingroup libusb_desc diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index ae09db7..7bb496b 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -1092,7 +1092,7 @@ static IOReturn darwin_request_descriptor (usb_device_t device, UInt8 desc, UInt static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) { usb_device_t device = dev->device; int retries = 1; - long delay = 30000; // microseconds + long delay = 30000; /* microseconds */ int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1; int is_open = 0; IOReturn ret = 0, ret2; diff --git a/libusb/os/emscripten_webusb.cpp b/libusb/os/emscripten_webusb.cpp index ced9ad8..0d7fec9 100644 --- a/libusb/os/emscripten_webusb.cpp +++ b/libusb/os/emscripten_webusb.cpp @@ -586,12 +586,17 @@ unsigned long getDeviceSessionId(val& web_usb_device) { } val getDeviceList(libusb_context* ctx, discovered_devs** devs) { + // Check if browser supports USB + val navigator_usb = val::global("navigator")["usb"]; + if (navigator_usb == val::undefined()) { + co_return (int) LIBUSB_ERROR_NOT_SUPPORTED; + } // C++ equivalent of `await navigator.usb.getDevices()`. Note: at this point // we must already have some devices exposed - caller must have called // `await navigator.usb.requestDevice(...)` in response to user interaction // before going to LibUSB. Otherwise this list will be empty. auto web_usb_devices = - co_await_try(val::global("navigator")["usb"].call<val>("getDevices")); + co_await_try(navigator_usb.call<val>("getDevices")); for (auto&& web_usb_device : web_usb_devices) { auto session_id = getDeviceSessionId(web_usb_device); diff --git a/libusb/os/events_posix.c b/libusb/os/events_posix.c index 4056dae..bf984b9 100644 --- a/libusb/os/events_posix.c +++ b/libusb/os/events_posix.c @@ -256,11 +256,11 @@ int usbi_wait_for_events(struct libusb_context *ctx, usbi_dbg(ctx, "poll() %u fds with timeout in %dms", (unsigned int)nfds, timeout_ms); #ifdef __EMSCRIPTEN__ - // Emscripten's poll doesn't actually block, so we need to use an out-of-band - // waiting signal. + /* Emscripten's poll doesn't actually block, so we need to use an + * out-of-band waiting signal. */ em_libusb_wait(&ctx->event.has_event, 0, timeout_ms); - // Emscripten ignores timeout_ms, but set it to 0 for future-proofing in case - // they ever implement real poll. + /* Emscripten ignores timeout_ms, but set it to 0 for future-proofing + * in case they ever implement real poll. */ timeout_ms = 0; #endif num_ready = poll(fds, nfds, timeout_ms); diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 25ee02e..8c7b3a9 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -182,7 +182,7 @@ static int dev_has_config0(struct libusb_device *dev) return 0; } -static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) +static int get_usbfs_fd(struct libusb_device *dev, int access_mode, int silent) { struct libusb_context *ctx = DEVICE_CTX(dev); char path[24]; @@ -195,7 +195,7 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) snprintf(path, sizeof(path), USB_DEVTMPFS_PATH "/%03u/%03u", dev->bus_number, dev->device_address); - fd = open(path, mode | O_CLOEXEC); + fd = open(path, access_mode | O_CLOEXEC); if (fd != -1) return fd; /* Success */ @@ -209,14 +209,14 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) /* Wait 10ms for USB device path creation.*/ nanosleep(&delay_ts, NULL); - fd = open(path, mode | O_CLOEXEC); + fd = open(path, access_mode | O_CLOEXEC); if (fd != -1) return fd; /* Success */ } if (!silent) { usbi_err(ctx, "libusb couldn't open USB device %s, errno=%d", path, errno); - if (errno == EACCES && mode == O_RDWR) + if (errno == EACCES && access_mode == O_RDWR) usbi_err(ctx, "libusb requires write access to USB device nodes"); } @@ -1628,8 +1628,9 @@ out: return ret; } -static int do_streams_ioctl(struct libusb_device_handle *handle, long req, - uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +static int do_streams_ioctl(struct libusb_device_handle *handle, + unsigned long req, uint32_t num_streams, unsigned char *endpoints, + int num_endpoints) { struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle); int r, fd = hpriv->fd; diff --git a/libusb/os/sunos_usb.c b/libusb/os/sunos_usb.c index d7be7de..761ca37 100644 --- a/libusb/os/sunos_usb.c +++ b/libusb/os/sunos_usb.c @@ -171,7 +171,7 @@ sunos_usb_ioctl(struct libusb_device *dev, int cmd) nvlist_alloc(&nvlist, NV_UNIQUE_NAME_TYPE, KM_NOSLEEP); nvlist_add_int32(nvlist, "port", dev->port_number); - //find the hub path + /* find the hub path */ snprintf(path_arg, sizeof(path_arg), "/devices%s:hubd", hubpath); usbi_dbg(DEVICE_CTX(dev), "ioctl hub path: %s", path_arg); diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index 926b9e8..a30f3de 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -1492,7 +1492,7 @@ static int get_guid(struct libusb_context *ctx, char *dev_id, HDEVINFO *dev_info // The GUID was read successfully break; } else if (s == ERROR_FILE_NOT_FOUND) { - usbi_info(ctx, "no DeviceInterfaceGUID registered for '%s'", dev_id); + usbi_dbg(ctx, "no DeviceInterfaceGUID registered for '%s'", dev_id); err = LIBUSB_ERROR_ACCESS; goto exit; } else if (s == ERROR_MORE_DATA) { @@ -1572,7 +1572,6 @@ static int get_guid(struct libusb_context *ctx, char *dev_id, HDEVINFO *dev_info usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string '%s', skipping", dev_id, guid); free(*if_guid); *if_guid = NULL; - err = LIBUSB_ERROR_NO_MEM; goto exit; } @@ -1767,7 +1766,7 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_ } // ...and to add the additional device interface GUIDs r = get_guid(ctx, dev_id, dev_info, &dev_info_data, 0, &if_guid); - if (r == LIBUSB_SUCCESS) { + if (r == LIBUSB_SUCCESS && if_guid != NULL) { // Check if we've already seen this GUID for (j = EXT_PASS; j < nb_guids; j++) { if (memcmp(guid_list[j], if_guid, sizeof(*if_guid)) == 0) @@ -1796,7 +1795,9 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_ } else if (r == LIBUSB_ERROR_NO_MEM) { LOOP_BREAK(LIBUSB_ERROR_NO_MEM); } else { - usbi_warn(ctx, "unexpected error during getting DeviceInterfaceGUID for '%s'", dev_id); + if (r != LIBUSB_SUCCESS) { + usbi_warn(ctx, "unexpected error during getting DeviceInterfaceGUID for '%s'", dev_id); + } } break; case HID_PASS: diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 8b5911c..8cad994 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11898 +#define LIBUSB_NANO 11913 |