usb 2.16.0 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/usb/endpoint.js +1 -1
- package/dist/usb/endpoint.js.map +1 -1
- package/dist/webusb/index.d.ts +1 -1
- package/dist/webusb/index.js +1 -1
- package/dist/webusb/index.js.map +1 -1
- package/dist/webusb/webusb-device.d.ts +4 -4
- package/dist/webusb/webusb-device.js +5 -2
- package/dist/webusb/webusb-device.js.map +1 -1
- package/libusb/.clang-tidy +34 -0
- package/libusb/AUTHORS +7 -0
- package/libusb/ChangeLog +14 -0
- package/libusb/KEYS +123 -0
- package/libusb/README +0 -4
- package/libusb/Xcode/common.xcconfig +20 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +12 -12
- package/libusb/android/examples/unrooted_android.c +1 -0
- package/libusb/configure.ac +2 -2
- package/libusb/examples/dpfp.c +1 -1
- package/libusb/examples/ezusb.c +6 -1
- package/libusb/examples/fxload.c +7 -5
- package/libusb/examples/testlibusb.c +1 -0
- package/libusb/examples/xusb.c +136 -76
- package/libusb/libusb/core.c +8 -10
- package/libusb/libusb/descriptor.c +253 -94
- package/libusb/libusb/hotplug.c +27 -8
- package/libusb/libusb/io.c +3 -2
- package/libusb/libusb/libusb-1.0.def +4 -0
- package/libusb/libusb/libusb.h +121 -11
- package/libusb/libusb/libusbi.h +12 -0
- package/libusb/libusb/os/darwin_usb.c +93 -47
- package/libusb/libusb/os/emscripten_webusb.cpp +7 -2
- package/libusb/libusb/os/events_posix.c +4 -4
- package/libusb/libusb/os/linux_usbfs.c +20 -9
- package/libusb/libusb/os/linux_usbfs.h +13 -3
- package/libusb/libusb/os/netbsd_usb.c +4 -4
- package/libusb/libusb/os/openbsd_usb.c +2 -2
- package/libusb/libusb/os/sunos_usb.c +5 -5
- package/libusb/libusb/os/threads_posix.c +17 -16
- package/libusb/libusb/os/threads_posix.h +1 -1
- package/libusb/libusb/os/threads_windows.h +2 -2
- package/libusb/libusb/os/windows_winusb.c +35 -15
- package/libusb/libusb/sync.c +8 -5
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/tests/macos.c +2 -2
- package/libusb/tests/stress_mt.c +4 -2
- package/package.json +3 -3
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-arm64/node.napi.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/test/webusb.coffee +2 -2
|
@@ -30,49 +30,18 @@
|
|
|
30
30
|
* for detected devices
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
(((uint16_t)((p)[1]) << 8) | \
|
|
35
|
-
((uint16_t)((p)[0]))))
|
|
36
|
-
|
|
37
|
-
#define READ_LE32(p) ((uint32_t) \
|
|
38
|
-
(((uint32_t)((p)[3]) << 24) | \
|
|
39
|
-
((uint32_t)((p)[2]) << 16) | \
|
|
40
|
-
((uint32_t)((p)[1]) << 8) | \
|
|
41
|
-
((uint32_t)((p)[0]))))
|
|
42
|
-
|
|
43
|
-
static void parse_descriptor(const void *source, const char *descriptor, void *dest)
|
|
33
|
+
static inline uint16_t ReadLittleEndian16(const uint8_t p[2])
|
|
44
34
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
while (*descriptor) {
|
|
50
|
-
field_type = *descriptor++;
|
|
51
|
-
switch (field_type) {
|
|
52
|
-
case 'b': /* 8-bit byte */
|
|
53
|
-
*dp++ = *sp++;
|
|
54
|
-
break;
|
|
55
|
-
case 'w': /* 16-bit word, convert from little endian to CPU */
|
|
56
|
-
dp += ((uintptr_t)dp & 1); /* Align to 16-bit word boundary */
|
|
57
|
-
|
|
58
|
-
*((uint16_t *)dp) = READ_LE16(sp);
|
|
59
|
-
sp += 2;
|
|
60
|
-
dp += 2;
|
|
61
|
-
break;
|
|
62
|
-
case 'd': /* 32-bit word, convert from little endian to CPU */
|
|
63
|
-
dp += 4 - ((uintptr_t)dp & 3); /* Align to 32-bit word boundary */
|
|
35
|
+
return (uint16_t)((uint16_t)p[1] << 8 |
|
|
36
|
+
(uint16_t)p[0]);
|
|
37
|
+
}
|
|
64
38
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
sp += 16;
|
|
72
|
-
dp += 16;
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
39
|
+
static inline uint32_t ReadLittleEndian32(const uint8_t p[4])
|
|
40
|
+
{
|
|
41
|
+
return (uint32_t)((uint32_t)p[3] << 24 |
|
|
42
|
+
(uint32_t)p[2] << 16 |
|
|
43
|
+
(uint32_t)p[1] << 8 |
|
|
44
|
+
(uint32_t)p[0]);
|
|
76
45
|
}
|
|
77
46
|
|
|
78
47
|
static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
|
|
@@ -87,7 +56,6 @@ static int parse_endpoint(struct libusb_context *ctx,
|
|
|
87
56
|
const uint8_t *begin;
|
|
88
57
|
void *extra;
|
|
89
58
|
int parsed = 0;
|
|
90
|
-
int len;
|
|
91
59
|
|
|
92
60
|
if (size < DESC_HEADER_LENGTH) {
|
|
93
61
|
usbi_err(ctx, "short endpoint descriptor read %d/%d",
|
|
@@ -109,10 +77,16 @@ static int parse_endpoint(struct libusb_context *ctx,
|
|
|
109
77
|
return parsed;
|
|
110
78
|
}
|
|
111
79
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
80
|
+
endpoint->bLength = buffer[0];
|
|
81
|
+
endpoint->bDescriptorType = buffer[1];
|
|
82
|
+
endpoint->bEndpointAddress = buffer[2];
|
|
83
|
+
endpoint->bmAttributes = buffer[3];
|
|
84
|
+
endpoint->wMaxPacketSize = ReadLittleEndian16(&buffer[4]);
|
|
85
|
+
endpoint->bInterval = buffer[6];
|
|
86
|
+
if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE) {
|
|
87
|
+
endpoint->bRefresh = buffer[7];
|
|
88
|
+
endpoint->bSynchAddress = buffer[8];
|
|
89
|
+
}
|
|
116
90
|
|
|
117
91
|
buffer += header->bLength;
|
|
118
92
|
size -= header->bLength;
|
|
@@ -148,7 +122,7 @@ static int parse_endpoint(struct libusb_context *ctx,
|
|
|
148
122
|
|
|
149
123
|
/* Copy any unknown descriptors into a storage area for drivers */
|
|
150
124
|
/* to later parse */
|
|
151
|
-
len =
|
|
125
|
+
ptrdiff_t len = buffer - begin;
|
|
152
126
|
if (len <= 0)
|
|
153
127
|
return parsed;
|
|
154
128
|
|
|
@@ -156,9 +130,9 @@ static int parse_endpoint(struct libusb_context *ctx,
|
|
|
156
130
|
if (!extra)
|
|
157
131
|
return LIBUSB_ERROR_NO_MEM;
|
|
158
132
|
|
|
159
|
-
memcpy(extra, begin, len);
|
|
133
|
+
memcpy(extra, begin, (size_t)len);
|
|
160
134
|
endpoint->extra = extra;
|
|
161
|
-
endpoint->extra_length = len;
|
|
135
|
+
endpoint->extra_length = (int)len;
|
|
162
136
|
|
|
163
137
|
return parsed;
|
|
164
138
|
}
|
|
@@ -191,7 +165,6 @@ static void clear_interface(struct libusb_interface *usb_interface)
|
|
|
191
165
|
static int parse_interface(libusb_context *ctx,
|
|
192
166
|
struct libusb_interface *usb_interface, const uint8_t *buffer, int size)
|
|
193
167
|
{
|
|
194
|
-
int len;
|
|
195
168
|
int r;
|
|
196
169
|
int parsed = 0;
|
|
197
170
|
int interface_number = -1;
|
|
@@ -212,7 +185,15 @@ static int parse_interface(libusb_context *ctx,
|
|
|
212
185
|
usb_interface->altsetting = altsetting;
|
|
213
186
|
|
|
214
187
|
ifp = altsetting + usb_interface->num_altsetting;
|
|
215
|
-
|
|
188
|
+
ifp->bLength = buffer[0];
|
|
189
|
+
ifp->bDescriptorType = buffer[1];
|
|
190
|
+
ifp->bInterfaceNumber = buffer[2];
|
|
191
|
+
ifp->bAlternateSetting = buffer[3];
|
|
192
|
+
ifp->bNumEndpoints = buffer[4];
|
|
193
|
+
ifp->bInterfaceClass = buffer[5];
|
|
194
|
+
ifp->bInterfaceSubClass = buffer[6];
|
|
195
|
+
ifp->bInterfaceProtocol = buffer[7];
|
|
196
|
+
ifp->iInterface = buffer[8];
|
|
216
197
|
if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
|
|
217
198
|
usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
|
|
218
199
|
ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
|
|
@@ -277,7 +258,7 @@ static int parse_interface(libusb_context *ctx,
|
|
|
277
258
|
|
|
278
259
|
/* Copy any unknown descriptors into a storage area for */
|
|
279
260
|
/* drivers to later parse */
|
|
280
|
-
len =
|
|
261
|
+
ptrdiff_t len = buffer - begin;
|
|
281
262
|
if (len > 0) {
|
|
282
263
|
void *extra = malloc((size_t)len);
|
|
283
264
|
|
|
@@ -286,9 +267,9 @@ static int parse_interface(libusb_context *ctx,
|
|
|
286
267
|
goto err;
|
|
287
268
|
}
|
|
288
269
|
|
|
289
|
-
memcpy(extra, begin, len);
|
|
270
|
+
memcpy(extra, begin, (size_t)len);
|
|
290
271
|
ifp->extra = extra;
|
|
291
|
-
ifp->extra_length = len;
|
|
272
|
+
ifp->extra_length = (int)len;
|
|
292
273
|
}
|
|
293
274
|
|
|
294
275
|
if (ifp->bNumEndpoints > 0) {
|
|
@@ -358,7 +339,14 @@ static int parse_configuration(struct libusb_context *ctx,
|
|
|
358
339
|
return LIBUSB_ERROR_IO;
|
|
359
340
|
}
|
|
360
341
|
|
|
361
|
-
|
|
342
|
+
config->bLength = buffer[0];
|
|
343
|
+
config->bDescriptorType = buffer[1];
|
|
344
|
+
config->wTotalLength = ReadLittleEndian16(&buffer[2]);
|
|
345
|
+
config->bNumInterfaces = buffer[4];
|
|
346
|
+
config->bConfigurationValue = buffer[5];
|
|
347
|
+
config->iConfiguration = buffer[6];
|
|
348
|
+
config->bmAttributes = buffer[7];
|
|
349
|
+
config->MaxPower = buffer[8];
|
|
362
350
|
if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
|
|
363
351
|
usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
|
|
364
352
|
config->bDescriptorType, LIBUSB_DT_CONFIG);
|
|
@@ -385,7 +373,6 @@ static int parse_configuration(struct libusb_context *ctx,
|
|
|
385
373
|
size -= config->bLength;
|
|
386
374
|
|
|
387
375
|
for (i = 0; i < config->bNumInterfaces; i++) {
|
|
388
|
-
int len;
|
|
389
376
|
const uint8_t *begin;
|
|
390
377
|
|
|
391
378
|
/* Skip over the rest of the Class Specific or Vendor */
|
|
@@ -421,22 +408,22 @@ static int parse_configuration(struct libusb_context *ctx,
|
|
|
421
408
|
|
|
422
409
|
/* Copy any unknown descriptors into a storage area for */
|
|
423
410
|
/* drivers to later parse */
|
|
424
|
-
len =
|
|
411
|
+
ptrdiff_t len = buffer - begin;
|
|
425
412
|
if (len > 0) {
|
|
426
413
|
uint8_t *extra = realloc((void *)config->extra,
|
|
427
|
-
(size_t)(config->extra_length + len)
|
|
414
|
+
(size_t)(config->extra_length) + (size_t)len);
|
|
428
415
|
|
|
429
416
|
if (!extra) {
|
|
430
417
|
r = LIBUSB_ERROR_NO_MEM;
|
|
431
418
|
goto err;
|
|
432
419
|
}
|
|
433
420
|
|
|
434
|
-
memcpy(extra + config->extra_length, begin, len);
|
|
421
|
+
memcpy(extra + config->extra_length, begin, (size_t)len);
|
|
435
422
|
config->extra = extra;
|
|
436
|
-
config->extra_length += len;
|
|
423
|
+
config->extra_length += (int)len;
|
|
437
424
|
}
|
|
438
425
|
|
|
439
|
-
r = parse_interface(ctx, usb_interface + i, buffer, size);
|
|
426
|
+
r = parse_interface(ctx, usb_interface + i, buffer, (int)size);
|
|
440
427
|
if (r < 0)
|
|
441
428
|
goto err;
|
|
442
429
|
if (r == 0) {
|
|
@@ -707,14 +694,14 @@ int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
|
|
|
707
694
|
const struct libusb_endpoint_descriptor *endpoint,
|
|
708
695
|
struct libusb_ss_endpoint_companion_descriptor **ep_comp)
|
|
709
696
|
{
|
|
710
|
-
struct usbi_descriptor_header *header;
|
|
697
|
+
const struct usbi_descriptor_header *header;
|
|
711
698
|
const uint8_t *buffer = endpoint->extra;
|
|
712
699
|
int size = endpoint->extra_length;
|
|
713
700
|
|
|
714
701
|
*ep_comp = NULL;
|
|
715
702
|
|
|
716
703
|
while (size >= DESC_HEADER_LENGTH) {
|
|
717
|
-
header = (struct usbi_descriptor_header *)buffer;
|
|
704
|
+
header = (const struct usbi_descriptor_header *)buffer;
|
|
718
705
|
if (header->bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
|
|
719
706
|
if (header->bLength < DESC_HEADER_LENGTH) {
|
|
720
707
|
usbi_err(ctx, "invalid descriptor length %u",
|
|
@@ -737,7 +724,11 @@ int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
|
|
|
737
724
|
*ep_comp = malloc(sizeof(**ep_comp));
|
|
738
725
|
if (!*ep_comp)
|
|
739
726
|
return LIBUSB_ERROR_NO_MEM;
|
|
740
|
-
|
|
727
|
+
(*ep_comp)->bLength = buffer[0];
|
|
728
|
+
(*ep_comp)->bDescriptorType = buffer[1];
|
|
729
|
+
(*ep_comp)->bMaxBurst = buffer[2];
|
|
730
|
+
(*ep_comp)->bmAttributes = buffer[3];
|
|
731
|
+
(*ep_comp)->wBytesPerInterval = ReadLittleEndian16(&buffer[4]);
|
|
741
732
|
return LIBUSB_SUCCESS;
|
|
742
733
|
}
|
|
743
734
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
@@ -790,7 +781,10 @@ static int parse_bos(struct libusb_context *ctx,
|
|
|
790
781
|
if (!_bos)
|
|
791
782
|
return LIBUSB_ERROR_NO_MEM;
|
|
792
783
|
|
|
793
|
-
|
|
784
|
+
_bos->bLength = buffer[0];
|
|
785
|
+
_bos->bDescriptorType = buffer[1];
|
|
786
|
+
_bos->wTotalLength = ReadLittleEndian16(&buffer[2]);
|
|
787
|
+
_bos->bNumDeviceCaps = buffer[4];
|
|
794
788
|
buffer += _bos->bLength;
|
|
795
789
|
size -= _bos->bLength;
|
|
796
790
|
|
|
@@ -910,7 +904,7 @@ void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
|
|
|
910
904
|
*
|
|
911
905
|
* \param ctx the context to operate on, or NULL for the default context
|
|
912
906
|
* \param dev_cap Device Capability descriptor with a bDevCapabilityType of
|
|
913
|
-
* \ref
|
|
907
|
+
* \ref libusb_bos_type::LIBUSB_BT_USB_2_0_EXTENSION
|
|
914
908
|
* LIBUSB_BT_USB_2_0_EXTENSION
|
|
915
909
|
* \param usb_2_0_extension output location for the USB 2.0 Extension
|
|
916
910
|
* descriptor. Only valid if 0 was returned. Must be freed with
|
|
@@ -940,7 +934,10 @@ int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
|
|
|
940
934
|
if (!_usb_2_0_extension)
|
|
941
935
|
return LIBUSB_ERROR_NO_MEM;
|
|
942
936
|
|
|
943
|
-
|
|
937
|
+
_usb_2_0_extension->bLength = dev_cap->bLength;
|
|
938
|
+
_usb_2_0_extension->bDescriptorType = dev_cap->bDescriptorType;
|
|
939
|
+
_usb_2_0_extension->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
|
940
|
+
_usb_2_0_extension->bmAttributes = ReadLittleEndian32(dev_cap->dev_capability_data);
|
|
944
941
|
|
|
945
942
|
*usb_2_0_extension = _usb_2_0_extension;
|
|
946
943
|
return LIBUSB_SUCCESS;
|
|
@@ -965,7 +962,7 @@ void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
|
|
|
965
962
|
*
|
|
966
963
|
* \param ctx the context to operate on, or NULL for the default context
|
|
967
964
|
* \param dev_cap Device Capability descriptor with a bDevCapabilityType of
|
|
968
|
-
* \ref
|
|
965
|
+
* \ref libusb_bos_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
|
|
969
966
|
* LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
|
|
970
967
|
* \param ss_usb_device_cap output location for the SuperSpeed USB Device
|
|
971
968
|
* Capability descriptor. Only valid if 0 was returned. Must be freed with
|
|
@@ -995,12 +992,150 @@ int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
|
|
|
995
992
|
if (!_ss_usb_device_cap)
|
|
996
993
|
return LIBUSB_ERROR_NO_MEM;
|
|
997
994
|
|
|
998
|
-
|
|
995
|
+
_ss_usb_device_cap->bLength = dev_cap->bLength;
|
|
996
|
+
_ss_usb_device_cap->bDescriptorType = dev_cap->bDescriptorType;
|
|
997
|
+
_ss_usb_device_cap->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
|
998
|
+
_ss_usb_device_cap->bmAttributes = dev_cap->dev_capability_data[0];
|
|
999
|
+
_ss_usb_device_cap->wSpeedSupported = ReadLittleEndian16(&dev_cap->dev_capability_data[1]);
|
|
1000
|
+
_ss_usb_device_cap->bFunctionalitySupport = dev_cap->dev_capability_data[3];
|
|
1001
|
+
_ss_usb_device_cap->bU1DevExitLat = dev_cap->dev_capability_data[4];
|
|
1002
|
+
_ss_usb_device_cap->bU2DevExitLat = ReadLittleEndian16(&dev_cap->dev_capability_data[5]);
|
|
999
1003
|
|
|
1000
1004
|
*ss_usb_device_cap = _ss_usb_device_cap;
|
|
1001
1005
|
return LIBUSB_SUCCESS;
|
|
1002
1006
|
}
|
|
1003
1007
|
|
|
1008
|
+
/// @cond DEV
|
|
1009
|
+
/** \internal \ingroup libusb_desc
|
|
1010
|
+
* We use this private struct only to parse a SuperSpeedPlus device capability
|
|
1011
|
+
* descriptor according to section 9.6.2.5 of the USB 3.1 specification.
|
|
1012
|
+
* We don't expose it.
|
|
1013
|
+
*/
|
|
1014
|
+
struct internal_ssplus_capability_descriptor {
|
|
1015
|
+
/** The length of the descriptor. Must be equal to LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE */
|
|
1016
|
+
uint8_t bLength;
|
|
1017
|
+
|
|
1018
|
+
/** The type of the descriptor */
|
|
1019
|
+
uint8_t bDescriptorType;
|
|
1020
|
+
|
|
1021
|
+
/** Must be equal to LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY */
|
|
1022
|
+
uint8_t bDevCapabilityType;
|
|
1023
|
+
|
|
1024
|
+
/** Unused */
|
|
1025
|
+
uint8_t bReserved;
|
|
1026
|
+
|
|
1027
|
+
/** Contains the number of SublinkSpeedIDs */
|
|
1028
|
+
uint32_t bmAttributes;
|
|
1029
|
+
|
|
1030
|
+
/** Contains the ssid, minRxLaneCount, and minTxLaneCount */
|
|
1031
|
+
uint16_t wFunctionalitySupport;
|
|
1032
|
+
|
|
1033
|
+
/** Unused */
|
|
1034
|
+
uint16_t wReserved;
|
|
1035
|
+
};
|
|
1036
|
+
/// @endcond
|
|
1037
|
+
|
|
1038
|
+
/** \ingroup libusb_desc
|
|
1039
|
+
* Get a SuperSpeedPlus USB Device Capability descriptor
|
|
1040
|
+
*
|
|
1041
|
+
* Since version 1.0.28, \ref LIBUSB_API_VERSION >= 0x0100010B
|
|
1042
|
+
*
|
|
1043
|
+
* \param ctx the context to operate on, or NULL for the default context
|
|
1044
|
+
* \param dev_cap Device Capability descriptor with a bDevCapabilityType of
|
|
1045
|
+
* \ref libusb_bos_type::LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY
|
|
1046
|
+
* LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY
|
|
1047
|
+
* \param ssplus_usb_device_cap output location for the SuperSpeedPlus USB Device
|
|
1048
|
+
* Capability descriptor. Only valid if 0 was returned. Must be freed with
|
|
1049
|
+
* libusb_free_ssplus_usb_device_capability_descriptor() after use.
|
|
1050
|
+
* \returns 0 on success
|
|
1051
|
+
* \returns a LIBUSB_ERROR code on error
|
|
1052
|
+
*/
|
|
1053
|
+
int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
|
|
1054
|
+
libusb_context *ctx,
|
|
1055
|
+
struct libusb_bos_dev_capability_descriptor *dev_cap,
|
|
1056
|
+
struct libusb_ssplus_usb_device_capability_descriptor **ssplus_usb_device_cap)
|
|
1057
|
+
{
|
|
1058
|
+
struct libusb_ssplus_usb_device_capability_descriptor *_ssplus_cap;
|
|
1059
|
+
|
|
1060
|
+
/* Use a private struct to reuse our descriptor parsing system. */
|
|
1061
|
+
struct internal_ssplus_capability_descriptor parsedDescriptor;
|
|
1062
|
+
|
|
1063
|
+
/* Some size/type checks to make sure everything is in order */
|
|
1064
|
+
if (dev_cap->bDevCapabilityType != LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY) {
|
|
1065
|
+
usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
|
|
1066
|
+
dev_cap->bDevCapabilityType,
|
|
1067
|
+
LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY);
|
|
1068
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1069
|
+
} else if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE) {
|
|
1070
|
+
usbi_err(ctx, "short dev-cap descriptor read %u/%d",
|
|
1071
|
+
dev_cap->bLength, LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE);
|
|
1072
|
+
return LIBUSB_ERROR_IO;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
const uint8_t* dev_capability_data = dev_cap->dev_capability_data;
|
|
1076
|
+
parsedDescriptor.bLength = dev_cap->bLength;
|
|
1077
|
+
parsedDescriptor.bDescriptorType = dev_cap->bDescriptorType;
|
|
1078
|
+
parsedDescriptor.bDevCapabilityType = dev_cap->bDevCapabilityType;
|
|
1079
|
+
parsedDescriptor.bReserved = dev_capability_data[0];
|
|
1080
|
+
parsedDescriptor.bmAttributes = ReadLittleEndian32(&dev_capability_data[1]);
|
|
1081
|
+
parsedDescriptor.wFunctionalitySupport = ReadLittleEndian16(&dev_capability_data[5]);
|
|
1082
|
+
parsedDescriptor.wReserved = ReadLittleEndian16(&dev_capability_data[7]);
|
|
1083
|
+
|
|
1084
|
+
uint8_t numSublikSpeedAttributes = (parsedDescriptor.bmAttributes & 0xF) + 1;
|
|
1085
|
+
_ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute));
|
|
1086
|
+
if (!_ssplus_cap)
|
|
1087
|
+
return LIBUSB_ERROR_NO_MEM;
|
|
1088
|
+
|
|
1089
|
+
/* Parse bmAttributes */
|
|
1090
|
+
_ssplus_cap->numSublinkSpeedAttributes = numSublikSpeedAttributes;
|
|
1091
|
+
_ssplus_cap->numSublinkSpeedIDs = ((parsedDescriptor.bmAttributes & 0xF0) >> 4) + 1;
|
|
1092
|
+
|
|
1093
|
+
/* Parse wFunctionalitySupport */
|
|
1094
|
+
_ssplus_cap->ssid = parsedDescriptor.wFunctionalitySupport & 0xF;
|
|
1095
|
+
_ssplus_cap->minRxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0x0F00) >> 8;
|
|
1096
|
+
_ssplus_cap->minTxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0xF000) >> 12;
|
|
1097
|
+
|
|
1098
|
+
/* Check that we have enough to read all the sublink attributes */
|
|
1099
|
+
if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + _ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t)) {
|
|
1100
|
+
usbi_err(ctx, "short ssplus capability descriptor, unable to read sublinks: Not enough data");
|
|
1101
|
+
return LIBUSB_ERROR_IO;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/* Read the attributes */
|
|
1105
|
+
uint8_t* base = ((uint8_t*)dev_cap) + LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE;
|
|
1106
|
+
for(uint8_t i = 0 ; i < _ssplus_cap->numSublinkSpeedAttributes ; i++) {
|
|
1107
|
+
uint32_t attr = ReadLittleEndian32(base + i * sizeof(uint32_t));
|
|
1108
|
+
_ssplus_cap->sublinkSpeedAttributes[i].ssid = attr & 0x0f;
|
|
1109
|
+
_ssplus_cap->sublinkSpeedAttributes[i].mantissa = attr >> 16;
|
|
1110
|
+
_ssplus_cap->sublinkSpeedAttributes[i].exponent = (attr >> 4) & 0x3 ;
|
|
1111
|
+
_ssplus_cap->sublinkSpeedAttributes[i].type = attr & 0x40 ? LIBUSB_SSPLUS_ATTR_TYPE_ASYM : LIBUSB_SSPLUS_ATTR_TYPE_SYM;
|
|
1112
|
+
_ssplus_cap->sublinkSpeedAttributes[i].direction = attr & 0x80 ? LIBUSB_SSPLUS_ATTR_DIR_TX : LIBUSB_SSPLUS_ATTR_DIR_RX;
|
|
1113
|
+
_ssplus_cap->sublinkSpeedAttributes[i].protocol = attr & 0x4000 ? LIBUSB_SSPLUS_ATTR_PROT_SSPLUS: LIBUSB_SSPLUS_ATTR_PROT_SS;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
*ssplus_usb_device_cap = _ssplus_cap;
|
|
1117
|
+
return LIBUSB_SUCCESS;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/** \ingroup libusb_desc
|
|
1121
|
+
* Free a SuperSpeedPlus USB Device Capability descriptor obtained from
|
|
1122
|
+
* libusb_get_ssplus_usb_device_capability_descriptor().
|
|
1123
|
+
* It is safe to call this function with a NULL ssplus_usb_device_cap
|
|
1124
|
+
* parameter, in which case the function simply returns.
|
|
1125
|
+
*
|
|
1126
|
+
* Since version 1.0.28, \ref LIBUSB_API_VERSION >= 0x0100010B
|
|
1127
|
+
*
|
|
1128
|
+
* \param ssplus_usb_device_cap the SuperSpeedPlus USB Device Capability descriptor
|
|
1129
|
+
* to free
|
|
1130
|
+
*/
|
|
1131
|
+
void API_EXPORTED libusb_free_ssplus_usb_device_capability_descriptor(
|
|
1132
|
+
struct libusb_ssplus_usb_device_capability_descriptor *ssplus_usb_device_cap)
|
|
1133
|
+
{
|
|
1134
|
+
free(ssplus_usb_device_cap);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1004
1139
|
/** \ingroup libusb_desc
|
|
1005
1140
|
* Free a SuperSpeed USB Device Capability descriptor obtained from
|
|
1006
1141
|
* libusb_get_ss_usb_device_capability_descriptor().
|
|
@@ -1021,7 +1156,7 @@ void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
|
|
|
1021
1156
|
*
|
|
1022
1157
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1023
1158
|
* \param dev_cap Device Capability descriptor with a bDevCapabilityType of
|
|
1024
|
-
* \ref
|
|
1159
|
+
* \ref libusb_bos_type::LIBUSB_BT_CONTAINER_ID
|
|
1025
1160
|
* LIBUSB_BT_CONTAINER_ID
|
|
1026
1161
|
* \param container_id output location for the Container ID descriptor.
|
|
1027
1162
|
* Only valid if 0 was returned. Must be freed with
|
|
@@ -1050,7 +1185,11 @@ int API_EXPORTED libusb_get_container_id_descriptor(libusb_context *ctx,
|
|
|
1050
1185
|
if (!_container_id)
|
|
1051
1186
|
return LIBUSB_ERROR_NO_MEM;
|
|
1052
1187
|
|
|
1053
|
-
|
|
1188
|
+
_container_id->bLength = dev_cap->bLength;
|
|
1189
|
+
_container_id->bDescriptorType = dev_cap->bDescriptorType;
|
|
1190
|
+
_container_id->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
|
1191
|
+
_container_id->bReserved = dev_cap->dev_capability_data[0];
|
|
1192
|
+
memcpy(_container_id->ContainerID, &dev_cap->dev_capability_data[1], 16);
|
|
1054
1193
|
|
|
1055
1194
|
*container_id = _container_id;
|
|
1056
1195
|
return LIBUSB_SUCCESS;
|
|
@@ -1077,7 +1216,7 @@ void API_EXPORTED libusb_free_container_id_descriptor(
|
|
|
1077
1216
|
*
|
|
1078
1217
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1079
1218
|
* \param dev_cap Device Capability descriptor with a bDevCapabilityType of
|
|
1080
|
-
* \ref
|
|
1219
|
+
* \ref libusb_bos_type::LIBUSB_BT_PLATFORM_DESCRIPTOR
|
|
1081
1220
|
* LIBUSB_BT_PLATFORM_DESCRIPTOR
|
|
1082
1221
|
* \param platform_descriptor output location for the Platform descriptor.
|
|
1083
1222
|
* Only valid if 0 was returned. Must be freed with
|
|
@@ -1106,13 +1245,17 @@ int API_EXPORTED libusb_get_platform_descriptor(libusb_context *ctx,
|
|
|
1106
1245
|
if (!_platform_descriptor)
|
|
1107
1246
|
return LIBUSB_ERROR_NO_MEM;
|
|
1108
1247
|
|
|
1109
|
-
|
|
1248
|
+
_platform_descriptor->bLength = dev_cap->bLength;
|
|
1249
|
+
_platform_descriptor->bDescriptorType = dev_cap->bDescriptorType;
|
|
1250
|
+
_platform_descriptor->bDevCapabilityType = dev_cap->bDevCapabilityType;
|
|
1251
|
+
_platform_descriptor->bReserved = dev_cap->dev_capability_data[0];
|
|
1252
|
+
memcpy(_platform_descriptor->PlatformCapabilityUUID, &(dev_cap->dev_capability_data[1]), 16);
|
|
1110
1253
|
|
|
1111
|
-
/* Capability data is located after reserved byte and
|
|
1254
|
+
/* Capability data is located after reserved byte and 16 byte UUID */
|
|
1112
1255
|
uint8_t* capability_data = dev_cap->dev_capability_data + 1 + 16;
|
|
1113
1256
|
|
|
1114
1257
|
/* Capability data length is total descriptor length minus initial fields */
|
|
1115
|
-
size_t capability_data_length =
|
|
1258
|
+
size_t capability_data_length = dev_cap->bLength - (3 + 1 + 16);
|
|
1116
1259
|
|
|
1117
1260
|
memcpy(_platform_descriptor->CapabilityData, capability_data, capability_data_length);
|
|
1118
1261
|
|
|
@@ -1168,9 +1311,7 @@ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_ha
|
|
|
1168
1311
|
r = libusb_get_string_descriptor(dev_handle, 0, 0, str.buf, 4);
|
|
1169
1312
|
if (r < 0)
|
|
1170
1313
|
return r;
|
|
1171
|
-
else if (r != 4 || str.desc.bLength < 4)
|
|
1172
|
-
return LIBUSB_ERROR_IO;
|
|
1173
|
-
else if (str.desc.bDescriptorType != LIBUSB_DT_STRING)
|
|
1314
|
+
else if (r != 4 || str.desc.bLength < 4 || str.desc.bDescriptorType != LIBUSB_DT_STRING)
|
|
1174
1315
|
return LIBUSB_ERROR_IO;
|
|
1175
1316
|
else if (str.desc.bLength & 1)
|
|
1176
1317
|
usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for language ID string descriptor", str.desc.bLength);
|
|
@@ -1179,9 +1320,7 @@ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_ha
|
|
|
1179
1320
|
r = libusb_get_string_descriptor(dev_handle, desc_index, langid, str.buf, sizeof(str.buf));
|
|
1180
1321
|
if (r < 0)
|
|
1181
1322
|
return r;
|
|
1182
|
-
else if (r < DESC_HEADER_LENGTH || str.desc.bLength > r)
|
|
1183
|
-
return LIBUSB_ERROR_IO;
|
|
1184
|
-
else if (str.desc.bDescriptorType != LIBUSB_DT_STRING)
|
|
1323
|
+
else if (r < DESC_HEADER_LENGTH || str.desc.bLength > r || str.desc.bDescriptorType != LIBUSB_DT_STRING)
|
|
1185
1324
|
return LIBUSB_ERROR_IO;
|
|
1186
1325
|
else if ((str.desc.bLength & 1) || str.desc.bLength != r)
|
|
1187
1326
|
usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for string descriptor (read %d)", str.desc.bLength, r);
|
|
@@ -1224,15 +1363,21 @@ static int parse_iad_array(struct libusb_context *ctx,
|
|
|
1224
1363
|
return LIBUSB_ERROR_IO;
|
|
1225
1364
|
}
|
|
1226
1365
|
|
|
1227
|
-
|
|
1366
|
+
/* First pass: Iterate through desc list, count number of IADs */
|
|
1228
1367
|
iad_array->length = 0;
|
|
1229
1368
|
while (consumed < size) {
|
|
1230
|
-
|
|
1231
|
-
|
|
1369
|
+
header.bLength = buf[0];
|
|
1370
|
+
header.bDescriptorType = buf[1];
|
|
1371
|
+
if (header.bLength < DESC_HEADER_LENGTH) {
|
|
1232
1372
|
usbi_err(ctx, "invalid descriptor bLength %d",
|
|
1233
1373
|
header.bLength);
|
|
1234
1374
|
return LIBUSB_ERROR_IO;
|
|
1235
1375
|
}
|
|
1376
|
+
else if (header.bLength > size) {
|
|
1377
|
+
usbi_warn(ctx, "short config descriptor read %d/%u",
|
|
1378
|
+
size, header.bLength);
|
|
1379
|
+
return LIBUSB_ERROR_IO;
|
|
1380
|
+
}
|
|
1236
1381
|
if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
|
|
1237
1382
|
iad_array->length++;
|
|
1238
1383
|
buf += header.bLength;
|
|
@@ -1241,22 +1386,36 @@ static int parse_iad_array(struct libusb_context *ctx,
|
|
|
1241
1386
|
|
|
1242
1387
|
iad_array->iad = NULL;
|
|
1243
1388
|
if (iad_array->length > 0) {
|
|
1244
|
-
iad = calloc(iad_array->length, sizeof(*iad));
|
|
1389
|
+
iad = calloc((size_t)iad_array->length, sizeof(*iad));
|
|
1245
1390
|
if (!iad)
|
|
1246
1391
|
return LIBUSB_ERROR_NO_MEM;
|
|
1247
1392
|
|
|
1248
1393
|
iad_array->iad = iad;
|
|
1249
1394
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1395
|
+
/* Second pass: Iterate through desc list, fill IAD structures */
|
|
1396
|
+
int remaining = size;
|
|
1252
1397
|
i = 0;
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1398
|
+
do {
|
|
1399
|
+
header.bLength = buffer[0];
|
|
1400
|
+
header.bDescriptorType = buffer[1];
|
|
1401
|
+
if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION && (remaining >= LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE)) {
|
|
1402
|
+
iad[i].bLength = buffer[0];
|
|
1403
|
+
iad[i].bDescriptorType = buffer[1];
|
|
1404
|
+
iad[i].bFirstInterface = buffer[2];
|
|
1405
|
+
iad[i].bInterfaceCount = buffer[3];
|
|
1406
|
+
iad[i].bFunctionClass = buffer[4];
|
|
1407
|
+
iad[i].bFunctionSubClass = buffer[5];
|
|
1408
|
+
iad[i].bFunctionProtocol = buffer[6];
|
|
1409
|
+
iad[i].iFunction = buffer[7];
|
|
1410
|
+
i++;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
remaining -= header.bLength;
|
|
1414
|
+
if (remaining < DESC_HEADER_LENGTH) {
|
|
1415
|
+
break;
|
|
1416
|
+
}
|
|
1417
|
+
buffer += header.bLength;
|
|
1418
|
+
} while (1);
|
|
1260
1419
|
}
|
|
1261
1420
|
|
|
1262
1421
|
return LIBUSB_SUCCESS;
|
package/libusb/libusb/hotplug.c
CHANGED
|
@@ -161,6 +161,27 @@ void usbi_hotplug_init(struct libusb_context *ctx)
|
|
|
161
161
|
usbi_atomic_store(&ctx->hotplug_ready, 1);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
static void usbi_recursively_remove_parents(struct libusb_device *dev, struct libusb_device *next_dev)
|
|
165
|
+
{
|
|
166
|
+
if (dev && dev->parent_dev) {
|
|
167
|
+
if (usbi_atomic_load(&dev->parent_dev->refcnt) == 1) {
|
|
168
|
+
/* The parent was processed before this device in the list and
|
|
169
|
+
* therefore has its ref count already decremented for its own ref.
|
|
170
|
+
* The only remaining counted ref comes from its remaining single child.
|
|
171
|
+
* It will thus be released when its child will be released. So we
|
|
172
|
+
* can remove it from the list. This is safe as parent_dev cannot be
|
|
173
|
+
* equal to next_dev given that we know at this point that it was
|
|
174
|
+
* previously seen in the list. */
|
|
175
|
+
assert (dev->parent_dev != next_dev);
|
|
176
|
+
if (dev->parent_dev->list.next && dev->parent_dev->list.prev) {
|
|
177
|
+
list_del(&dev->parent_dev->list);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
usbi_recursively_remove_parents(dev->parent_dev, next_dev);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
164
185
|
void usbi_hotplug_exit(struct libusb_context *ctx)
|
|
165
186
|
{
|
|
166
187
|
struct usbi_hotplug_callback *hotplug_cb, *next_cb;
|
|
@@ -193,7 +214,8 @@ void usbi_hotplug_exit(struct libusb_context *ctx)
|
|
|
193
214
|
free(msg);
|
|
194
215
|
}
|
|
195
216
|
|
|
196
|
-
/*
|
|
217
|
+
usbi_mutex_lock(&ctx->usb_devs_lock); /* hotplug thread might still be processing an already triggered event, possibly accessing this list as well */
|
|
218
|
+
/* free all discovered devices */
|
|
197
219
|
for_each_device_safe(ctx, dev, next_dev) {
|
|
198
220
|
/* remove the device from the usb_devs list only if there are no
|
|
199
221
|
* references held, otherwise leave it on the list so that a
|
|
@@ -201,15 +223,12 @@ void usbi_hotplug_exit(struct libusb_context *ctx)
|
|
|
201
223
|
if (usbi_atomic_load(&dev->refcnt) == 1) {
|
|
202
224
|
list_del(&dev->list);
|
|
203
225
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
equal to next_dev. */
|
|
208
|
-
assert (dev->parent_dev != next_dev);
|
|
209
|
-
list_del(&dev->parent_dev->list);
|
|
210
|
-
}
|
|
226
|
+
|
|
227
|
+
usbi_recursively_remove_parents(dev, next_dev);
|
|
228
|
+
|
|
211
229
|
libusb_unref_device(dev);
|
|
212
230
|
}
|
|
231
|
+
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
|
213
232
|
|
|
214
233
|
usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
|
|
215
234
|
}
|
package/libusb/libusb/io.c
CHANGED
|
@@ -1714,6 +1714,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
|
1714
1714
|
flags = transfer->flags;
|
|
1715
1715
|
transfer->status = status;
|
|
1716
1716
|
transfer->actual_length = itransfer->transferred;
|
|
1717
|
+
assert(transfer->actual_length >= 0);
|
|
1717
1718
|
usbi_dbg(ctx, "transfer %p has callback %p",
|
|
1718
1719
|
(void *) transfer, transfer->callback);
|
|
1719
1720
|
if (transfer->callback) {
|
|
@@ -2044,7 +2045,7 @@ int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
|
|
|
2044
2045
|
return 0;
|
|
2045
2046
|
}
|
|
2046
2047
|
|
|
2047
|
-
|
|
2048
|
+
/* NB: flying_transfers_lock must be held when calling this */
|
|
2048
2049
|
static void handle_timeout(struct usbi_transfer *itransfer)
|
|
2049
2050
|
{
|
|
2050
2051
|
struct libusb_transfer *transfer =
|
|
@@ -2060,7 +2061,7 @@ static void handle_timeout(struct usbi_transfer *itransfer)
|
|
|
2060
2061
|
"async cancel failed %d", r);
|
|
2061
2062
|
}
|
|
2062
2063
|
|
|
2063
|
-
|
|
2064
|
+
/* NB: flying_transfers_lock must be held when calling this */
|
|
2064
2065
|
static void handle_timeouts_locked(struct libusb_context *ctx)
|
|
2065
2066
|
{
|
|
2066
2067
|
struct timespec systime;
|
|
@@ -50,6 +50,8 @@ EXPORTS
|
|
|
50
50
|
libusb_free_ss_endpoint_companion_descriptor@4 = libusb_free_ss_endpoint_companion_descriptor
|
|
51
51
|
libusb_free_ss_usb_device_capability_descriptor
|
|
52
52
|
libusb_free_ss_usb_device_capability_descriptor@4 = libusb_free_ss_usb_device_capability_descriptor
|
|
53
|
+
libusb_free_ssplus_usb_device_capability_descriptor
|
|
54
|
+
libusb_free_ssplus_usb_device_capability_descriptor@4 = libusb_free_ssplus_usb_device_capability_descriptor
|
|
53
55
|
libusb_free_streams
|
|
54
56
|
libusb_free_streams@12 = libusb_free_streams
|
|
55
57
|
libusb_free_transfer
|
|
@@ -108,6 +110,8 @@ EXPORTS
|
|
|
108
110
|
libusb_get_ss_endpoint_companion_descriptor@12 = libusb_get_ss_endpoint_companion_descriptor
|
|
109
111
|
libusb_get_ss_usb_device_capability_descriptor
|
|
110
112
|
libusb_get_ss_usb_device_capability_descriptor@12 = libusb_get_ss_usb_device_capability_descriptor
|
|
113
|
+
libusb_get_ssplus_usb_device_capability_descriptor
|
|
114
|
+
libusb_get_ssplus_usb_device_capability_descriptor@12 = libusb_get_ssplus_usb_device_capability_descriptor
|
|
111
115
|
libusb_get_string_descriptor_ascii
|
|
112
116
|
libusb_get_string_descriptor_ascii@16 = libusb_get_string_descriptor_ascii
|
|
113
117
|
libusb_get_usb_2_0_extension_descriptor
|