libusb 0.5.0 → 0.5.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +1 -0
- data/History.md +8 -0
- data/README.md +5 -15
- data/Rakefile +8 -1
- data/ext/extconf.rb +49 -12
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/AUTHORS +12 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/COPYING +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/ChangeLog +18 -2
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/INSTALL +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Makefile.am +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Makefile.in +31 -18
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/NEWS +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/PORTING +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/README +5 -3
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/TODO +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/common.xcconfig +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/config.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/debug.xcconfig +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/libusb.xcconfig +0 -0
- data/ext/libusb-1.0.20/Xcode/libusb.xcodeproj/project.pbxproj +865 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/libusb_debug.xcconfig +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/libusb_release.xcconfig +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/release.xcconfig +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/aclocal.m4 +35 -32
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/README +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/config.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/Android.mk +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/Application.mk +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/examples.mk +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/libusb.mk +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/tests.mk +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/compile +1 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/config.guess +13 -160
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/config.h.in +6 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/config.sub +26 -12
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/configure +244 -20
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/configure.ac +27 -4
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/depcomp +1 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/doc/Makefile.am +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/doc/Makefile.in +19 -6
- data/ext/libusb-1.0.20/doc/doxygen.cfg.in +2334 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/Makefile.am +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/Makefile.in +19 -6
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/dpfp.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/dpfp_threaded.c +15 -10
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/ezusb.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/ezusb.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/fxload.c +28 -7
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/getopt/getopt.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/getopt/getopt.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/getopt/getopt1.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/hotplugtest.c +21 -3
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/listdevs.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/sam3u_benchmark.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/xusb.c +2 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/install-sh +170 -196
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb-1.0.pc.in +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/Makefile.am +15 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/Makefile.in +192 -53
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/core.c +218 -100
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/descriptor.c +3 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/hotplug.c +26 -9
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/hotplug.h +8 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/io.c +432 -290
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusb-1.0.def +2 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusb-1.0.rc +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusb.h +11 -10
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusbi.h +106 -29
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/darwin_usb.c +27 -67
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/darwin_usb.h +3 -7
- data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.am +5 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.in +810 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/aclocal.m4 +1193 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/compile +347 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/config.guess +1421 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/config.sub +1807 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/configure +17579 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/configure.ac +8 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/depcomp +791 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/haiku_pollfs.cpp +378 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb.h +112 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_backend.cpp +550 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.cpp +255 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.h +180 -0
- data/ext/libusb-1.0.20/libusb/os/haiku/install-sh +501 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/ltmain.sh +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/libtool.m4 +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/ltoptions.m4 +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/ltsugar.m4 +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/ltversion.m4 +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/lt~obsolete.m4 +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/missing +1 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_netlink.c +4 -4
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_udev.c +1 -2
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_usbfs.c +46 -49
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_usbfs.h +1 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/netbsd_usb.c +9 -73
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/openbsd_usb.c +9 -73
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_posix.c +2 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_posix.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_windows.c +3 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_windows.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_posix.c +3 -3
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_windows.c +3 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_windows.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/wince_usb.c +87 -250
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/wince_usb.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/windows_common.h +1 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/windows_usb.c +267 -181
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/windows_usb.h +22 -7
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/strerror.c +5 -2
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/sync.c +2 -1
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/version.h +1 -1
- data/ext/libusb-1.0.20/libusb/version_nano.h +1 -0
- data/ext/libusb-1.0.20/ltmain.sh +9655 -0
- data/ext/libusb-1.0.20/m4/libtool.m4 +7992 -0
- data/ext/libusb-1.0.20/m4/ltoptions.m4 +384 -0
- data/ext/libusb-1.0.20/m4/ltsugar.m4 +123 -0
- data/ext/libusb-1.0.20/m4/ltversion.m4 +23 -0
- data/ext/libusb-1.0.20/m4/lt~obsolete.m4 +98 -0
- data/ext/libusb-1.0.20/missing +215 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/Makefile.am +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/Makefile.in +19 -6
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/libusb_testlib.h +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/stress.c +0 -0
- data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/testlib.c +0 -0
- data/lib/libusb.rb +1 -0
- data/lib/libusb/call.rb +1 -0
- data/lib/libusb/context.rb +5 -2
- data/lib/libusb/stdio.rb +25 -0
- data/lib/libusb/version_gem.rb +1 -1
- data/libusb.gemspec +2 -1
- metadata +152 -115
- metadata.gz.sig +0 -0
- data/ext/libusb-1.0.19/Xcode/libusb.xcodeproj/project.pbxproj +0 -1
- data/ext/libusb-1.0.19/doc/doxygen.cfg.in +0 -1288
- data/ext/libusb-1.0.19/libusb/version_nano.h +0 -1
|
@@ -80,6 +80,8 @@ EXPORTS
|
|
|
80
80
|
libusb_get_parent@4 = libusb_get_parent
|
|
81
81
|
libusb_get_pollfds
|
|
82
82
|
libusb_get_pollfds@4 = libusb_get_pollfds
|
|
83
|
+
libusb_free_pollfds
|
|
84
|
+
libusb_free_pollfds@4 = libusb_free_pollfds
|
|
83
85
|
libusb_get_port_number
|
|
84
86
|
libusb_get_port_number@4 = libusb_get_port_number
|
|
85
87
|
libusb_get_port_numbers
|
|
File without changes
|
|
@@ -54,7 +54,7 @@ typedef unsigned __int32 uint32_t;
|
|
|
54
54
|
#include <sys/types.h>
|
|
55
55
|
#endif
|
|
56
56
|
|
|
57
|
-
#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__)
|
|
57
|
+
#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__)
|
|
58
58
|
#include <sys/time.h>
|
|
59
59
|
#endif
|
|
60
60
|
|
|
@@ -90,7 +90,7 @@ typedef unsigned __int32 uint32_t;
|
|
|
90
90
|
* Under Windows, the selection of available compilers and configurations
|
|
91
91
|
* means that, unlike other platforms, there is not <em>one true calling
|
|
92
92
|
* convention</em> (calling convention: the manner in which parameters are
|
|
93
|
-
* passed to
|
|
93
|
+
* passed to functions in the generated assembly code).
|
|
94
94
|
*
|
|
95
95
|
* Matching the Windows API itself, libusb uses the WINAPI convention (which
|
|
96
96
|
* translates to the <tt>stdcall</tt> convention) and guarantees that the
|
|
@@ -138,13 +138,10 @@ typedef unsigned __int32 uint32_t;
|
|
|
138
138
|
* #endif
|
|
139
139
|
* \endcode
|
|
140
140
|
*
|
|
141
|
-
* Another feature of LIBUSB_API_VERSION is that it can be used to detect
|
|
142
|
-
* whether you are compiling against the libusb or the libusb library.
|
|
143
|
-
*
|
|
144
141
|
* Internally, LIBUSB_API_VERSION is defined as follows:
|
|
145
142
|
* (libusb major << 24) | (libusb minor << 16) | (16 bit incremental)
|
|
146
143
|
*/
|
|
147
|
-
#define LIBUSB_API_VERSION
|
|
144
|
+
#define LIBUSB_API_VERSION 0x01000104
|
|
148
145
|
|
|
149
146
|
/* The following is kept for compatibility, but will be deprecated in the future */
|
|
150
147
|
#define LIBUSBX_API_VERSION LIBUSB_API_VERSION
|
|
@@ -668,8 +665,9 @@ struct libusb_config_descriptor {
|
|
|
668
665
|
uint8_t bmAttributes;
|
|
669
666
|
|
|
670
667
|
/** Maximum power consumption of the USB device from this bus in this
|
|
671
|
-
* configuration when the device is fully
|
|
672
|
-
* of 2 mA
|
|
668
|
+
* configuration when the device is fully operation. Expressed in units
|
|
669
|
+
* of 2 mA when the device is operating in high-speed mode and in units
|
|
670
|
+
* of 8 mA when the device is operating in super-speed mode. */
|
|
673
671
|
uint8_t MaxPower;
|
|
674
672
|
|
|
675
673
|
/** Array of interfaces supported by this configuration. The length of
|
|
@@ -900,7 +898,6 @@ struct libusb_control_setup {
|
|
|
900
898
|
struct libusb_context;
|
|
901
899
|
struct libusb_device;
|
|
902
900
|
struct libusb_device_handle;
|
|
903
|
-
struct libusb_hotplug_callback;
|
|
904
901
|
|
|
905
902
|
/** \ingroup lib
|
|
906
903
|
* Structure providing the version of the libusb runtime
|
|
@@ -1860,6 +1857,7 @@ typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data);
|
|
|
1860
1857
|
|
|
1861
1858
|
const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
|
|
1862
1859
|
libusb_context *ctx);
|
|
1860
|
+
void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds);
|
|
1863
1861
|
void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
|
|
1864
1862
|
libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
|
|
1865
1863
|
void *user_data);
|
|
@@ -1884,8 +1882,11 @@ typedef int libusb_hotplug_callback_handle;
|
|
|
1884
1882
|
*
|
|
1885
1883
|
* Flags for hotplug events */
|
|
1886
1884
|
typedef enum {
|
|
1885
|
+
/** Default value when not using any flags. */
|
|
1886
|
+
LIBUSB_HOTPLUG_NO_FLAGS = 0,
|
|
1887
|
+
|
|
1887
1888
|
/** Arm the callback and fire it for all matching currently attached devices. */
|
|
1888
|
-
LIBUSB_HOTPLUG_ENUMERATE = 1,
|
|
1889
|
+
LIBUSB_HOTPLUG_ENUMERATE = 1<<0,
|
|
1889
1890
|
} libusb_hotplug_flag;
|
|
1890
1891
|
|
|
1891
1892
|
/** \ingroup hotplug
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
#ifndef LIBUSBI_H
|
|
22
22
|
#define LIBUSBI_H
|
|
23
23
|
|
|
24
|
-
#include
|
|
24
|
+
#include <config.h>
|
|
25
25
|
|
|
26
26
|
#include <stdlib.h>
|
|
27
27
|
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
#ifdef HAVE_POLL_H
|
|
33
33
|
#include <poll.h>
|
|
34
34
|
#endif
|
|
35
|
-
|
|
36
35
|
#ifdef HAVE_MISSING_H
|
|
37
|
-
#include
|
|
36
|
+
#include <missing.h>
|
|
38
37
|
#endif
|
|
38
|
+
|
|
39
39
|
#include "libusb.h"
|
|
40
40
|
#include "version.h"
|
|
41
41
|
|
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
*/
|
|
49
49
|
#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY
|
|
50
50
|
|
|
51
|
+
#ifdef __cplusplus
|
|
52
|
+
extern "C" {
|
|
53
|
+
#endif
|
|
54
|
+
|
|
51
55
|
#define DEVICE_DESC_LENGTH 18
|
|
52
56
|
|
|
53
57
|
#define USB_MAXENDPOINTS 32
|
|
@@ -82,6 +86,9 @@ struct list_head {
|
|
|
82
86
|
#define list_entry(ptr, type, member) \
|
|
83
87
|
((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))
|
|
84
88
|
|
|
89
|
+
#define list_first_entry(ptr, type, member) \
|
|
90
|
+
list_entry((ptr)->next, type, member)
|
|
91
|
+
|
|
85
92
|
/* Get each entry from a list
|
|
86
93
|
* pos - A structure pointer has a "member" element
|
|
87
94
|
* head - list head
|
|
@@ -144,8 +151,12 @@ static inline void *usbi_reallocf(void *ptr, size_t size)
|
|
|
144
151
|
const typeof( ((type *)0)->member ) *mptr = (ptr); \
|
|
145
152
|
(type *)( (char *)mptr - offsetof(type,member) );})
|
|
146
153
|
|
|
154
|
+
#ifndef MIN
|
|
147
155
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
156
|
+
#endif
|
|
157
|
+
#ifndef MAX
|
|
148
158
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
159
|
+
#endif
|
|
149
160
|
|
|
150
161
|
#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
|
|
151
162
|
|
|
@@ -228,13 +239,15 @@ static inline void usbi_dbg(const char *format, ...)
|
|
|
228
239
|
|
|
229
240
|
extern struct libusb_context *usbi_default_context;
|
|
230
241
|
|
|
242
|
+
/* Forward declaration for use in context (fully defined inside poll abstraction) */
|
|
243
|
+
struct pollfd;
|
|
244
|
+
|
|
231
245
|
struct libusb_context {
|
|
232
246
|
int debug;
|
|
233
247
|
int debug_fixed;
|
|
234
248
|
|
|
235
|
-
/* internal
|
|
236
|
-
|
|
237
|
-
int ctrl_pipe[2];
|
|
249
|
+
/* internal event pipe, used for signalling occurrence of an internal event. */
|
|
250
|
+
int event_pipe[2];
|
|
238
251
|
|
|
239
252
|
struct list_head usb_devs;
|
|
240
253
|
usbi_mutex_t usb_devs_lock;
|
|
@@ -247,7 +260,6 @@ struct libusb_context {
|
|
|
247
260
|
/* A list of registered hotplug callbacks */
|
|
248
261
|
struct list_head hotplug_cbs;
|
|
249
262
|
usbi_mutex_t hotplug_cbs_lock;
|
|
250
|
-
int hotplug_pipe[2];
|
|
251
263
|
|
|
252
264
|
/* this is a list of in-flight transfer handles, sorted by timeout
|
|
253
265
|
* expiration. URBs to timeout the soonest are placed at the beginning of
|
|
@@ -256,15 +268,6 @@ struct libusb_context {
|
|
|
256
268
|
struct list_head flying_transfers;
|
|
257
269
|
usbi_mutex_t flying_transfers_lock;
|
|
258
270
|
|
|
259
|
-
/* list of poll fds */
|
|
260
|
-
struct list_head pollfds;
|
|
261
|
-
usbi_mutex_t pollfds_lock;
|
|
262
|
-
|
|
263
|
-
/* a counter that is set when we want to interrupt event handling, in order
|
|
264
|
-
* to modify the poll fd set. and a lock to protect it. */
|
|
265
|
-
unsigned int pollfd_modify;
|
|
266
|
-
usbi_mutex_t pollfd_modify_lock;
|
|
267
|
-
|
|
268
271
|
/* user callbacks for pollfd changes */
|
|
269
272
|
libusb_pollfd_added_cb fd_added_cb;
|
|
270
273
|
libusb_pollfd_removed_cb fd_removed_cb;
|
|
@@ -281,6 +284,28 @@ struct libusb_context {
|
|
|
281
284
|
usbi_mutex_t event_waiters_lock;
|
|
282
285
|
usbi_cond_t event_waiters_cond;
|
|
283
286
|
|
|
287
|
+
/* A lock to protect internal context event data. */
|
|
288
|
+
usbi_mutex_t event_data_lock;
|
|
289
|
+
|
|
290
|
+
/* A counter that is set when we want to interrupt and prevent event handling,
|
|
291
|
+
* in order to safely close a device. Protected by event_data_lock. */
|
|
292
|
+
unsigned int device_close;
|
|
293
|
+
|
|
294
|
+
/* list and count of poll fds and an array of poll fd structures that is
|
|
295
|
+
* (re)allocated as necessary prior to polling, and a flag to indicate
|
|
296
|
+
* when the list of poll fds has changed since the last poll.
|
|
297
|
+
* Protected by event_data_lock. */
|
|
298
|
+
struct list_head ipollfds;
|
|
299
|
+
struct pollfd *pollfds;
|
|
300
|
+
POLL_NFDS_TYPE pollfds_cnt;
|
|
301
|
+
unsigned int pollfds_modified;
|
|
302
|
+
|
|
303
|
+
/* A list of pending hotplug messages. Protected by event_data_lock. */
|
|
304
|
+
struct list_head hotplug_msgs;
|
|
305
|
+
|
|
306
|
+
/* A list of pending completed transfers. Protected by event_data_lock. */
|
|
307
|
+
struct list_head completed_transfers;
|
|
308
|
+
|
|
284
309
|
#ifdef USBI_TIMERFD_AVAILABLE
|
|
285
310
|
/* used for timeout handling, if supported by OS.
|
|
286
311
|
* this timerfd is maintained to trigger on the next pending timeout */
|
|
@@ -290,6 +315,11 @@ struct libusb_context {
|
|
|
290
315
|
struct list_head list;
|
|
291
316
|
};
|
|
292
317
|
|
|
318
|
+
/* Update the following macro if new event sources are added */
|
|
319
|
+
#define usbi_pending_events(ctx) \
|
|
320
|
+
((ctx)->device_close || (ctx)->pollfds_modified \
|
|
321
|
+
|| !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers))
|
|
322
|
+
|
|
293
323
|
#ifdef USBI_TIMERFD_AVAILABLE
|
|
294
324
|
#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0)
|
|
295
325
|
#else
|
|
@@ -364,6 +394,7 @@ enum {
|
|
|
364
394
|
struct usbi_transfer {
|
|
365
395
|
int num_iso_packets;
|
|
366
396
|
struct list_head list;
|
|
397
|
+
struct list_head completed_list;
|
|
367
398
|
struct timeval timeout;
|
|
368
399
|
int transferred;
|
|
369
400
|
uint32_t stream_id;
|
|
@@ -377,6 +408,10 @@ struct usbi_transfer {
|
|
|
377
408
|
* its completion (presumably there would be races within your OS backend
|
|
378
409
|
* if this were possible). */
|
|
379
410
|
usbi_mutex_t lock;
|
|
411
|
+
|
|
412
|
+
/* this lock should be held whenever viewing or modifying flags
|
|
413
|
+
* relating to the transfer state */
|
|
414
|
+
usbi_mutex_t flags_lock;
|
|
380
415
|
};
|
|
381
416
|
|
|
382
417
|
enum usbi_transfer_flags {
|
|
@@ -392,8 +427,17 @@ enum usbi_transfer_flags {
|
|
|
392
427
|
/* Operation on the transfer failed because the device disappeared */
|
|
393
428
|
USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3,
|
|
394
429
|
|
|
395
|
-
/*
|
|
396
|
-
|
|
430
|
+
/* Transfer is currently being submitted */
|
|
431
|
+
USBI_TRANSFER_SUBMITTING = 1 << 4,
|
|
432
|
+
|
|
433
|
+
/* Transfer successfully submitted by backend */
|
|
434
|
+
USBI_TRANSFER_IN_FLIGHT = 1 << 5,
|
|
435
|
+
|
|
436
|
+
/* Completion handler has run */
|
|
437
|
+
USBI_TRANSFER_COMPLETED = 1 << 6,
|
|
438
|
+
|
|
439
|
+
/* The transfer timeout has been handled */
|
|
440
|
+
USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 7,
|
|
397
441
|
};
|
|
398
442
|
|
|
399
443
|
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
|
|
@@ -434,6 +478,7 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle);
|
|
|
434
478
|
int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
435
479
|
enum libusb_transfer_status status);
|
|
436
480
|
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);
|
|
481
|
+
void usbi_signal_transfer_completion(struct usbi_transfer *transfer);
|
|
437
482
|
|
|
438
483
|
int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
|
|
439
484
|
void *dest, int host_endian);
|
|
@@ -444,8 +489,11 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
|
|
|
444
489
|
void usbi_connect_device (struct libusb_device *dev);
|
|
445
490
|
void usbi_disconnect_device (struct libusb_device *dev);
|
|
446
491
|
|
|
492
|
+
int usbi_signal_event(struct libusb_context *ctx);
|
|
493
|
+
int usbi_clear_event(struct libusb_context *ctx);
|
|
494
|
+
|
|
447
495
|
/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
|
|
448
|
-
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD)
|
|
496
|
+
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU)
|
|
449
497
|
#include <unistd.h>
|
|
450
498
|
#include "os/poll_posix.h"
|
|
451
499
|
#elif defined(OS_WINDOWS) || defined(OS_WINCE)
|
|
@@ -474,7 +522,6 @@ struct usbi_pollfd {
|
|
|
474
522
|
|
|
475
523
|
int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
|
|
476
524
|
void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
|
|
477
|
-
void usbi_fd_notification(struct libusb_context *ctx);
|
|
478
525
|
|
|
479
526
|
/* device discovery */
|
|
480
527
|
|
|
@@ -765,7 +812,7 @@ struct usbi_os_backend {
|
|
|
765
812
|
* This function should not generate any bus I/O and should not block.
|
|
766
813
|
* Interface claiming is a logical operation that simply ensures that
|
|
767
814
|
* no other drivers/applications are using the interface, and after
|
|
768
|
-
* claiming, no other drivers/
|
|
815
|
+
* claiming, no other drivers/applications can use the interface because
|
|
769
816
|
* we now "own" it.
|
|
770
817
|
*
|
|
771
818
|
* Return:
|
|
@@ -943,8 +990,14 @@ struct usbi_os_backend {
|
|
|
943
990
|
*/
|
|
944
991
|
void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
|
|
945
992
|
|
|
946
|
-
/* Handle any pending events
|
|
947
|
-
*
|
|
993
|
+
/* Handle any pending events on file descriptors. Optional.
|
|
994
|
+
*
|
|
995
|
+
* Provide this function when file descriptors directly indicate device
|
|
996
|
+
* or transfer activity. If your backend does not have such file descriptors,
|
|
997
|
+
* implement the handle_transfer_completion function below.
|
|
998
|
+
*
|
|
999
|
+
* This involves monitoring any active transfers and processing their
|
|
1000
|
+
* completion or cancellation.
|
|
948
1001
|
*
|
|
949
1002
|
* The function is passed an array of pollfd structures (size nfds)
|
|
950
1003
|
* as a result of the poll() system call. The num_ready parameter
|
|
@@ -972,6 +1025,31 @@ struct usbi_os_backend {
|
|
|
972
1025
|
int (*handle_events)(struct libusb_context *ctx,
|
|
973
1026
|
struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
|
|
974
1027
|
|
|
1028
|
+
/* Handle transfer completion. Optional.
|
|
1029
|
+
*
|
|
1030
|
+
* Provide this function when there are no file descriptors available
|
|
1031
|
+
* that directly indicate device or transfer activity. If your backend does
|
|
1032
|
+
* have such file descriptors, implement the handle_events function above.
|
|
1033
|
+
*
|
|
1034
|
+
* Your backend must tell the library when a transfer has completed by
|
|
1035
|
+
* calling usbi_signal_transfer_completion(). You should store any private
|
|
1036
|
+
* information about the transfer and its completion status in the transfer's
|
|
1037
|
+
* private backend data.
|
|
1038
|
+
*
|
|
1039
|
+
* During event handling, this function will be called on each transfer for
|
|
1040
|
+
* which usbi_signal_transfer_completion() was called.
|
|
1041
|
+
*
|
|
1042
|
+
* For any cancelled transfers, call usbi_handle_transfer_cancellation().
|
|
1043
|
+
* For completed transfers, call usbi_handle_transfer_completion().
|
|
1044
|
+
* For control/bulk/interrupt transfers, populate the "transferred"
|
|
1045
|
+
* element of the appropriate usbi_transfer structure before calling the
|
|
1046
|
+
* above functions. For isochronous transfers, populate the status and
|
|
1047
|
+
* transferred fields of the iso packet descriptors of the transfer.
|
|
1048
|
+
*
|
|
1049
|
+
* Return 0 on success, or a LIBUSB_ERROR code on failure.
|
|
1050
|
+
*/
|
|
1051
|
+
int (*handle_transfer_completion)(struct usbi_transfer *itransfer);
|
|
1052
|
+
|
|
975
1053
|
/* Get time from specified clock. At least two clocks must be implemented
|
|
976
1054
|
by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
|
|
977
1055
|
|
|
@@ -1002,12 +1080,6 @@ struct usbi_os_backend {
|
|
|
1002
1080
|
* usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance.
|
|
1003
1081
|
*/
|
|
1004
1082
|
size_t transfer_priv_size;
|
|
1005
|
-
|
|
1006
|
-
/* Mumber of additional bytes for os_priv for each iso packet.
|
|
1007
|
-
* Can your backend use this? */
|
|
1008
|
-
/* FIXME: linux can't use this any more. if other OS's cannot either,
|
|
1009
|
-
* then remove this */
|
|
1010
|
-
size_t add_iso_packet_size;
|
|
1011
1083
|
};
|
|
1012
1084
|
|
|
1013
1085
|
extern const struct usbi_os_backend * const usbi_backend;
|
|
@@ -1018,8 +1090,13 @@ extern const struct usbi_os_backend openbsd_backend;
|
|
|
1018
1090
|
extern const struct usbi_os_backend netbsd_backend;
|
|
1019
1091
|
extern const struct usbi_os_backend windows_backend;
|
|
1020
1092
|
extern const struct usbi_os_backend wince_backend;
|
|
1093
|
+
extern const struct usbi_os_backend haiku_usb_raw_backend;
|
|
1021
1094
|
|
|
1022
1095
|
extern struct list_head active_contexts_list;
|
|
1023
1096
|
extern usbi_mutex_static_t active_contexts_lock;
|
|
1024
1097
|
|
|
1098
|
+
#ifdef __cplusplus
|
|
1099
|
+
}
|
|
1100
|
+
#endif
|
|
1101
|
+
|
|
1025
1102
|
#endif
|
|
@@ -246,7 +246,7 @@ static usb_device_t **darwin_device_from_service (io_service_t service)
|
|
|
246
246
|
&score);
|
|
247
247
|
|
|
248
248
|
if (kIOReturnSuccess != result || !plugInInterface) {
|
|
249
|
-
usbi_dbg ("could not set up plugin for service: %s
|
|
249
|
+
usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (result));
|
|
250
250
|
return NULL;
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -279,6 +279,7 @@ static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
|
|
|
279
279
|
static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
|
280
280
|
struct libusb_device *dev = NULL;
|
|
281
281
|
struct libusb_context *ctx;
|
|
282
|
+
struct darwin_cached_device *old_device;
|
|
282
283
|
|
|
283
284
|
io_service_t device;
|
|
284
285
|
UInt64 session;
|
|
@@ -293,6 +294,17 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
|
|
293
294
|
if (!ret)
|
|
294
295
|
continue;
|
|
295
296
|
|
|
297
|
+
/* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
|
|
298
|
+
otherwise no cached device will ever get freed */
|
|
299
|
+
usbi_mutex_lock(&darwin_cached_devices_lock);
|
|
300
|
+
list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
|
|
301
|
+
if (old_device->session == session) {
|
|
302
|
+
darwin_deref_cached_device (old_device);
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
usbi_mutex_unlock(&darwin_cached_devices_lock);
|
|
307
|
+
|
|
296
308
|
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
|
|
297
309
|
usbi_dbg ("notifying context %p of device disconnect", ctx);
|
|
298
310
|
|
|
@@ -973,14 +985,6 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
|
|
|
973
985
|
/* device opened successfully */
|
|
974
986
|
dpriv->open_count++;
|
|
975
987
|
|
|
976
|
-
/* create a file descriptor for notifications */
|
|
977
|
-
pipe (priv->fds);
|
|
978
|
-
|
|
979
|
-
/* set the pipe to be non-blocking */
|
|
980
|
-
fcntl (priv->fds[1], F_SETFD, O_NONBLOCK);
|
|
981
|
-
|
|
982
|
-
usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
|
|
983
|
-
|
|
984
988
|
usbi_dbg ("device open for access");
|
|
985
989
|
|
|
986
990
|
return 0;
|
|
@@ -994,7 +998,7 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
|
|
|
994
998
|
|
|
995
999
|
if (dpriv->open_count == 0) {
|
|
996
1000
|
/* something is probably very wrong if this is the case */
|
|
997
|
-
usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open
|
|
1001
|
+
usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
|
|
998
1002
|
return;
|
|
999
1003
|
}
|
|
1000
1004
|
|
|
@@ -1024,13 +1028,6 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
|
|
|
1024
1028
|
}
|
|
1025
1029
|
}
|
|
1026
1030
|
}
|
|
1027
|
-
|
|
1028
|
-
/* file descriptors are maintained per-instance */
|
|
1029
|
-
usbi_remove_pollfd (HANDLE_CTX (dev_handle), priv->fds[0]);
|
|
1030
|
-
close (priv->fds[1]);
|
|
1031
|
-
close (priv->fds[0]);
|
|
1032
|
-
|
|
1033
|
-
priv->fds[0] = priv->fds[1] = -1;
|
|
1034
1031
|
}
|
|
1035
1032
|
|
|
1036
1033
|
static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
|
|
@@ -1761,9 +1758,7 @@ static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) {
|
|
|
1761
1758
|
static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
|
|
1762
1759
|
struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
|
|
1763
1760
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1764
|
-
struct
|
|
1765
|
-
struct darwin_msg_async_io_complete message = {.itransfer = itransfer, .result = result,
|
|
1766
|
-
.size = (UInt32) (uintptr_t) arg0};
|
|
1761
|
+
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
|
1767
1762
|
|
|
1768
1763
|
usbi_dbg ("an async io operation has completed");
|
|
1769
1764
|
|
|
@@ -1777,8 +1772,11 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
|
|
|
1777
1772
|
(*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
|
|
1778
1773
|
}
|
|
1779
1774
|
|
|
1780
|
-
|
|
1781
|
-
|
|
1775
|
+
tpriv->result = result;
|
|
1776
|
+
tpriv->size = (UInt32) (uintptr_t) arg0;
|
|
1777
|
+
|
|
1778
|
+
/* signal the core that this transfer is complete */
|
|
1779
|
+
usbi_signal_transfer_completion(itransfer);
|
|
1782
1780
|
}
|
|
1783
1781
|
|
|
1784
1782
|
static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
|
|
@@ -1807,7 +1805,7 @@ static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_
|
|
|
1807
1805
|
}
|
|
1808
1806
|
}
|
|
1809
1807
|
|
|
1810
|
-
static
|
|
1808
|
+
static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
|
|
1811
1809
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1812
1810
|
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
|
1813
1811
|
int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
|
|
@@ -1818,13 +1816,13 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
|
|
|
1818
1816
|
|
|
1819
1817
|
if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
|
|
1820
1818
|
usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
|
|
1821
|
-
return;
|
|
1819
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1822
1820
|
}
|
|
1823
1821
|
|
|
1824
1822
|
usbi_dbg ("handling %s completion with kernel status %d",
|
|
1825
|
-
isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", result);
|
|
1823
|
+
isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
|
|
1826
1824
|
|
|
1827
|
-
if (kIOReturnSuccess == result || kIOReturnUnderrun == result) {
|
|
1825
|
+
if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
|
|
1828
1826
|
if (isIsoc && tpriv->isoc_framelist) {
|
|
1829
1827
|
/* copy isochronous results back */
|
|
1830
1828
|
|
|
@@ -1834,48 +1832,11 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
|
|
|
1834
1832
|
lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
|
|
1835
1833
|
}
|
|
1836
1834
|
} else if (!isIsoc)
|
|
1837
|
-
itransfer->transferred +=
|
|
1835
|
+
itransfer->transferred += tpriv->size;
|
|
1838
1836
|
}
|
|
1839
1837
|
|
|
1840
1838
|
/* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
|
|
1841
|
-
usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
|
|
1845
|
-
struct darwin_msg_async_io_complete message;
|
|
1846
|
-
POLL_NFDS_TYPE i = 0;
|
|
1847
|
-
ssize_t ret;
|
|
1848
|
-
|
|
1849
|
-
usbi_mutex_lock(&ctx->open_devs_lock);
|
|
1850
|
-
|
|
1851
|
-
for (i = 0; i < nfds && num_ready > 0; i++) {
|
|
1852
|
-
struct pollfd *pollfd = &fds[i];
|
|
1853
|
-
|
|
1854
|
-
usbi_dbg ("checking fd %i with revents = %x", pollfd->fd, pollfd->revents);
|
|
1855
|
-
|
|
1856
|
-
if (!pollfd->revents)
|
|
1857
|
-
continue;
|
|
1858
|
-
|
|
1859
|
-
num_ready--;
|
|
1860
|
-
|
|
1861
|
-
if (pollfd->revents & POLLERR) {
|
|
1862
|
-
/* this probably will never happen so ignore the error an move on. */
|
|
1863
|
-
continue;
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
/* there is only one type of message */
|
|
1867
|
-
ret = read (pollfd->fd, &message, sizeof (message));
|
|
1868
|
-
if (ret < (ssize_t) sizeof (message)) {
|
|
1869
|
-
usbi_dbg ("WARNING: short read on async io completion pipe\n");
|
|
1870
|
-
continue;
|
|
1871
|
-
}
|
|
1872
|
-
|
|
1873
|
-
darwin_handle_callback (message.itransfer, message.result, message.size);
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
usbi_mutex_unlock(&ctx->open_devs_lock);
|
|
1877
|
-
|
|
1878
|
-
return 0;
|
|
1839
|
+
return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
|
|
1879
1840
|
}
|
|
1880
1841
|
|
|
1881
1842
|
static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
|
|
@@ -1998,12 +1959,11 @@ const struct usbi_os_backend darwin_backend = {
|
|
|
1998
1959
|
.cancel_transfer = darwin_cancel_transfer,
|
|
1999
1960
|
.clear_transfer_priv = darwin_clear_transfer_priv,
|
|
2000
1961
|
|
|
2001
|
-
.
|
|
1962
|
+
.handle_transfer_completion = darwin_handle_transfer_completion,
|
|
2002
1963
|
|
|
2003
1964
|
.clock_gettime = darwin_clock_gettime,
|
|
2004
1965
|
|
|
2005
1966
|
.device_priv_size = sizeof(struct darwin_device_priv),
|
|
2006
1967
|
.device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
|
|
2007
1968
|
.transfer_priv_size = sizeof(struct darwin_transfer_priv),
|
|
2008
|
-
.add_iso_packet_size = 0,
|
|
2009
1969
|
};
|