summary refs log tree commit diff
path: root/usb_util
diff options
context:
space:
mode:
authorJingkui Wang <jkwang@google.com>2018-11-02 00:27:48 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-12-01 01:08:35 -0800
commit33e08312f272c863f062fffe53ea4a4ce94e6e26 (patch)
treec58171884a5b0e4d16dd9a4ee8633d75a461a281 /usb_util
parent9ae286d008fd1c2a5b7f25f4184529fe6b5f169d (diff)
downloadcrosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.tar
crosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.tar.gz
crosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.tar.bz2
crosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.tar.lz
crosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.tar.xz
crosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.tar.zst
crosvm-33e08312f272c863f062fffe53ea4a4ce94e6e26.zip
usb_util: Create libusb wrapper
This wrapper will be part of usb emulation backend.

BUG=chromium:831850
TEST=local build

Change-Id: I084b15201941e4c16c4e3ff9b967e55db09db567
Reviewed-on: https://chromium-review.googlesource.com/1124870
Commit-Ready: Jingkui Wang <jkwang@google.com>
Tested-by: Jingkui Wang <jkwang@google.com>
Reviewed-by: Jingkui Wang <jkwang@google.com>
Diffstat (limited to 'usb_util')
-rw-r--r--usb_util/Cargo.toml11
-rw-r--r--usb_util/build.rs11
-rw-r--r--usb_util/src/bindings.rs4627
-rw-r--r--usb_util/src/config_descriptor.rs32
-rw-r--r--usb_util/src/device_handle.rs129
-rw-r--r--usb_util/src/error.rs85
-rw-r--r--usb_util/src/lib.rs19
-rw-r--r--usb_util/src/libusb_context.rs156
-rw-r--r--usb_util/src/libusb_device.rs109
-rw-r--r--usb_util/src/types.rs198
10 files changed, 5377 insertions, 0 deletions
diff --git a/usb_util/Cargo.toml b/usb_util/Cargo.toml
new file mode 100644
index 0000000..a0984a2
--- /dev/null
+++ b/usb_util/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "usb_util"
+version = "0.1.0"
+authors = ["The Chromium OS Authors"]
+build = "build.rs"
+
+[dependencies]
+data_model = { path = "../data_model" }
+
+[build-dependencies]
+pkg-config = "=0.3.11"
diff --git a/usb_util/build.rs b/usb_util/build.rs
new file mode 100644
index 0000000..ee6ab30
--- /dev/null
+++ b/usb_util/build.rs
@@ -0,0 +1,11 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+extern crate pkg_config;
+use std::env;
+
+fn main() {
+    env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
+    pkg_config::probe_library("libusb-1.0").unwrap();
+}
diff --git a/usb_util/src/bindings.rs b/usb_util/src/bindings.rs
new file mode 100644
index 0000000..d24bf03
--- /dev/null
+++ b/usb_util/src/bindings.rs
@@ -0,0 +1,4627 @@
+/* automatically generated by rust-bindgen */
+
+#[repr(C)]
+#[derive(Default)]
+pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
+impl<T> __IncompleteArrayField<T> {
+    #[inline]
+    pub fn new() -> Self {
+        __IncompleteArrayField(::std::marker::PhantomData)
+    }
+    #[inline]
+    pub unsafe fn as_ptr(&self) -> *const T {
+        ::std::mem::transmute(self)
+    }
+    #[inline]
+    pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
+        ::std::mem::transmute(self)
+    }
+    #[inline]
+    pub unsafe fn as_slice(&self, len: usize) -> &[T] {
+        ::std::slice::from_raw_parts(self.as_ptr(), len)
+    }
+    #[inline]
+    pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
+        ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
+    }
+}
+impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
+    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+        fmt.write_str("__IncompleteArrayField")
+    }
+}
+impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        Self::new()
+    }
+}
+impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
+pub const _STDINT_H: u32 = 1;
+pub const _FEATURES_H: u32 = 1;
+pub const _DEFAULT_SOURCE: u32 = 1;
+pub const __USE_ISOC11: u32 = 1;
+pub const __USE_ISOC99: u32 = 1;
+pub const __USE_ISOC95: u32 = 1;
+pub const __USE_POSIX_IMPLICITLY: u32 = 1;
+pub const _POSIX_SOURCE: u32 = 1;
+pub const _POSIX_C_SOURCE: u32 = 200809;
+pub const __USE_POSIX: u32 = 1;
+pub const __USE_POSIX2: u32 = 1;
+pub const __USE_POSIX199309: u32 = 1;
+pub const __USE_POSIX199506: u32 = 1;
+pub const __USE_XOPEN2K: u32 = 1;
+pub const __USE_XOPEN2K8: u32 = 1;
+pub const _ATFILE_SOURCE: u32 = 1;
+pub const __USE_MISC: u32 = 1;
+pub const __USE_ATFILE: u32 = 1;
+pub const __USE_FORTIFY_LEVEL: u32 = 0;
+pub const _STDC_PREDEF_H: u32 = 1;
+pub const __STDC_IEC_559__: u32 = 1;
+pub const __STDC_IEC_559_COMPLEX__: u32 = 1;
+pub const __STDC_ISO_10646__: u32 = 201605;
+pub const __STDC_NO_THREADS__: u32 = 1;
+pub const __GNU_LIBRARY__: u32 = 6;
+pub const __GLIBC__: u32 = 2;
+pub const __GLIBC_MINOR__: u32 = 24;
+pub const _SYS_CDEFS_H: u32 = 1;
+pub const __WORDSIZE: u32 = 64;
+pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1;
+pub const __SYSCALL_WORDSIZE: u32 = 64;
+pub const _BITS_WCHAR_H: u32 = 1;
+pub const INT8_MIN: i32 = -128;
+pub const INT16_MIN: i32 = -32768;
+pub const INT32_MIN: i32 = -2147483648;
+pub const INT8_MAX: u32 = 127;
+pub const INT16_MAX: u32 = 32767;
+pub const INT32_MAX: u32 = 2147483647;
+pub const UINT8_MAX: u32 = 255;
+pub const UINT16_MAX: u32 = 65535;
+pub const UINT32_MAX: u32 = 4294967295;
+pub const INT_LEAST8_MIN: i32 = -128;
+pub const INT_LEAST16_MIN: i32 = -32768;
+pub const INT_LEAST32_MIN: i32 = -2147483648;
+pub const INT_LEAST8_MAX: u32 = 127;
+pub const INT_LEAST16_MAX: u32 = 32767;
+pub const INT_LEAST32_MAX: u32 = 2147483647;
+pub const UINT_LEAST8_MAX: u32 = 255;
+pub const UINT_LEAST16_MAX: u32 = 65535;
+pub const UINT_LEAST32_MAX: u32 = 4294967295;
+pub const INT_FAST8_MIN: i32 = -128;
+pub const INT_FAST16_MIN: i64 = -9223372036854775808;
+pub const INT_FAST32_MIN: i64 = -9223372036854775808;
+pub const INT_FAST8_MAX: u32 = 127;
+pub const INT_FAST16_MAX: u64 = 9223372036854775807;
+pub const INT_FAST32_MAX: u64 = 9223372036854775807;
+pub const UINT_FAST8_MAX: u32 = 255;
+pub const UINT_FAST16_MAX: i32 = -1;
+pub const UINT_FAST32_MAX: i32 = -1;
+pub const INTPTR_MIN: i64 = -9223372036854775808;
+pub const INTPTR_MAX: u64 = 9223372036854775807;
+pub const UINTPTR_MAX: i32 = -1;
+pub const PTRDIFF_MIN: i64 = -9223372036854775808;
+pub const PTRDIFF_MAX: u64 = 9223372036854775807;
+pub const SIG_ATOMIC_MIN: i32 = -2147483648;
+pub const SIG_ATOMIC_MAX: u32 = 2147483647;
+pub const SIZE_MAX: i32 = -1;
+pub const WINT_MIN: u32 = 0;
+pub const WINT_MAX: u32 = 4294967295;
+pub const _SYS_TYPES_H: u32 = 1;
+pub const _BITS_TYPES_H: u32 = 1;
+pub const _BITS_TYPESIZES_H: u32 = 1;
+pub const __OFF_T_MATCHES_OFF64_T: u32 = 1;
+pub const __INO_T_MATCHES_INO64_T: u32 = 1;
+pub const __FD_SETSIZE: u32 = 1024;
+pub const __clock_t_defined: u32 = 1;
+pub const __time_t_defined: u32 = 1;
+pub const __clockid_t_defined: u32 = 1;
+pub const __timer_t_defined: u32 = 1;
+pub const __BIT_TYPES_DEFINED__: u32 = 1;
+pub const _ENDIAN_H: u32 = 1;
+pub const __LITTLE_ENDIAN: u32 = 1234;
+pub const __BIG_ENDIAN: u32 = 4321;
+pub const __PDP_ENDIAN: u32 = 3412;
+pub const __BYTE_ORDER: u32 = 1234;
+pub const __FLOAT_WORD_ORDER: u32 = 1234;
+pub const LITTLE_ENDIAN: u32 = 1234;
+pub const BIG_ENDIAN: u32 = 4321;
+pub const PDP_ENDIAN: u32 = 3412;
+pub const BYTE_ORDER: u32 = 1234;
+pub const _BITS_BYTESWAP_H: u32 = 1;
+pub const _SYS_SELECT_H: u32 = 1;
+pub const __FD_ZERO_STOS: &'static [u8; 6usize] = b"stosq\0";
+pub const _SIGSET_H_types: u32 = 1;
+pub const __timespec_defined: u32 = 1;
+pub const _STRUCT_TIMEVAL: u32 = 1;
+pub const FD_SETSIZE: u32 = 1024;
+pub const _SYS_SYSMACROS_H: u32 = 1;
+pub const _BITS_PTHREADTYPES_H: u32 = 1;
+pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56;
+pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40;
+pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4;
+pub const __SIZEOF_PTHREAD_COND_T: u32 = 48;
+pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4;
+pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8;
+pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32;
+pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4;
+pub const __have_pthread_attr_t: u32 = 1;
+pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1;
+pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1;
+pub const _SYS_TIME_H: u32 = 1;
+pub const _TIME_H: u32 = 1;
+pub const _BITS_TIME_H: u32 = 1;
+pub const CLOCK_REALTIME: u32 = 0;
+pub const CLOCK_MONOTONIC: u32 = 1;
+pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2;
+pub const CLOCK_THREAD_CPUTIME_ID: u32 = 3;
+pub const CLOCK_MONOTONIC_RAW: u32 = 4;
+pub const CLOCK_REALTIME_COARSE: u32 = 5;
+pub const CLOCK_MONOTONIC_COARSE: u32 = 6;
+pub const CLOCK_BOOTTIME: u32 = 7;
+pub const CLOCK_REALTIME_ALARM: u32 = 8;
+pub const CLOCK_BOOTTIME_ALARM: u32 = 9;
+pub const CLOCK_TAI: u32 = 11;
+pub const TIMER_ABSTIME: u32 = 1;
+pub const TIME_UTC: u32 = 1;
+pub const _XLOCALE_H: u32 = 1;
+pub const _LIBC_LIMITS_H_: u32 = 1;
+pub const MB_LEN_MAX: u32 = 16;
+pub const _BITS_POSIX1_LIM_H: u32 = 1;
+pub const _POSIX_AIO_LISTIO_MAX: u32 = 2;
+pub const _POSIX_AIO_MAX: u32 = 1;
+pub const _POSIX_ARG_MAX: u32 = 4096;
+pub const _POSIX_CHILD_MAX: u32 = 25;
+pub const _POSIX_DELAYTIMER_MAX: u32 = 32;
+pub const _POSIX_HOST_NAME_MAX: u32 = 255;
+pub const _POSIX_LINK_MAX: u32 = 8;
+pub const _POSIX_LOGIN_NAME_MAX: u32 = 9;
+pub const _POSIX_MAX_CANON: u32 = 255;
+pub const _POSIX_MAX_INPUT: u32 = 255;
+pub const _POSIX_MQ_OPEN_MAX: u32 = 8;
+pub const _POSIX_MQ_PRIO_MAX: u32 = 32;
+pub const _POSIX_NAME_MAX: u32 = 14;
+pub const _POSIX_NGROUPS_MAX: u32 = 8;
+pub const _POSIX_OPEN_MAX: u32 = 20;
+pub const _POSIX_PATH_MAX: u32 = 256;
+pub const _POSIX_PIPE_BUF: u32 = 512;
+pub const _POSIX_RE_DUP_MAX: u32 = 255;
+pub const _POSIX_RTSIG_MAX: u32 = 8;
+pub const _POSIX_SEM_NSEMS_MAX: u32 = 256;
+pub const _POSIX_SEM_VALUE_MAX: u32 = 32767;
+pub const _POSIX_SIGQUEUE_MAX: u32 = 32;
+pub const _POSIX_SSIZE_MAX: u32 = 32767;
+pub const _POSIX_STREAM_MAX: u32 = 8;
+pub const _POSIX_SYMLINK_MAX: u32 = 255;
+pub const _POSIX_SYMLOOP_MAX: u32 = 8;
+pub const _POSIX_TIMER_MAX: u32 = 32;
+pub const _POSIX_TTY_NAME_MAX: u32 = 9;
+pub const _POSIX_TZNAME_MAX: u32 = 6;
+pub const _POSIX_CLOCKRES_MIN: u32 = 20000000;
+pub const NR_OPEN: u32 = 1024;
+pub const NGROUPS_MAX: u32 = 65536;
+pub const ARG_MAX: u32 = 131072;
+pub const LINK_MAX: u32 = 127;
+pub const MAX_CANON: u32 = 255;
+pub const MAX_INPUT: u32 = 255;
+pub const NAME_MAX: u32 = 255;
+pub const PATH_MAX: u32 = 4096;
+pub const PIPE_BUF: u32 = 4096;
+pub const XATTR_NAME_MAX: u32 = 255;
+pub const XATTR_SIZE_MAX: u32 = 65536;
+pub const XATTR_LIST_MAX: u32 = 65536;
+pub const RTSIG_MAX: u32 = 32;
+pub const _POSIX_THREAD_KEYS_MAX: u32 = 128;
+pub const PTHREAD_KEYS_MAX: u32 = 1024;
+pub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: u32 = 4;
+pub const PTHREAD_DESTRUCTOR_ITERATIONS: u32 = 4;
+pub const _POSIX_THREAD_THREADS_MAX: u32 = 64;
+pub const AIO_PRIO_DELTA_MAX: u32 = 20;
+pub const PTHREAD_STACK_MIN: u32 = 16384;
+pub const DELAYTIMER_MAX: u32 = 2147483647;
+pub const TTY_NAME_MAX: u32 = 32;
+pub const LOGIN_NAME_MAX: u32 = 256;
+pub const HOST_NAME_MAX: u32 = 64;
+pub const MQ_PRIO_MAX: u32 = 32768;
+pub const SEM_VALUE_MAX: u32 = 2147483647;
+pub const _BITS_POSIX2_LIM_H: u32 = 1;
+pub const _POSIX2_BC_BASE_MAX: u32 = 99;
+pub const _POSIX2_BC_DIM_MAX: u32 = 2048;
+pub const _POSIX2_BC_SCALE_MAX: u32 = 99;
+pub const _POSIX2_BC_STRING_MAX: u32 = 1000;
+pub const _POSIX2_COLL_WEIGHTS_MAX: u32 = 2;
+pub const _POSIX2_EXPR_NEST_MAX: u32 = 32;
+pub const _POSIX2_LINE_MAX: u32 = 2048;
+pub const _POSIX2_RE_DUP_MAX: u32 = 255;
+pub const _POSIX2_CHARCLASS_NAME_MAX: u32 = 14;
+pub const BC_BASE_MAX: u32 = 99;
+pub const BC_DIM_MAX: u32 = 2048;
+pub const BC_SCALE_MAX: u32 = 99;
+pub const BC_STRING_MAX: u32 = 1000;
+pub const COLL_WEIGHTS_MAX: u32 = 255;
+pub const EXPR_NEST_MAX: u32 = 32;
+pub const LINE_MAX: u32 = 2048;
+pub const CHARCLASS_NAME_MAX: u32 = 2048;
+pub const RE_DUP_MAX: u32 = 32767;
+pub const LIBUSB_API_VERSION: u32 = 16777477;
+pub const LIBUSBX_API_VERSION: u32 = 16777477;
+pub const LIBUSB_DT_DEVICE_SIZE: u32 = 18;
+pub const LIBUSB_DT_CONFIG_SIZE: u32 = 9;
+pub const LIBUSB_DT_INTERFACE_SIZE: u32 = 9;
+pub const LIBUSB_DT_ENDPOINT_SIZE: u32 = 7;
+pub const LIBUSB_DT_ENDPOINT_AUDIO_SIZE: u32 = 9;
+pub const LIBUSB_DT_HUB_NONVAR_SIZE: u32 = 7;
+pub const LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE: u32 = 6;
+pub const LIBUSB_DT_BOS_SIZE: u32 = 5;
+pub const LIBUSB_DT_DEVICE_CAPABILITY_SIZE: u32 = 3;
+pub const LIBUSB_BT_USB_2_0_EXTENSION_SIZE: u32 = 7;
+pub const LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE: u32 = 10;
+pub const LIBUSB_BT_CONTAINER_ID_SIZE: u32 = 20;
+pub const LIBUSB_DT_BOS_MAX_SIZE: u32 = 42;
+pub const LIBUSB_ENDPOINT_ADDRESS_MASK: u32 = 15;
+pub const LIBUSB_ENDPOINT_DIR_MASK: u32 = 128;
+pub const LIBUSB_TRANSFER_TYPE_MASK: u32 = 3;
+pub const LIBUSB_ISO_SYNC_TYPE_MASK: u32 = 12;
+pub const LIBUSB_ISO_USAGE_TYPE_MASK: u32 = 48;
+pub const LIBUSB_ERROR_COUNT: u32 = 14;
+pub const LIBUSB_HOTPLUG_MATCH_ANY: i32 = -1;
+pub type int_least8_t = ::std::os::raw::c_schar;
+pub type int_least16_t = ::std::os::raw::c_short;
+pub type int_least32_t = ::std::os::raw::c_int;
+pub type int_least64_t = ::std::os::raw::c_long;
+pub type uint_least8_t = ::std::os::raw::c_uchar;
+pub type uint_least16_t = ::std::os::raw::c_ushort;
+pub type uint_least32_t = ::std::os::raw::c_uint;
+pub type uint_least64_t = ::std::os::raw::c_ulong;
+pub type int_fast8_t = ::std::os::raw::c_schar;
+pub type int_fast16_t = ::std::os::raw::c_long;
+pub type int_fast32_t = ::std::os::raw::c_long;
+pub type int_fast64_t = ::std::os::raw::c_long;
+pub type uint_fast8_t = ::std::os::raw::c_uchar;
+pub type uint_fast16_t = ::std::os::raw::c_ulong;
+pub type uint_fast32_t = ::std::os::raw::c_ulong;
+pub type uint_fast64_t = ::std::os::raw::c_ulong;
+pub type intmax_t = ::std::os::raw::c_long;
+pub type uintmax_t = ::std::os::raw::c_ulong;
+pub type __u_char = ::std::os::raw::c_uchar;
+pub type __u_short = ::std::os::raw::c_ushort;
+pub type __u_int = ::std::os::raw::c_uint;
+pub type __u_long = ::std::os::raw::c_ulong;
+pub type __int8_t = ::std::os::raw::c_schar;
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __int16_t = ::std::os::raw::c_short;
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __int32_t = ::std::os::raw::c_int;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __int64_t = ::std::os::raw::c_long;
+pub type __uint64_t = ::std::os::raw::c_ulong;
+pub type __quad_t = ::std::os::raw::c_long;
+pub type __u_quad_t = ::std::os::raw::c_ulong;
+pub type __dev_t = ::std::os::raw::c_ulong;
+pub type __uid_t = ::std::os::raw::c_uint;
+pub type __gid_t = ::std::os::raw::c_uint;
+pub type __ino_t = ::std::os::raw::c_ulong;
+pub type __ino64_t = ::std::os::raw::c_ulong;
+pub type __mode_t = ::std::os::raw::c_uint;
+pub type __nlink_t = ::std::os::raw::c_ulong;
+pub type __off_t = ::std::os::raw::c_long;
+pub type __off64_t = ::std::os::raw::c_long;
+pub type __pid_t = ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __fsid_t {
+    pub __val: [::std::os::raw::c_int; 2usize],
+}
+#[test]
+fn bindgen_test_layout___fsid_t() {
+    assert_eq!(
+        ::std::mem::size_of::<__fsid_t>(),
+        8usize,
+        concat!("Size of: ", stringify!(__fsid_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<__fsid_t>(),
+        4usize,
+        concat!("Alignment of ", stringify!(__fsid_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__fsid_t),
+            "::",
+            stringify!(__val)
+        )
+    );
+}
+pub type __clock_t = ::std::os::raw::c_long;
+pub type __rlim_t = ::std::os::raw::c_ulong;
+pub type __rlim64_t = ::std::os::raw::c_ulong;
+pub type __id_t = ::std::os::raw::c_uint;
+pub type __time_t = ::std::os::raw::c_long;
+pub type __useconds_t = ::std::os::raw::c_uint;
+pub type __suseconds_t = ::std::os::raw::c_long;
+pub type __daddr_t = ::std::os::raw::c_int;
+pub type __key_t = ::std::os::raw::c_int;
+pub type __clockid_t = ::std::os::raw::c_int;
+pub type __timer_t = *mut ::std::os::raw::c_void;
+pub type __blksize_t = ::std::os::raw::c_long;
+pub type __blkcnt_t = ::std::os::raw::c_long;
+pub type __blkcnt64_t = ::std::os::raw::c_long;
+pub type __fsblkcnt_t = ::std::os::raw::c_ulong;
+pub type __fsblkcnt64_t = ::std::os::raw::c_ulong;
+pub type __fsfilcnt_t = ::std::os::raw::c_ulong;
+pub type __fsfilcnt64_t = ::std::os::raw::c_ulong;
+pub type __fsword_t = ::std::os::raw::c_long;
+pub type __ssize_t = ::std::os::raw::c_long;
+pub type __syscall_slong_t = ::std::os::raw::c_long;
+pub type __syscall_ulong_t = ::std::os::raw::c_ulong;
+pub type __loff_t = __off64_t;
+pub type __qaddr_t = *mut __quad_t;
+pub type __caddr_t = *mut ::std::os::raw::c_char;
+pub type __intptr_t = ::std::os::raw::c_long;
+pub type __socklen_t = ::std::os::raw::c_uint;
+pub type u_char = __u_char;
+pub type u_short = __u_short;
+pub type u_int = __u_int;
+pub type u_long = __u_long;
+pub type quad_t = __quad_t;
+pub type u_quad_t = __u_quad_t;
+pub type fsid_t = __fsid_t;
+pub type loff_t = __loff_t;
+pub type ino_t = __ino_t;
+pub type dev_t = __dev_t;
+pub type gid_t = __gid_t;
+pub type mode_t = __mode_t;
+pub type nlink_t = __nlink_t;
+pub type uid_t = __uid_t;
+pub type off_t = __off_t;
+pub type pid_t = __pid_t;
+pub type id_t = __id_t;
+pub type daddr_t = __daddr_t;
+pub type caddr_t = __caddr_t;
+pub type key_t = __key_t;
+pub type clock_t = __clock_t;
+pub type time_t = __time_t;
+pub type clockid_t = __clockid_t;
+pub type timer_t = __timer_t;
+pub type ulong = ::std::os::raw::c_ulong;
+pub type ushort = ::std::os::raw::c_ushort;
+pub type uint = ::std::os::raw::c_uint;
+pub type u_int8_t = ::std::os::raw::c_uchar;
+pub type u_int16_t = ::std::os::raw::c_ushort;
+pub type u_int32_t = ::std::os::raw::c_uint;
+pub type u_int64_t = ::std::os::raw::c_ulong;
+pub type register_t = ::std::os::raw::c_long;
+pub type __sig_atomic_t = ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __sigset_t {
+    pub __val: [::std::os::raw::c_ulong; 16usize],
+}
+#[test]
+fn bindgen_test_layout___sigset_t() {
+    assert_eq!(
+        ::std::mem::size_of::<__sigset_t>(),
+        128usize,
+        concat!("Size of: ", stringify!(__sigset_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<__sigset_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(__sigset_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__sigset_t>())).__val as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__sigset_t),
+            "::",
+            stringify!(__val)
+        )
+    );
+}
+pub type sigset_t = __sigset_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct timespec {
+    pub tv_sec: __time_t,
+    pub tv_nsec: __syscall_slong_t,
+}
+#[test]
+fn bindgen_test_layout_timespec() {
+    assert_eq!(
+        ::std::mem::size_of::<timespec>(),
+        16usize,
+        concat!("Size of: ", stringify!(timespec))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<timespec>(),
+        8usize,
+        concat!("Alignment of ", stringify!(timespec))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<timespec>())).tv_sec as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(timespec),
+            "::",
+            stringify!(tv_sec)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<timespec>())).tv_nsec as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(timespec),
+            "::",
+            stringify!(tv_nsec)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct timeval {
+    pub tv_sec: __time_t,
+    pub tv_usec: __suseconds_t,
+}
+#[test]
+fn bindgen_test_layout_timeval() {
+    assert_eq!(
+        ::std::mem::size_of::<timeval>(),
+        16usize,
+        concat!("Size of: ", stringify!(timeval))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<timeval>(),
+        8usize,
+        concat!("Alignment of ", stringify!(timeval))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<timeval>())).tv_sec as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(timeval),
+            "::",
+            stringify!(tv_sec)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<timeval>())).tv_usec as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(timeval),
+            "::",
+            stringify!(tv_usec)
+        )
+    );
+}
+pub type suseconds_t = __suseconds_t;
+pub type __fd_mask = ::std::os::raw::c_long;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct fd_set {
+    pub __fds_bits: [__fd_mask; 16usize],
+}
+#[test]
+fn bindgen_test_layout_fd_set() {
+    assert_eq!(
+        ::std::mem::size_of::<fd_set>(),
+        128usize,
+        concat!("Size of: ", stringify!(fd_set))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<fd_set>(),
+        8usize,
+        concat!("Alignment of ", stringify!(fd_set))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<fd_set>())).__fds_bits as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(fd_set),
+            "::",
+            stringify!(__fds_bits)
+        )
+    );
+}
+pub type fd_mask = __fd_mask;
+extern "C" {
+    pub fn select(
+        __nfds: ::std::os::raw::c_int,
+        __readfds: *mut fd_set,
+        __writefds: *mut fd_set,
+        __exceptfds: *mut fd_set,
+        __timeout: *mut timeval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn pselect(
+        __nfds: ::std::os::raw::c_int,
+        __readfds: *mut fd_set,
+        __writefds: *mut fd_set,
+        __exceptfds: *mut fd_set,
+        __timeout: *const timespec,
+        __sigmask: *const __sigset_t,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn gnu_dev_major(__dev: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_uint;
+}
+extern "C" {
+    pub fn gnu_dev_minor(__dev: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_uint;
+}
+extern "C" {
+    pub fn gnu_dev_makedev(
+        __major: ::std::os::raw::c_uint,
+        __minor: ::std::os::raw::c_uint,
+    ) -> ::std::os::raw::c_ulonglong;
+}
+pub type blksize_t = __blksize_t;
+pub type blkcnt_t = __blkcnt_t;
+pub type fsblkcnt_t = __fsblkcnt_t;
+pub type fsfilcnt_t = __fsfilcnt_t;
+pub type pthread_t = ::std::os::raw::c_ulong;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_attr_t {
+    pub __size: [::std::os::raw::c_char; 56usize],
+    pub __align: ::std::os::raw::c_long,
+    _bindgen_union_align: [u64; 7usize],
+}
+#[test]
+fn bindgen_test_layout_pthread_attr_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_attr_t>(),
+        56usize,
+        concat!("Size of: ", stringify!(pthread_attr_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_attr_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_attr_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_attr_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_attr_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_attr_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_attr_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __pthread_internal_list {
+    pub __prev: *mut __pthread_internal_list,
+    pub __next: *mut __pthread_internal_list,
+}
+#[test]
+fn bindgen_test_layout___pthread_internal_list() {
+    assert_eq!(
+        ::std::mem::size_of::<__pthread_internal_list>(),
+        16usize,
+        concat!("Size of: ", stringify!(__pthread_internal_list))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<__pthread_internal_list>(),
+        8usize,
+        concat!("Alignment of ", stringify!(__pthread_internal_list))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__pthread_internal_list>())).__prev as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__pthread_internal_list),
+            "::",
+            stringify!(__prev)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__pthread_internal_list>())).__next as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__pthread_internal_list),
+            "::",
+            stringify!(__next)
+        )
+    );
+}
+pub type __pthread_list_t = __pthread_internal_list;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_mutex_t {
+    pub __data: pthread_mutex_t___pthread_mutex_s,
+    pub __size: [::std::os::raw::c_char; 40usize],
+    pub __align: ::std::os::raw::c_long,
+    _bindgen_union_align: [u64; 5usize],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct pthread_mutex_t___pthread_mutex_s {
+    pub __lock: ::std::os::raw::c_int,
+    pub __count: ::std::os::raw::c_uint,
+    pub __owner: ::std::os::raw::c_int,
+    pub __nusers: ::std::os::raw::c_uint,
+    pub __kind: ::std::os::raw::c_int,
+    pub __spins: ::std::os::raw::c_short,
+    pub __elision: ::std::os::raw::c_short,
+    pub __list: __pthread_list_t,
+}
+#[test]
+fn bindgen_test_layout_pthread_mutex_t___pthread_mutex_s() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_mutex_t___pthread_mutex_s>(),
+        40usize,
+        concat!("Size of: ", stringify!(pthread_mutex_t___pthread_mutex_s))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_mutex_t___pthread_mutex_s>(),
+        8usize,
+        concat!(
+            "Alignment of ",
+            stringify!(pthread_mutex_t___pthread_mutex_s)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__lock as *const _
+                as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__lock)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__count as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__count)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__owner as *const _
+                as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__owner)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__nusers as *const _
+                as usize
+        },
+        12usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__nusers)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__kind as *const _
+                as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__kind)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__spins as *const _
+                as usize
+        },
+        20usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__spins)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__elision as *const _
+                as usize
+        },
+        22usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__elision)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_mutex_t___pthread_mutex_s>())).__list as *const _
+                as usize
+        },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t___pthread_mutex_s),
+            "::",
+            stringify!(__list)
+        )
+    );
+}
+#[test]
+fn bindgen_test_layout_pthread_mutex_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_mutex_t>(),
+        40usize,
+        concat!("Size of: ", stringify!(pthread_mutex_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_mutex_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_mutex_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_mutex_t>())).__data as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t),
+            "::",
+            stringify!(__data)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_mutex_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_mutex_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutex_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_mutexattr_t {
+    pub __size: [::std::os::raw::c_char; 4usize],
+    pub __align: ::std::os::raw::c_int,
+    _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_pthread_mutexattr_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_mutexattr_t>(),
+        4usize,
+        concat!("Size of: ", stringify!(pthread_mutexattr_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_mutexattr_t>(),
+        4usize,
+        concat!("Alignment of ", stringify!(pthread_mutexattr_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_mutexattr_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutexattr_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_mutexattr_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_mutexattr_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_cond_t {
+    pub __data: pthread_cond_t__bindgen_ty_1,
+    pub __size: [::std::os::raw::c_char; 48usize],
+    pub __align: ::std::os::raw::c_longlong,
+    _bindgen_union_align: [u64; 6usize],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct pthread_cond_t__bindgen_ty_1 {
+    pub __lock: ::std::os::raw::c_int,
+    pub __futex: ::std::os::raw::c_uint,
+    pub __total_seq: ::std::os::raw::c_ulonglong,
+    pub __wakeup_seq: ::std::os::raw::c_ulonglong,
+    pub __woken_seq: ::std::os::raw::c_ulonglong,
+    pub __mutex: *mut ::std::os::raw::c_void,
+    pub __nwaiters: ::std::os::raw::c_uint,
+    pub __broadcast_seq: ::std::os::raw::c_uint,
+}
+#[test]
+fn bindgen_test_layout_pthread_cond_t__bindgen_ty_1() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_cond_t__bindgen_ty_1>(),
+        48usize,
+        concat!("Size of: ", stringify!(pthread_cond_t__bindgen_ty_1))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_cond_t__bindgen_ty_1>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_cond_t__bindgen_ty_1))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__lock as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__lock)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__futex as *const _ as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__futex)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__total_seq as *const _
+                as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__total_seq)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__wakeup_seq as *const _
+                as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__wakeup_seq)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__woken_seq as *const _
+                as usize
+        },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__woken_seq)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__mutex as *const _ as usize
+        },
+        32usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__mutex)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__nwaiters as *const _ as usize
+        },
+        40usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__nwaiters)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_cond_t__bindgen_ty_1>())).__broadcast_seq as *const _
+                as usize
+        },
+        44usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t__bindgen_ty_1),
+            "::",
+            stringify!(__broadcast_seq)
+        )
+    );
+}
+#[test]
+fn bindgen_test_layout_pthread_cond_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_cond_t>(),
+        48usize,
+        concat!("Size of: ", stringify!(pthread_cond_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_cond_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_cond_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_cond_t>())).__data as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t),
+            "::",
+            stringify!(__data)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_cond_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_cond_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_cond_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_condattr_t {
+    pub __size: [::std::os::raw::c_char; 4usize],
+    pub __align: ::std::os::raw::c_int,
+    _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_pthread_condattr_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_condattr_t>(),
+        4usize,
+        concat!("Size of: ", stringify!(pthread_condattr_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_condattr_t>(),
+        4usize,
+        concat!("Alignment of ", stringify!(pthread_condattr_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_condattr_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_condattr_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_condattr_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_condattr_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+pub type pthread_key_t = ::std::os::raw::c_uint;
+pub type pthread_once_t = ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_rwlock_t {
+    pub __data: pthread_rwlock_t__bindgen_ty_1,
+    pub __size: [::std::os::raw::c_char; 56usize],
+    pub __align: ::std::os::raw::c_long,
+    _bindgen_union_align: [u64; 7usize],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct pthread_rwlock_t__bindgen_ty_1 {
+    pub __lock: ::std::os::raw::c_int,
+    pub __nr_readers: ::std::os::raw::c_uint,
+    pub __readers_wakeup: ::std::os::raw::c_uint,
+    pub __writer_wakeup: ::std::os::raw::c_uint,
+    pub __nr_readers_queued: ::std::os::raw::c_uint,
+    pub __nr_writers_queued: ::std::os::raw::c_uint,
+    pub __writer: ::std::os::raw::c_int,
+    pub __shared: ::std::os::raw::c_int,
+    pub __rwelision: ::std::os::raw::c_schar,
+    pub __pad1: [::std::os::raw::c_uchar; 7usize],
+    pub __pad2: ::std::os::raw::c_ulong,
+    pub __flags: ::std::os::raw::c_uint,
+}
+#[test]
+fn bindgen_test_layout_pthread_rwlock_t__bindgen_ty_1() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_rwlock_t__bindgen_ty_1>(),
+        56usize,
+        concat!("Size of: ", stringify!(pthread_rwlock_t__bindgen_ty_1))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_rwlock_t__bindgen_ty_1>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_rwlock_t__bindgen_ty_1))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__lock as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__lock)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__nr_readers as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__nr_readers)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__readers_wakeup as *const _
+                as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__readers_wakeup)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__writer_wakeup as *const _
+                as usize
+        },
+        12usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__writer_wakeup)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__nr_readers_queued
+                as *const _ as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__nr_readers_queued)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__nr_writers_queued
+                as *const _ as usize
+        },
+        20usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__nr_writers_queued)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__writer as *const _ as usize
+        },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__writer)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__shared as *const _ as usize
+        },
+        28usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__shared)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__rwelision as *const _
+                as usize
+        },
+        32usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__rwelision)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__pad1 as *const _ as usize
+        },
+        33usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__pad1)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__pad2 as *const _ as usize
+        },
+        40usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__pad2)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<pthread_rwlock_t__bindgen_ty_1>())).__flags as *const _ as usize
+        },
+        48usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t__bindgen_ty_1),
+            "::",
+            stringify!(__flags)
+        )
+    );
+}
+#[test]
+fn bindgen_test_layout_pthread_rwlock_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_rwlock_t>(),
+        56usize,
+        concat!("Size of: ", stringify!(pthread_rwlock_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_rwlock_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_rwlock_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_rwlock_t>())).__data as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t),
+            "::",
+            stringify!(__data)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_rwlock_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_rwlock_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlock_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_rwlockattr_t {
+    pub __size: [::std::os::raw::c_char; 8usize],
+    pub __align: ::std::os::raw::c_long,
+    _bindgen_union_align: u64,
+}
+#[test]
+fn bindgen_test_layout_pthread_rwlockattr_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_rwlockattr_t>(),
+        8usize,
+        concat!("Size of: ", stringify!(pthread_rwlockattr_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_rwlockattr_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_rwlockattr_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_rwlockattr_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlockattr_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_rwlockattr_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_rwlockattr_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+pub type pthread_spinlock_t = ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_barrier_t {
+    pub __size: [::std::os::raw::c_char; 32usize],
+    pub __align: ::std::os::raw::c_long,
+    _bindgen_union_align: [u64; 4usize],
+}
+#[test]
+fn bindgen_test_layout_pthread_barrier_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_barrier_t>(),
+        32usize,
+        concat!("Size of: ", stringify!(pthread_barrier_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_barrier_t>(),
+        8usize,
+        concat!("Alignment of ", stringify!(pthread_barrier_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_barrier_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_barrier_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_barrier_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_barrier_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union pthread_barrierattr_t {
+    pub __size: [::std::os::raw::c_char; 4usize],
+    pub __align: ::std::os::raw::c_int,
+    _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_pthread_barrierattr_t() {
+    assert_eq!(
+        ::std::mem::size_of::<pthread_barrierattr_t>(),
+        4usize,
+        concat!("Size of: ", stringify!(pthread_barrierattr_t))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<pthread_barrierattr_t>(),
+        4usize,
+        concat!("Alignment of ", stringify!(pthread_barrierattr_t))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_barrierattr_t>())).__size as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_barrierattr_t),
+            "::",
+            stringify!(__size)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<pthread_barrierattr_t>())).__align as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(pthread_barrierattr_t),
+            "::",
+            stringify!(__align)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct timezone {
+    pub tz_minuteswest: ::std::os::raw::c_int,
+    pub tz_dsttime: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_timezone() {
+    assert_eq!(
+        ::std::mem::size_of::<timezone>(),
+        8usize,
+        concat!("Size of: ", stringify!(timezone))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<timezone>(),
+        4usize,
+        concat!("Alignment of ", stringify!(timezone))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<timezone>())).tz_minuteswest as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(timezone),
+            "::",
+            stringify!(tz_minuteswest)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<timezone>())).tz_dsttime as *const _ as usize },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(timezone),
+            "::",
+            stringify!(tz_dsttime)
+        )
+    );
+}
+pub type __timezone_ptr_t = *mut timezone;
+extern "C" {
+    pub fn gettimeofday(__tv: *mut timeval, __tz: __timezone_ptr_t) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn settimeofday(__tv: *const timeval, __tz: *const timezone) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn adjtime(__delta: *const timeval, __olddelta: *mut timeval) -> ::std::os::raw::c_int;
+}
+pub const ITIMER_REAL: __itimer_which = 0;
+pub const ITIMER_VIRTUAL: __itimer_which = 1;
+pub const ITIMER_PROF: __itimer_which = 2;
+pub type __itimer_which = u32;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct itimerval {
+    pub it_interval: timeval,
+    pub it_value: timeval,
+}
+#[test]
+fn bindgen_test_layout_itimerval() {
+    assert_eq!(
+        ::std::mem::size_of::<itimerval>(),
+        32usize,
+        concat!("Size of: ", stringify!(itimerval))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<itimerval>(),
+        8usize,
+        concat!("Alignment of ", stringify!(itimerval))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<itimerval>())).it_interval as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(itimerval),
+            "::",
+            stringify!(it_interval)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<itimerval>())).it_value as *const _ as usize },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(itimerval),
+            "::",
+            stringify!(it_value)
+        )
+    );
+}
+pub type __itimer_which_t = ::std::os::raw::c_int;
+extern "C" {
+    pub fn getitimer(__which: __itimer_which_t, __value: *mut itimerval) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn setitimer(
+        __which: __itimer_which_t,
+        __new: *const itimerval,
+        __old: *mut itimerval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn utimes(
+        __file: *const ::std::os::raw::c_char,
+        __tvp: *const timeval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn lutimes(
+        __file: *const ::std::os::raw::c_char,
+        __tvp: *const timeval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn futimes(__fd: ::std::os::raw::c_int, __tvp: *const timeval) -> ::std::os::raw::c_int;
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct tm {
+    pub tm_sec: ::std::os::raw::c_int,
+    pub tm_min: ::std::os::raw::c_int,
+    pub tm_hour: ::std::os::raw::c_int,
+    pub tm_mday: ::std::os::raw::c_int,
+    pub tm_mon: ::std::os::raw::c_int,
+    pub tm_year: ::std::os::raw::c_int,
+    pub tm_wday: ::std::os::raw::c_int,
+    pub tm_yday: ::std::os::raw::c_int,
+    pub tm_isdst: ::std::os::raw::c_int,
+    pub tm_gmtoff: ::std::os::raw::c_long,
+    pub tm_zone: *const ::std::os::raw::c_char,
+}
+#[test]
+fn bindgen_test_layout_tm() {
+    assert_eq!(
+        ::std::mem::size_of::<tm>(),
+        56usize,
+        concat!("Size of: ", stringify!(tm))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<tm>(),
+        8usize,
+        concat!("Alignment of ", stringify!(tm))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_sec as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_sec)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_min as *const _ as usize },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_min)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_hour as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_hour)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_mday as *const _ as usize },
+        12usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_mday)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_mon as *const _ as usize },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_mon)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_year as *const _ as usize },
+        20usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_year)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_wday as *const _ as usize },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_wday)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_yday as *const _ as usize },
+        28usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_yday)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_isdst as *const _ as usize },
+        32usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_isdst)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_gmtoff as *const _ as usize },
+        40usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_gmtoff)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<tm>())).tm_zone as *const _ as usize },
+        48usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(tm),
+            "::",
+            stringify!(tm_zone)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct itimerspec {
+    pub it_interval: timespec,
+    pub it_value: timespec,
+}
+#[test]
+fn bindgen_test_layout_itimerspec() {
+    assert_eq!(
+        ::std::mem::size_of::<itimerspec>(),
+        32usize,
+        concat!("Size of: ", stringify!(itimerspec))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<itimerspec>(),
+        8usize,
+        concat!("Alignment of ", stringify!(itimerspec))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<itimerspec>())).it_interval as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(itimerspec),
+            "::",
+            stringify!(it_interval)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<itimerspec>())).it_value as *const _ as usize },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(itimerspec),
+            "::",
+            stringify!(it_value)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct sigevent {
+    _unused: [u8; 0],
+}
+extern "C" {
+    pub fn clock() -> clock_t;
+}
+extern "C" {
+    pub fn time(__timer: *mut time_t) -> time_t;
+}
+extern "C" {
+    pub fn difftime(__time1: time_t, __time0: time_t) -> f64;
+}
+extern "C" {
+    pub fn mktime(__tp: *mut tm) -> time_t;
+}
+extern "C" {
+    pub fn strftime(
+        __s: *mut ::std::os::raw::c_char,
+        __maxsize: usize,
+        __format: *const ::std::os::raw::c_char,
+        __tp: *const tm,
+    ) -> usize;
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __locale_struct {
+    pub __locales: [*mut __locale_data; 13usize],
+    pub __ctype_b: *const ::std::os::raw::c_ushort,
+    pub __ctype_tolower: *const ::std::os::raw::c_int,
+    pub __ctype_toupper: *const ::std::os::raw::c_int,
+    pub __names: [*const ::std::os::raw::c_char; 13usize],
+}
+#[test]
+fn bindgen_test_layout___locale_struct() {
+    assert_eq!(
+        ::std::mem::size_of::<__locale_struct>(),
+        232usize,
+        concat!("Size of: ", stringify!(__locale_struct))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<__locale_struct>(),
+        8usize,
+        concat!("Alignment of ", stringify!(__locale_struct))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__locale_struct>())).__locales as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__locale_struct),
+            "::",
+            stringify!(__locales)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__locale_struct>())).__ctype_b as *const _ as usize },
+        104usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__locale_struct),
+            "::",
+            stringify!(__ctype_b)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__locale_struct>())).__ctype_tolower as *const _ as usize },
+        112usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__locale_struct),
+            "::",
+            stringify!(__ctype_tolower)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__locale_struct>())).__ctype_toupper as *const _ as usize },
+        120usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__locale_struct),
+            "::",
+            stringify!(__ctype_toupper)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<__locale_struct>())).__names as *const _ as usize },
+        128usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(__locale_struct),
+            "::",
+            stringify!(__names)
+        )
+    );
+}
+pub type __locale_t = *mut __locale_struct;
+pub type locale_t = __locale_t;
+extern "C" {
+    pub fn strftime_l(
+        __s: *mut ::std::os::raw::c_char,
+        __maxsize: usize,
+        __format: *const ::std::os::raw::c_char,
+        __tp: *const tm,
+        __loc: __locale_t,
+    ) -> usize;
+}
+extern "C" {
+    pub fn gmtime(__timer: *const time_t) -> *mut tm;
+}
+extern "C" {
+    pub fn localtime(__timer: *const time_t) -> *mut tm;
+}
+extern "C" {
+    pub fn gmtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm;
+}
+extern "C" {
+    pub fn localtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm;
+}
+extern "C" {
+    pub fn asctime(__tp: *const tm) -> *mut ::std::os::raw::c_char;
+}
+extern "C" {
+    pub fn ctime(__timer: *const time_t) -> *mut ::std::os::raw::c_char;
+}
+extern "C" {
+    pub fn asctime_r(
+        __tp: *const tm,
+        __buf: *mut ::std::os::raw::c_char,
+    ) -> *mut ::std::os::raw::c_char;
+}
+extern "C" {
+    pub fn ctime_r(
+        __timer: *const time_t,
+        __buf: *mut ::std::os::raw::c_char,
+    ) -> *mut ::std::os::raw::c_char;
+}
+extern "C" {
+    #[link_name = "\u{1}__tzname"]
+    pub static mut __tzname: [*mut ::std::os::raw::c_char; 2usize];
+}
+extern "C" {
+    #[link_name = "\u{1}__daylight"]
+    pub static mut __daylight: ::std::os::raw::c_int;
+}
+extern "C" {
+    #[link_name = "\u{1}__timezone"]
+    pub static mut __timezone: ::std::os::raw::c_long;
+}
+extern "C" {
+    #[link_name = "\u{1}tzname"]
+    pub static mut tzname: [*mut ::std::os::raw::c_char; 2usize];
+}
+extern "C" {
+    pub fn tzset();
+}
+extern "C" {
+    #[link_name = "\u{1}daylight"]
+    pub static mut daylight: ::std::os::raw::c_int;
+}
+extern "C" {
+    #[link_name = "\u{1}timezone"]
+    pub static mut timezone: ::std::os::raw::c_long;
+}
+extern "C" {
+    pub fn stime(__when: *const time_t) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timegm(__tp: *mut tm) -> time_t;
+}
+extern "C" {
+    pub fn timelocal(__tp: *mut tm) -> time_t;
+}
+extern "C" {
+    pub fn dysize(__year: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn nanosleep(
+        __requested_time: *const timespec,
+        __remaining: *mut timespec,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn clock_getres(__clock_id: clockid_t, __res: *mut timespec) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut timespec) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn clock_settime(__clock_id: clockid_t, __tp: *const timespec) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn clock_nanosleep(
+        __clock_id: clockid_t,
+        __flags: ::std::os::raw::c_int,
+        __req: *const timespec,
+        __rem: *mut timespec,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn clock_getcpuclockid(__pid: pid_t, __clock_id: *mut clockid_t) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timer_create(
+        __clock_id: clockid_t,
+        __evp: *mut sigevent,
+        __timerid: *mut timer_t,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timer_delete(__timerid: timer_t) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timer_settime(
+        __timerid: timer_t,
+        __flags: ::std::os::raw::c_int,
+        __value: *const itimerspec,
+        __ovalue: *mut itimerspec,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timer_gettime(__timerid: timer_t, __value: *mut itimerspec) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timer_getoverrun(__timerid: timer_t) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn timespec_get(
+        __ts: *mut timespec,
+        __base: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+/// In the context of a \ref libusb_device_descriptor "device descriptor",
+/// this bDeviceClass value indicates that each interface specifies its
+/// own class information and all interfaces operate independently.
+pub const LIBUSB_CLASS_PER_INTERFACE: libusb_class_code = 0;
+/// Audio class
+pub const LIBUSB_CLASS_AUDIO: libusb_class_code = 1;
+/// Communications class
+pub const LIBUSB_CLASS_COMM: libusb_class_code = 2;
+/// Human Interface Device class
+pub const LIBUSB_CLASS_HID: libusb_class_code = 3;
+/// Physical
+pub const LIBUSB_CLASS_PHYSICAL: libusb_class_code = 5;
+/// Printer class
+pub const LIBUSB_CLASS_PRINTER: libusb_class_code = 7;
+/// Image class
+pub const LIBUSB_CLASS_PTP: libusb_class_code = 6;
+/// Image class
+pub const LIBUSB_CLASS_IMAGE: libusb_class_code = 6;
+/// Mass storage class
+pub const LIBUSB_CLASS_MASS_STORAGE: libusb_class_code = 8;
+/// Hub class
+pub const LIBUSB_CLASS_HUB: libusb_class_code = 9;
+/// Data class
+pub const LIBUSB_CLASS_DATA: libusb_class_code = 10;
+/// Smart Card
+pub const LIBUSB_CLASS_SMART_CARD: libusb_class_code = 11;
+/// Content Security
+pub const LIBUSB_CLASS_CONTENT_SECURITY: libusb_class_code = 13;
+/// Video
+pub const LIBUSB_CLASS_VIDEO: libusb_class_code = 14;
+/// Personal Healthcare
+pub const LIBUSB_CLASS_PERSONAL_HEALTHCARE: libusb_class_code = 15;
+/// Diagnostic Device
+pub const LIBUSB_CLASS_DIAGNOSTIC_DEVICE: libusb_class_code = 220;
+/// Wireless class
+pub const LIBUSB_CLASS_WIRELESS: libusb_class_code = 224;
+/// Application class
+pub const LIBUSB_CLASS_APPLICATION: libusb_class_code = 254;
+/// Class is vendor-specific
+pub const LIBUSB_CLASS_VENDOR_SPEC: libusb_class_code = 255;
+/// \ingroup libusb_desc
+/// Device and/or Interface Class codes
+pub type libusb_class_code = u32;
+/// Device descriptor. See libusb_device_descriptor.
+pub const LIBUSB_DT_DEVICE: libusb_descriptor_type = 1;
+/// Configuration descriptor. See libusb_config_descriptor.
+pub const LIBUSB_DT_CONFIG: libusb_descriptor_type = 2;
+/// String descriptor
+pub const LIBUSB_DT_STRING: libusb_descriptor_type = 3;
+/// Interface descriptor. See libusb_interface_descriptor.
+pub const LIBUSB_DT_INTERFACE: libusb_descriptor_type = 4;
+/// Endpoint descriptor. See libusb_endpoint_descriptor.
+pub const LIBUSB_DT_ENDPOINT: libusb_descriptor_type = 5;
+/// BOS descriptor
+pub const LIBUSB_DT_BOS: libusb_descriptor_type = 15;
+/// Device Capability descriptor
+pub const LIBUSB_DT_DEVICE_CAPABILITY: libusb_descriptor_type = 16;
+/// HID descriptor
+pub const LIBUSB_DT_HID: libusb_descriptor_type = 33;
+/// HID report descriptor
+pub const LIBUSB_DT_REPORT: libusb_descriptor_type = 34;
+/// Physical descriptor
+pub const LIBUSB_DT_PHYSICAL: libusb_descriptor_type = 35;
+/// Hub descriptor
+pub const LIBUSB_DT_HUB: libusb_descriptor_type = 41;
+/// SuperSpeed Hub descriptor
+pub const LIBUSB_DT_SUPERSPEED_HUB: libusb_descriptor_type = 42;
+/// SuperSpeed Endpoint Companion descriptor
+pub const LIBUSB_DT_SS_ENDPOINT_COMPANION: libusb_descriptor_type = 48;
+/// \ingroup libusb_desc
+/// Descriptor types as defined by the USB specification.
+pub type libusb_descriptor_type = u32;
+/// In: device-to-host
+pub const LIBUSB_ENDPOINT_IN: libusb_endpoint_direction = 128;
+/// Out: host-to-device
+pub const LIBUSB_ENDPOINT_OUT: libusb_endpoint_direction = 0;
+/// \ingroup libusb_desc
+/// Endpoint direction. Values for bit 7 of the
+/// \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme.
+pub type libusb_endpoint_direction = u32;
+/// Control endpoint
+pub const LIBUSB_TRANSFER_TYPE_CONTROL: libusb_transfer_type = 0;
+/// Isochronous endpoint
+pub const LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: libusb_transfer_type = 1;
+/// Bulk endpoint
+pub const LIBUSB_TRANSFER_TYPE_BULK: libusb_transfer_type = 2;
+/// Interrupt endpoint
+pub const LIBUSB_TRANSFER_TYPE_INTERRUPT: libusb_transfer_type = 3;
+/// Stream endpoint
+pub const LIBUSB_TRANSFER_TYPE_BULK_STREAM: libusb_transfer_type = 4;
+/// \ingroup libusb_desc
+/// Endpoint transfer type. Values for bits 0:1 of the
+/// \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field.
+pub type libusb_transfer_type = u32;
+/// Request status of the specific recipient
+pub const LIBUSB_REQUEST_GET_STATUS: libusb_standard_request = 0;
+/// Clear or disable a specific feature
+pub const LIBUSB_REQUEST_CLEAR_FEATURE: libusb_standard_request = 1;
+/// Set or enable a specific feature
+pub const LIBUSB_REQUEST_SET_FEATURE: libusb_standard_request = 3;
+/// Set device address for all future accesses
+pub const LIBUSB_REQUEST_SET_ADDRESS: libusb_standard_request = 5;
+/// Get the specified descriptor
+pub const LIBUSB_REQUEST_GET_DESCRIPTOR: libusb_standard_request = 6;
+/// Used to update existing descriptors or add new descriptors
+pub const LIBUSB_REQUEST_SET_DESCRIPTOR: libusb_standard_request = 7;
+/// Get the current device configuration value
+pub const LIBUSB_REQUEST_GET_CONFIGURATION: libusb_standard_request = 8;
+/// Set device configuration
+pub const LIBUSB_REQUEST_SET_CONFIGURATION: libusb_standard_request = 9;
+/// Return the selected alternate setting for the specified interface
+pub const LIBUSB_REQUEST_GET_INTERFACE: libusb_standard_request = 10;
+/// Select an alternate interface for the specified interface
+pub const LIBUSB_REQUEST_SET_INTERFACE: libusb_standard_request = 11;
+/// Set then report an endpoint's synchronization frame
+pub const LIBUSB_REQUEST_SYNCH_FRAME: libusb_standard_request = 12;
+/// Sets both the U1 and U2 Exit Latency
+pub const LIBUSB_REQUEST_SET_SEL: libusb_standard_request = 48;
+/// Delay from the time a host transmits a packet to the time it is
+/// received by the device.
+pub const LIBUSB_SET_ISOCH_DELAY: libusb_standard_request = 49;
+/// \ingroup libusb_misc
+/// Standard requests, as defined in table 9-5 of the USB 3.0 specifications
+pub type libusb_standard_request = u32;
+/// Standard
+pub const LIBUSB_REQUEST_TYPE_STANDARD: libusb_request_type = 0;
+/// Class
+pub const LIBUSB_REQUEST_TYPE_CLASS: libusb_request_type = 32;
+/// Vendor
+pub const LIBUSB_REQUEST_TYPE_VENDOR: libusb_request_type = 64;
+/// Reserved
+pub const LIBUSB_REQUEST_TYPE_RESERVED: libusb_request_type = 96;
+/// \ingroup libusb_misc
+/// Request type bits of the
+/// \ref libusb_control_setup::bmRequestType "bmRequestType" field in control
+/// transfers.
+pub type libusb_request_type = u32;
+/// Device
+pub const LIBUSB_RECIPIENT_DEVICE: libusb_request_recipient = 0;
+/// Interface
+pub const LIBUSB_RECIPIENT_INTERFACE: libusb_request_recipient = 1;
+/// Endpoint
+pub const LIBUSB_RECIPIENT_ENDPOINT: libusb_request_recipient = 2;
+/// Other
+pub const LIBUSB_RECIPIENT_OTHER: libusb_request_recipient = 3;
+/// \ingroup libusb_misc
+/// Recipient bits of the
+/// \ref libusb_control_setup::bmRequestType "bmRequestType" field in control
+/// transfers. Values 4 through 31 are reserved.
+pub type libusb_request_recipient = u32;
+/// No synchronization
+pub const LIBUSB_ISO_SYNC_TYPE_NONE: libusb_iso_sync_type = 0;
+/// Asynchronous
+pub const LIBUSB_ISO_SYNC_TYPE_ASYNC: libusb_iso_sync_type = 1;
+/// Adaptive
+pub const LIBUSB_ISO_SYNC_TYPE_ADAPTIVE: libusb_iso_sync_type = 2;
+/// Synchronous
+pub const LIBUSB_ISO_SYNC_TYPE_SYNC: libusb_iso_sync_type = 3;
+/// \ingroup libusb_desc
+/// Synchronization type for isochronous endpoints. Values for bits 2:3 of the
+/// \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in
+/// libusb_endpoint_descriptor.
+pub type libusb_iso_sync_type = u32;
+/// Data endpoint
+pub const LIBUSB_ISO_USAGE_TYPE_DATA: libusb_iso_usage_type = 0;
+/// Feedback endpoint
+pub const LIBUSB_ISO_USAGE_TYPE_FEEDBACK: libusb_iso_usage_type = 1;
+/// Implicit feedback Data endpoint
+pub const LIBUSB_ISO_USAGE_TYPE_IMPLICIT: libusb_iso_usage_type = 2;
+/// \ingroup libusb_desc
+/// Usage type for isochronous endpoints. Values for bits 4:5 of the
+/// \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in
+/// libusb_endpoint_descriptor.
+pub type libusb_iso_usage_type = u32;
+/// \ingroup libusb_desc
+/// A structure representing the standard USB device descriptor. This
+/// descriptor is documented in section 9.6.1 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_device_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this
+    /// context.
+    pub bDescriptorType: u8,
+    /// USB specification release number in binary-coded decimal. A value of
+    /// 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc.
+    pub bcdUSB: u16,
+    /// USB-IF class code for the device. See \ref libusb_class_code.
+    pub bDeviceClass: u8,
+    /// USB-IF subclass code for the device, qualified by the bDeviceClass
+    /// value
+    pub bDeviceSubClass: u8,
+    /// USB-IF protocol code for the device, qualified by the bDeviceClass and
+    /// bDeviceSubClass values
+    pub bDeviceProtocol: u8,
+    /// Maximum packet size for endpoint 0
+    pub bMaxPacketSize0: u8,
+    /// USB-IF vendor ID
+    pub idVendor: u16,
+    /// USB-IF product ID
+    pub idProduct: u16,
+    /// Device release number in binary-coded decimal
+    pub bcdDevice: u16,
+    /// Index of string descriptor describing manufacturer
+    pub iManufacturer: u8,
+    /// Index of string descriptor describing product
+    pub iProduct: u8,
+    /// Index of string descriptor containing device serial number
+    pub iSerialNumber: u8,
+    /// Number of possible configurations
+    pub bNumConfigurations: u8,
+}
+#[test]
+fn bindgen_test_layout_libusb_device_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_device_descriptor>(),
+        18usize,
+        concat!("Size of: ", stringify!(libusb_device_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_device_descriptor>(),
+        2usize,
+        concat!("Alignment of ", stringify!(libusb_device_descriptor))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bLength as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bDescriptorType as *const _
+                as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_device_descriptor>())).bcdUSB as *const _ as usize },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bcdUSB)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bDeviceClass as *const _ as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bDeviceClass)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bDeviceSubClass as *const _
+                as usize
+        },
+        5usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bDeviceSubClass)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bDeviceProtocol as *const _
+                as usize
+        },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bDeviceProtocol)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bMaxPacketSize0 as *const _
+                as usize
+        },
+        7usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bMaxPacketSize0)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).idVendor as *const _ as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(idVendor)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).idProduct as *const _ as usize
+        },
+        10usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(idProduct)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bcdDevice as *const _ as usize
+        },
+        12usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bcdDevice)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).iManufacturer as *const _ as usize
+        },
+        14usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(iManufacturer)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).iProduct as *const _ as usize
+        },
+        15usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(iProduct)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).iSerialNumber as *const _ as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(iSerialNumber)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_device_descriptor>())).bNumConfigurations as *const _
+                as usize
+        },
+        17usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_device_descriptor),
+            "::",
+            stringify!(bNumConfigurations)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the standard USB endpoint descriptor. This
+/// descriptor is documented in section 9.6.6 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_endpoint_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in
+    /// this context.
+    pub bDescriptorType: u8,
+    /// The address of the endpoint described by this descriptor. Bits 0:3 are
+    /// the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction,
+    /// see \ref libusb_endpoint_direction.
+    pub bEndpointAddress: u8,
+    /// Attributes which apply to the endpoint when it is configured using
+    /// the bConfigurationValue. Bits 0:1 determine the transfer type and
+    /// correspond to \ref libusb_transfer_type. Bits 2:3 are only used for
+    /// isochronous endpoints and correspond to \ref libusb_iso_sync_type.
+    /// Bits 4:5 are also only used for isochronous endpoints and correspond to
+    /// \ref libusb_iso_usage_type. Bits 6:7 are reserved.
+    pub bmAttributes: u8,
+    /// Maximum packet size this endpoint is capable of sending/receiving.
+    pub wMaxPacketSize: u16,
+    /// Interval for polling endpoint for data transfers.
+    pub bInterval: u8,
+    /// For audio devices only: the rate at which synchronization feedback
+    /// is provided.
+    pub bRefresh: u8,
+    /// For audio devices only: the address if the synch endpoint
+    pub bSynchAddress: u8,
+    /// Extra descriptors. If libusb encounters unknown endpoint descriptors,
+    /// it will store them here, should you wish to parse them.
+    pub extra: *const ::std::os::raw::c_uchar,
+    /// Length of the extra descriptors, in bytes.
+    pub extra_length: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_libusb_endpoint_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_endpoint_descriptor>(),
+        32usize,
+        concat!("Size of: ", stringify!(libusb_endpoint_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_endpoint_descriptor>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_endpoint_descriptor))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bLength as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bDescriptorType as *const _
+                as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bEndpointAddress as *const _
+                as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bEndpointAddress)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bmAttributes as *const _ as usize
+        },
+        3usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bmAttributes)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).wMaxPacketSize as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(wMaxPacketSize)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bInterval as *const _ as usize
+        },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bInterval)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bRefresh as *const _ as usize
+        },
+        7usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bRefresh)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).bSynchAddress as *const _
+                as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(bSynchAddress)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).extra as *const _ as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(extra)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_endpoint_descriptor>())).extra_length as *const _ as usize
+        },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_endpoint_descriptor),
+            "::",
+            stringify!(extra_length)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the standard USB interface descriptor. This
+/// descriptor is documented in section 9.6.5 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_interface_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE
+    /// in this context.
+    pub bDescriptorType: u8,
+    /// Number of this interface
+    pub bInterfaceNumber: u8,
+    /// Value used to select this alternate setting for this interface
+    pub bAlternateSetting: u8,
+    /// Number of endpoints used by this interface (excluding the control
+    /// endpoint).
+    pub bNumEndpoints: u8,
+    /// USB-IF class code for this interface. See \ref libusb_class_code.
+    pub bInterfaceClass: u8,
+    /// USB-IF subclass code for this interface, qualified by the
+    /// bInterfaceClass value
+    pub bInterfaceSubClass: u8,
+    /// USB-IF protocol code for this interface, qualified by the
+    /// bInterfaceClass and bInterfaceSubClass values
+    pub bInterfaceProtocol: u8,
+    /// Index of string descriptor describing this interface
+    pub iInterface: u8,
+    /// Array of endpoint descriptors. This length of this array is determined
+    /// by the bNumEndpoints field.
+    pub endpoint: *const libusb_endpoint_descriptor,
+    /// Extra descriptors. If libusb encounters unknown interface descriptors,
+    /// it will store them here, should you wish to parse them.
+    pub extra: *const ::std::os::raw::c_uchar,
+    /// Length of the extra descriptors, in bytes.
+    pub extra_length: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_libusb_interface_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_interface_descriptor>(),
+        40usize,
+        concat!("Size of: ", stringify!(libusb_interface_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_interface_descriptor>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_interface_descriptor))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bLength as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bDescriptorType as *const _
+                as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bInterfaceNumber as *const _
+                as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bInterfaceNumber)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bAlternateSetting as *const _
+                as usize
+        },
+        3usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bAlternateSetting)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bNumEndpoints as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bNumEndpoints)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bInterfaceClass as *const _
+                as usize
+        },
+        5usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bInterfaceClass)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bInterfaceSubClass as *const _
+                as usize
+        },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bInterfaceSubClass)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).bInterfaceProtocol as *const _
+                as usize
+        },
+        7usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(bInterfaceProtocol)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).iInterface as *const _ as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(iInterface)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).endpoint as *const _ as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(endpoint)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).extra as *const _ as usize
+        },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(extra)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_interface_descriptor>())).extra_length as *const _
+                as usize
+        },
+        32usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface_descriptor),
+            "::",
+            stringify!(extra_length)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A collection of alternate settings for a particular USB interface.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_interface {
+    /// Array of interface descriptors. The length of this array is determined
+    /// by the num_altsetting field.
+    pub altsetting: *const libusb_interface_descriptor,
+    /// The number of alternate settings that belong to this interface
+    pub num_altsetting: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_libusb_interface() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_interface>(),
+        16usize,
+        concat!("Size of: ", stringify!(libusb_interface))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_interface>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_interface))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_interface>())).altsetting as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface),
+            "::",
+            stringify!(altsetting)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_interface>())).num_altsetting as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_interface),
+            "::",
+            stringify!(num_altsetting)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the standard USB configuration descriptor. This
+/// descriptor is documented in section 9.6.3 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_config_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG
+    /// in this context.
+    pub bDescriptorType: u8,
+    /// Total length of data returned for this configuration
+    pub wTotalLength: u16,
+    /// Number of interfaces supported by this configuration
+    pub bNumInterfaces: u8,
+    /// Identifier value for this configuration
+    pub bConfigurationValue: u8,
+    /// Index of string descriptor describing this configuration
+    pub iConfiguration: u8,
+    /// Configuration characteristics
+    pub bmAttributes: u8,
+    /// Maximum power consumption of the USB device from this bus in this
+    /// configuration when the device is fully operation. Expressed in units
+    /// of 2 mA when the device is operating in high-speed mode and in units
+    /// of 8 mA when the device is operating in super-speed mode.
+    pub MaxPower: u8,
+    /// Array of interfaces supported by this configuration. The length of
+    /// this array is determined by the bNumInterfaces field.
+    pub interface: *const libusb_interface,
+    /// Extra descriptors. If libusb encounters unknown configuration
+    /// descriptors, it will store them here, should you wish to parse them.
+    pub extra: *const ::std::os::raw::c_uchar,
+    /// Length of the extra descriptors, in bytes.
+    pub extra_length: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_libusb_config_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_config_descriptor>(),
+        40usize,
+        concat!("Size of: ", stringify!(libusb_config_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_config_descriptor>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_config_descriptor))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).bLength as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).bDescriptorType as *const _
+                as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).wTotalLength as *const _ as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(wTotalLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).bNumInterfaces as *const _ as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(bNumInterfaces)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).bConfigurationValue as *const _
+                as usize
+        },
+        5usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(bConfigurationValue)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).iConfiguration as *const _ as usize
+        },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(iConfiguration)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).bmAttributes as *const _ as usize
+        },
+        7usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(bmAttributes)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).MaxPower as *const _ as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(MaxPower)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).interface as *const _ as usize
+        },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(interface)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_config_descriptor>())).extra as *const _ as usize },
+        24usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(extra)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_config_descriptor>())).extra_length as *const _ as usize
+        },
+        32usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_config_descriptor),
+            "::",
+            stringify!(extra_length)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the superspeed endpoint companion
+/// descriptor. This descriptor is documented in section 9.6.7 of
+/// the USB 3.0 specification. All multiple-byte fields are represented in
+/// host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_ss_endpoint_companion_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in
+    /// this context.
+    pub bDescriptorType: u8,
+    /// The maximum number of packets the endpoint can send or
+    /// receive as part of a burst.
+    pub bMaxBurst: u8,
+    /// In bulk EP:	bits 4:0 represents the	maximum	number of
+    /// streams the	EP supports. In	isochronous EP:	bits 1:0
+    /// represents the Mult	- a zero based value that determines
+    /// the	maximum	number of packets within a service interval
+    pub bmAttributes: u8,
+    /// The	total number of bytes this EP will transfer every
+    /// service interval. valid only for periodic EPs.
+    pub wBytesPerInterval: u16,
+}
+#[test]
+fn bindgen_test_layout_libusb_ss_endpoint_companion_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_ss_endpoint_companion_descriptor>(),
+        6usize,
+        concat!(
+            "Size of: ",
+            stringify!(libusb_ss_endpoint_companion_descriptor)
+        )
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_ss_endpoint_companion_descriptor>(),
+        2usize,
+        concat!(
+            "Alignment of ",
+            stringify!(libusb_ss_endpoint_companion_descriptor)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_endpoint_companion_descriptor>())).bLength as *const _
+                as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_endpoint_companion_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_endpoint_companion_descriptor>())).bDescriptorType
+                as *const _ as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_endpoint_companion_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_endpoint_companion_descriptor>())).bMaxBurst
+                as *const _ as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_endpoint_companion_descriptor),
+            "::",
+            stringify!(bMaxBurst)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_endpoint_companion_descriptor>())).bmAttributes
+                as *const _ as usize
+        },
+        3usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_endpoint_companion_descriptor),
+            "::",
+            stringify!(bmAttributes)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_endpoint_companion_descriptor>())).wBytesPerInterval
+                as *const _ as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_endpoint_companion_descriptor),
+            "::",
+            stringify!(wBytesPerInterval)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A generic representation of a BOS Device Capability descriptor. It is
+/// advised to check bDevCapabilityType and call the matching
+/// libusb_get_*_descriptor function to get a structure fully matching the type.
+#[repr(C)]
+#[derive(Debug)]
+pub struct libusb_bos_dev_capability_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+    /// LIBUSB_DT_DEVICE_CAPABILITY in this context.
+    pub bDescriptorType: u8,
+    /// Device Capability type
+    pub bDevCapabilityType: u8,
+    /// Device Capability data (bLength - 3 bytes)
+    pub dev_capability_data: __IncompleteArrayField<u8>,
+}
+#[test]
+fn bindgen_test_layout_libusb_bos_dev_capability_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_bos_dev_capability_descriptor>(),
+        3usize,
+        concat!(
+            "Size of: ",
+            stringify!(libusb_bos_dev_capability_descriptor)
+        )
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_bos_dev_capability_descriptor>(),
+        1usize,
+        concat!(
+            "Alignment of ",
+            stringify!(libusb_bos_dev_capability_descriptor)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the Binary Device Object Store (BOS) descriptor.
+/// This descriptor is documented in section 9.6.2 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug)]
+pub struct libusb_bos_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS
+    /// in this context.
+    pub bDescriptorType: u8,
+    /// Length of this descriptor and all of its sub descriptors
+    pub wTotalLength: u16,
+    /// The number of separate device capability descriptors in
+    /// the BOS
+    pub bNumDeviceCaps: u8,
+    /// bNumDeviceCap Device Capability Descriptors
+    pub dev_capability: __IncompleteArrayField<*mut libusb_bos_dev_capability_descriptor>,
+    pub __bindgen_align: [u64; 0usize],
+}
+#[test]
+fn bindgen_test_layout_libusb_bos_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_bos_descriptor>(),
+        8usize,
+        concat!("Size of: ", stringify!(libusb_bos_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_bos_descriptor>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_bos_descriptor))
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the USB 2.0 Extension descriptor
+/// This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_usb_2_0_extension_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+    /// LIBUSB_DT_DEVICE_CAPABILITY in this context.
+    pub bDescriptorType: u8,
+    /// Capability type. Will have value
+    /// \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
+    /// LIBUSB_BT_USB_2_0_EXTENSION in this context.
+    pub bDevCapabilityType: u8,
+    /// Bitmap encoding of supported device level features.
+    /// A value of one in a bit location indicates a feature is
+    /// supported; a value of zero indicates it is not supported.
+    /// See \ref libusb_usb_2_0_extension_attributes.
+    pub bmAttributes: u32,
+}
+#[test]
+fn bindgen_test_layout_libusb_usb_2_0_extension_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_usb_2_0_extension_descriptor>(),
+        8usize,
+        concat!("Size of: ", stringify!(libusb_usb_2_0_extension_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_usb_2_0_extension_descriptor>(),
+        4usize,
+        concat!(
+            "Alignment of ",
+            stringify!(libusb_usb_2_0_extension_descriptor)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_usb_2_0_extension_descriptor>())).bLength as *const _
+                as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_usb_2_0_extension_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_usb_2_0_extension_descriptor>())).bDescriptorType
+                as *const _ as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_usb_2_0_extension_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_usb_2_0_extension_descriptor>())).bDevCapabilityType
+                as *const _ as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_usb_2_0_extension_descriptor),
+            "::",
+            stringify!(bDevCapabilityType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_usb_2_0_extension_descriptor>())).bmAttributes as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_usb_2_0_extension_descriptor),
+            "::",
+            stringify!(bmAttributes)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the SuperSpeed USB Device Capability descriptor
+/// This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification.
+/// All multiple-byte fields are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_ss_usb_device_capability_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+    /// LIBUSB_DT_DEVICE_CAPABILITY in this context.
+    pub bDescriptorType: u8,
+    /// Capability type. Will have value
+    /// \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
+    /// LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context.
+    pub bDevCapabilityType: u8,
+    /// Bitmap encoding of supported device level features.
+    /// A value of one in a bit location indicates a feature is
+    /// supported; a value of zero indicates it is not supported.
+    /// See \ref libusb_ss_usb_device_capability_attributes.
+    pub bmAttributes: u8,
+    /// Bitmap encoding of the speed supported by this device when
+    /// operating in SuperSpeed mode. See \ref libusb_supported_speed.
+    pub wSpeedSupported: u16,
+    /// The lowest speed at which all the functionality supported
+    /// by the device is available to the user. For example if the
+    /// device supports all its functionality when connected at
+    /// full speed and above then it sets this value to 1.
+    pub bFunctionalitySupport: u8,
+    /// U1 Device Exit Latency.
+    pub bU1DevExitLat: u8,
+    /// U2 Device Exit Latency.
+    pub bU2DevExitLat: u16,
+}
+#[test]
+fn bindgen_test_layout_libusb_ss_usb_device_capability_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_ss_usb_device_capability_descriptor>(),
+        10usize,
+        concat!(
+            "Size of: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor)
+        )
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_ss_usb_device_capability_descriptor>(),
+        2usize,
+        concat!(
+            "Alignment of ",
+            stringify!(libusb_ss_usb_device_capability_descriptor)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>())).bLength
+                as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>())).bDescriptorType
+                as *const _ as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>()))
+                .bDevCapabilityType as *const _ as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bDevCapabilityType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>())).bmAttributes
+                as *const _ as usize
+        },
+        3usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bmAttributes)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>())).wSpeedSupported
+                as *const _ as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(wSpeedSupported)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>()))
+                .bFunctionalitySupport as *const _ as usize
+        },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bFunctionalitySupport)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>())).bU1DevExitLat
+                as *const _ as usize
+        },
+        7usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bU1DevExitLat)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_ss_usb_device_capability_descriptor>())).bU2DevExitLat
+                as *const _ as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_ss_usb_device_capability_descriptor),
+            "::",
+            stringify!(bU2DevExitLat)
+        )
+    );
+}
+/// \ingroup libusb_desc
+/// A structure representing the Container ID descriptor.
+/// This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification.
+/// All multiple-byte fields, except UUIDs, are represented in host-endian format.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_container_id_descriptor {
+    /// Size of this descriptor (in bytes)
+    pub bLength: u8,
+    /// Descriptor type. Will have value
+    /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+    /// LIBUSB_DT_DEVICE_CAPABILITY in this context.
+    pub bDescriptorType: u8,
+    /// Capability type. Will have value
+    /// \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
+    /// LIBUSB_BT_CONTAINER_ID in this context.
+    pub bDevCapabilityType: u8,
+    /// Reserved field
+    pub bReserved: u8,
+    /// 128 bit UUID
+    pub ContainerID: [u8; 16usize],
+}
+#[test]
+fn bindgen_test_layout_libusb_container_id_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_container_id_descriptor>(),
+        20usize,
+        concat!("Size of: ", stringify!(libusb_container_id_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_container_id_descriptor>(),
+        1usize,
+        concat!("Alignment of ", stringify!(libusb_container_id_descriptor))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_container_id_descriptor>())).bLength as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_container_id_descriptor),
+            "::",
+            stringify!(bLength)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_container_id_descriptor>())).bDescriptorType as *const _
+                as usize
+        },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_container_id_descriptor),
+            "::",
+            stringify!(bDescriptorType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_container_id_descriptor>())).bDevCapabilityType
+                as *const _ as usize
+        },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_container_id_descriptor),
+            "::",
+            stringify!(bDevCapabilityType)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_container_id_descriptor>())).bReserved as *const _
+                as usize
+        },
+        3usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_container_id_descriptor),
+            "::",
+            stringify!(bReserved)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_container_id_descriptor>())).ContainerID as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_container_id_descriptor),
+            "::",
+            stringify!(ContainerID)
+        )
+    );
+}
+/// \ingroup libusb_asyncio
+/// Setup packet for control transfers.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_control_setup {
+    /// Request type. Bits 0:4 determine recipient, see
+    /// \ref libusb_request_recipient. Bits 5:6 determine type, see
+    /// \ref libusb_request_type. Bit 7 determines data transfer direction, see
+    /// \ref libusb_endpoint_direction.
+    pub bmRequestType: u8,
+    /// Request. If the type bits of bmRequestType are equal to
+    /// \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD
+    /// "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to
+    /// \ref libusb_standard_request. For other cases, use of this field is
+    /// application-specific.
+    pub bRequest: u8,
+    /// Value. Varies according to request
+    pub wValue: u16,
+    /// Index. Varies according to request, typically used to pass an index
+    /// or offset
+    pub wIndex: u16,
+    /// Number of bytes to transfer
+    pub wLength: u16,
+}
+#[test]
+fn bindgen_test_layout_libusb_control_setup() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_control_setup>(),
+        8usize,
+        concat!("Size of: ", stringify!(libusb_control_setup))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_control_setup>(),
+        2usize,
+        concat!("Alignment of ", stringify!(libusb_control_setup))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_control_setup>())).bmRequestType as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_control_setup),
+            "::",
+            stringify!(bmRequestType)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_control_setup>())).bRequest as *const _ as usize },
+        1usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_control_setup),
+            "::",
+            stringify!(bRequest)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_control_setup>())).wValue as *const _ as usize },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_control_setup),
+            "::",
+            stringify!(wValue)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_control_setup>())).wIndex as *const _ as usize },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_control_setup),
+            "::",
+            stringify!(wIndex)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_control_setup>())).wLength as *const _ as usize },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_control_setup),
+            "::",
+            stringify!(wLength)
+        )
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_context {
+    _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_device {
+    _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_device_handle {
+    _unused: [u8; 0],
+}
+/// \ingroup libusb_lib
+/// Structure providing the version of the libusb runtime
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_version {
+    /// Library major version.
+    pub major: u16,
+    /// Library minor version.
+    pub minor: u16,
+    /// Library micro version.
+    pub micro: u16,
+    /// Library nano version.
+    pub nano: u16,
+    /// Library release candidate suffix string, e.g. "-rc4".
+    pub rc: *const ::std::os::raw::c_char,
+    /// For ABI compatibility only.
+    pub describe: *const ::std::os::raw::c_char,
+}
+#[test]
+fn bindgen_test_layout_libusb_version() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_version>(),
+        24usize,
+        concat!("Size of: ", stringify!(libusb_version))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_version>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_version))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_version>())).major as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_version),
+            "::",
+            stringify!(major)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_version>())).minor as *const _ as usize },
+        2usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_version),
+            "::",
+            stringify!(minor)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_version>())).micro as *const _ as usize },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_version),
+            "::",
+            stringify!(micro)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_version>())).nano as *const _ as usize },
+        6usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_version),
+            "::",
+            stringify!(nano)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_version>())).rc as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_version),
+            "::",
+            stringify!(rc)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_version>())).describe as *const _ as usize },
+        16usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_version),
+            "::",
+            stringify!(describe)
+        )
+    );
+}
+/// The OS doesn't report or know the device speed.
+pub const LIBUSB_SPEED_UNKNOWN: libusb_speed = 0;
+/// The device is operating at low speed (1.5MBit/s).
+pub const LIBUSB_SPEED_LOW: libusb_speed = 1;
+/// The device is operating at full speed (12MBit/s).
+pub const LIBUSB_SPEED_FULL: libusb_speed = 2;
+/// The device is operating at high speed (480MBit/s).
+pub const LIBUSB_SPEED_HIGH: libusb_speed = 3;
+/// The device is operating at super speed (5000MBit/s).
+pub const LIBUSB_SPEED_SUPER: libusb_speed = 4;
+/// \ingroup libusb_dev
+/// Speed codes. Indicates the speed at which the device is operating.
+pub type libusb_speed = u32;
+/// Low speed operation supported (1.5MBit/s).
+pub const LIBUSB_LOW_SPEED_OPERATION: libusb_supported_speed = 1;
+/// Full speed operation supported (12MBit/s).
+pub const LIBUSB_FULL_SPEED_OPERATION: libusb_supported_speed = 2;
+/// High speed operation supported (480MBit/s).
+pub const LIBUSB_HIGH_SPEED_OPERATION: libusb_supported_speed = 4;
+/// Superspeed operation supported (5000MBit/s).
+pub const LIBUSB_SUPER_SPEED_OPERATION: libusb_supported_speed = 8;
+/// \ingroup libusb_dev
+/// Supported speeds (wSpeedSupported) bitfield. Indicates what
+/// speeds the device supports.
+pub type libusb_supported_speed = u32;
+/// Supports Link Power Management (LPM)
+pub const LIBUSB_BM_LPM_SUPPORT: libusb_usb_2_0_extension_attributes = 2;
+/// \ingroup libusb_dev
+/// Masks for the bits of the
+/// \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field
+/// of the USB 2.0 Extension descriptor.
+pub type libusb_usb_2_0_extension_attributes = u32;
+/// Supports Latency Tolerance Messages (LTM)
+pub const LIBUSB_BM_LTM_SUPPORT: libusb_ss_usb_device_capability_attributes = 2;
+/// \ingroup libusb_dev
+/// Masks for the bits of the
+/// \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field
+/// field of the SuperSpeed USB Device Capability descriptor.
+pub type libusb_ss_usb_device_capability_attributes = u32;
+/// Wireless USB device capability
+pub const LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY: libusb_bos_type = 1;
+/// USB 2.0 extensions
+pub const LIBUSB_BT_USB_2_0_EXTENSION: libusb_bos_type = 2;
+/// SuperSpeed USB device capability
+pub const LIBUSB_BT_SS_USB_DEVICE_CAPABILITY: libusb_bos_type = 3;
+/// Container ID type
+pub const LIBUSB_BT_CONTAINER_ID: libusb_bos_type = 4;
+/// \ingroup libusb_dev
+/// USB capability types
+pub type libusb_bos_type = u32;
+/// Success (no error)
+pub const LIBUSB_SUCCESS: libusb_error = 0;
+/// Input/output error
+pub const LIBUSB_ERROR_IO: libusb_error = -1;
+/// Invalid parameter
+pub const LIBUSB_ERROR_INVALID_PARAM: libusb_error = -2;
+/// Access denied (insufficient permissions)
+pub const LIBUSB_ERROR_ACCESS: libusb_error = -3;
+/// No such device (it may have been disconnected)
+pub const LIBUSB_ERROR_NO_DEVICE: libusb_error = -4;
+/// Entity not found
+pub const LIBUSB_ERROR_NOT_FOUND: libusb_error = -5;
+/// Resource busy
+pub const LIBUSB_ERROR_BUSY: libusb_error = -6;
+/// Operation timed out
+pub const LIBUSB_ERROR_TIMEOUT: libusb_error = -7;
+/// Overflow
+pub const LIBUSB_ERROR_OVERFLOW: libusb_error = -8;
+/// Pipe error
+pub const LIBUSB_ERROR_PIPE: libusb_error = -9;
+/// System call interrupted (perhaps due to signal)
+pub const LIBUSB_ERROR_INTERRUPTED: libusb_error = -10;
+/// Insufficient memory
+pub const LIBUSB_ERROR_NO_MEM: libusb_error = -11;
+/// Operation not supported or unimplemented on this platform
+pub const LIBUSB_ERROR_NOT_SUPPORTED: libusb_error = -12;
+/// Other error
+pub const LIBUSB_ERROR_OTHER: libusb_error = -99;
+/// \ingroup libusb_misc
+/// Error codes. Most libusb functions return 0 on success or one of these
+/// codes on failure.
+/// You can call libusb_error_name() to retrieve a string representation of an
+/// error code or libusb_strerror() to get an end-user suitable description of
+/// an error code.
+pub type libusb_error = i32;
+/// Transfer completed without error. Note that this does not indicate
+/// that the entire amount of requested data was transferred.
+pub const LIBUSB_TRANSFER_COMPLETED: libusb_transfer_status = 0;
+/// Transfer failed
+pub const LIBUSB_TRANSFER_ERROR: libusb_transfer_status = 1;
+/// Transfer timed out
+pub const LIBUSB_TRANSFER_TIMED_OUT: libusb_transfer_status = 2;
+/// Transfer was cancelled
+pub const LIBUSB_TRANSFER_CANCELLED: libusb_transfer_status = 3;
+/// For bulk/interrupt endpoints: halt condition detected (endpoint
+/// stalled). For control endpoints: control request not supported.
+pub const LIBUSB_TRANSFER_STALL: libusb_transfer_status = 4;
+/// Device was disconnected
+pub const LIBUSB_TRANSFER_NO_DEVICE: libusb_transfer_status = 5;
+/// Device sent more data than requested
+pub const LIBUSB_TRANSFER_OVERFLOW: libusb_transfer_status = 6;
+/// \ingroup libusb_asyncio
+/// Transfer status codes
+pub type libusb_transfer_status = u32;
+/// Report short frames as errors
+pub const LIBUSB_TRANSFER_SHORT_NOT_OK: libusb_transfer_flags = 1;
+/// Automatically free() transfer buffer during libusb_free_transfer().
+/// Note that buffers allocated with libusb_dev_mem_alloc() should not
+/// be attempted freed in this way, since free() is not an appropriate
+/// way to release such memory.
+pub const LIBUSB_TRANSFER_FREE_BUFFER: libusb_transfer_flags = 2;
+/// Automatically call libusb_free_transfer() after callback returns.
+/// If this flag is set, it is illegal to call libusb_free_transfer()
+/// from your transfer callback, as this will result in a double-free
+/// when this flag is acted upon.
+pub const LIBUSB_TRANSFER_FREE_TRANSFER: libusb_transfer_flags = 4;
+/// Terminate transfers that are a multiple of the endpoint's
+/// wMaxPacketSize with an extra zero length packet. This is useful
+/// when a device protocol mandates that each logical request is
+/// terminated by an incomplete packet (i.e. the logical requests are
+/// not separated by other means).
+///
+/// This flag only affects host-to-device transfers to bulk and interrupt
+/// endpoints. In other situations, it is ignored.
+///
+/// This flag only affects transfers with a length that is a multiple of
+/// the endpoint's wMaxPacketSize. On transfers of other lengths, this
+/// flag has no effect. Therefore, if you are working with a device that
+/// needs a ZLP whenever the end of the logical request falls on a packet
+/// boundary, then it is sensible to set this flag on <em>every</em>
+/// transfer (you do not have to worry about only setting it on transfers
+/// that end on the boundary).
+///
+/// This flag is currently only supported on Linux.
+/// On other systems, libusb_submit_transfer() will return
+/// LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set.
+///
+/// Available since libusb-1.0.9.
+pub const LIBUSB_TRANSFER_ADD_ZERO_PACKET: libusb_transfer_flags = 8;
+/// \ingroup libusb_asyncio
+/// libusb_transfer.flags values
+pub type libusb_transfer_flags = u32;
+/// \ingroup libusb_asyncio
+/// Isochronous packet descriptor.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_iso_packet_descriptor {
+    /// Length of data to request in this packet
+    pub length: ::std::os::raw::c_uint,
+    /// Amount of data that was actually transferred
+    pub actual_length: ::std::os::raw::c_uint,
+    /// Status code for this packet
+    pub status: libusb_transfer_status,
+}
+#[test]
+fn bindgen_test_layout_libusb_iso_packet_descriptor() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_iso_packet_descriptor>(),
+        12usize,
+        concat!("Size of: ", stringify!(libusb_iso_packet_descriptor))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_iso_packet_descriptor>(),
+        4usize,
+        concat!("Alignment of ", stringify!(libusb_iso_packet_descriptor))
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_iso_packet_descriptor>())).length as *const _ as usize
+        },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_iso_packet_descriptor),
+            "::",
+            stringify!(length)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_iso_packet_descriptor>())).actual_length as *const _
+                as usize
+        },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_iso_packet_descriptor),
+            "::",
+            stringify!(actual_length)
+        )
+    );
+    assert_eq!(
+        unsafe {
+            &(*(::std::ptr::null::<libusb_iso_packet_descriptor>())).status as *const _ as usize
+        },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_iso_packet_descriptor),
+            "::",
+            stringify!(status)
+        )
+    );
+}
+/// \ingroup libusb_asyncio
+/// Asynchronous transfer callback function type. When submitting asynchronous
+/// transfers, you pass a pointer to a callback function of this type via the
+/// \ref libusb_transfer::callback "callback" member of the libusb_transfer
+/// structure. libusb will call this function later, when the transfer has
+/// completed or failed. See \ref libusb_asyncio for more information.
+/// \param transfer The libusb_transfer struct the callback function is being
+/// notified about.
+pub type libusb_transfer_cb_fn =
+    ::std::option::Option<unsafe extern "C" fn(transfer: *mut libusb_transfer)>;
+/// \ingroup libusb_asyncio
+/// The generic USB transfer structure. The user populates this structure and
+/// then submits it in order to request a transfer. After the transfer has
+/// completed, the library populates the transfer with the results and passes
+/// it back to the user.
+#[repr(C)]
+#[derive(Debug)]
+pub struct libusb_transfer {
+    /// Handle of the device that this transfer will be submitted to
+    pub dev_handle: *mut libusb_device_handle,
+    /// A bitwise OR combination of \ref libusb_transfer_flags.
+    pub flags: u8,
+    /// Address of the endpoint where this transfer will be sent.
+    pub endpoint: ::std::os::raw::c_uchar,
+    /// Type of the endpoint from \ref libusb_transfer_type
+    pub type_: ::std::os::raw::c_uchar,
+    /// Timeout for this transfer in millseconds. A value of 0 indicates no
+    /// timeout.
+    pub timeout: ::std::os::raw::c_uint,
+    /// The status of the transfer. Read-only, and only for use within
+    /// transfer callback function.
+    ///
+    /// If this is an isochronous transfer, this field may read COMPLETED even
+    /// if there were errors in the frames. Use the
+    /// \ref libusb_iso_packet_descriptor::status "status" field in each packet
+    /// to determine if errors occurred.
+    pub status: libusb_transfer_status,
+    /// Length of the data buffer
+    pub length: ::std::os::raw::c_int,
+    /// Actual length of data that was transferred. Read-only, and only for
+    /// use within transfer callback function. Not valid for isochronous
+    /// endpoint transfers.
+    pub actual_length: ::std::os::raw::c_int,
+    /// Callback function. This will be invoked when the transfer completes,
+    /// fails, or is cancelled.
+    pub callback: libusb_transfer_cb_fn,
+    /// User context data to pass to the callback function.
+    pub user_data: *mut ::std::os::raw::c_void,
+    /// Data buffer
+    pub buffer: *mut ::std::os::raw::c_uchar,
+    /// Number of isochronous packets. Only used for I/O with isochronous
+    /// endpoints.
+    pub num_iso_packets: ::std::os::raw::c_int,
+    /// Isochronous packet descriptors, for isochronous transfers only.
+    pub iso_packet_desc: __IncompleteArrayField<libusb_iso_packet_descriptor>,
+}
+#[test]
+fn bindgen_test_layout_libusb_transfer() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_transfer>(),
+        64usize,
+        concat!("Size of: ", stringify!(libusb_transfer))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_transfer>(),
+        8usize,
+        concat!("Alignment of ", stringify!(libusb_transfer))
+    );
+}
+/// The libusb_has_capability() API is available.
+pub const LIBUSB_CAP_HAS_CAPABILITY: libusb_capability = 0;
+/// Hotplug support is available on this platform.
+pub const LIBUSB_CAP_HAS_HOTPLUG: libusb_capability = 1;
+/// The library can access HID devices without requiring user intervention.
+/// Note that before being able to actually access an HID device, you may
+/// still have to call additional libusb functions such as
+/// \ref libusb_detach_kernel_driver().
+pub const LIBUSB_CAP_HAS_HID_ACCESS: libusb_capability = 256;
+/// The library supports detaching of the default USB driver, using
+/// \ref libusb_detach_kernel_driver(), if one is set by the OS kernel
+pub const LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER: libusb_capability = 257;
+/// \ingroup libusb_misc
+/// Capabilities supported by an instance of libusb on the current running
+/// platform. Test if the loaded library supports a given capability by calling
+/// \ref libusb_has_capability().
+pub type libusb_capability = u32;
+pub const LIBUSB_LOG_LEVEL_NONE: libusb_log_level = 0;
+pub const LIBUSB_LOG_LEVEL_ERROR: libusb_log_level = 1;
+pub const LIBUSB_LOG_LEVEL_WARNING: libusb_log_level = 2;
+pub const LIBUSB_LOG_LEVEL_INFO: libusb_log_level = 3;
+pub const LIBUSB_LOG_LEVEL_DEBUG: libusb_log_level = 4;
+/// \ingroup libusb_lib
+/// Log message levels.
+/// - LIBUSB_LOG_LEVEL_NONE (0)    : no messages ever printed by the library (default)
+/// - LIBUSB_LOG_LEVEL_ERROR (1)   : error messages are printed to stderr
+/// - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr
+/// - LIBUSB_LOG_LEVEL_INFO (3)    : informational messages are printed to stdout, warning
+/// and error messages are printed to stderr
+/// - LIBUSB_LOG_LEVEL_DEBUG (4)   : debug and informational messages are printed to stdout,
+/// warnings and errors to stderr
+pub type libusb_log_level = u32;
+extern "C" {
+    pub fn libusb_init(ctx: *mut *mut libusb_context) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_exit(ctx: *mut libusb_context);
+}
+extern "C" {
+    pub fn libusb_set_debug(ctx: *mut libusb_context, level: ::std::os::raw::c_int);
+}
+extern "C" {
+    pub fn libusb_get_version() -> *const libusb_version;
+}
+extern "C" {
+    pub fn libusb_has_capability(capability: u32) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_error_name(errcode: ::std::os::raw::c_int) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+    pub fn libusb_setlocale(locale: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_strerror(errcode: libusb_error) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+    pub fn libusb_get_device_list(
+        ctx: *mut libusb_context,
+        list: *mut *mut *mut libusb_device,
+    ) -> isize;
+}
+extern "C" {
+    pub fn libusb_free_device_list(
+        list: *mut *mut libusb_device,
+        unref_devices: ::std::os::raw::c_int,
+    );
+}
+extern "C" {
+    pub fn libusb_ref_device(dev: *mut libusb_device) -> *mut libusb_device;
+}
+extern "C" {
+    pub fn libusb_unref_device(dev: *mut libusb_device);
+}
+extern "C" {
+    pub fn libusb_get_configuration(
+        dev: *mut libusb_device_handle,
+        config: *mut ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_device_descriptor(
+        dev: *mut libusb_device,
+        desc: *mut libusb_device_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_active_config_descriptor(
+        dev: *mut libusb_device,
+        config: *mut *mut libusb_config_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_config_descriptor(
+        dev: *mut libusb_device,
+        config_index: u8,
+        config: *mut *mut libusb_config_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_config_descriptor_by_value(
+        dev: *mut libusb_device,
+        bConfigurationValue: u8,
+        config: *mut *mut libusb_config_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_config_descriptor(config: *mut libusb_config_descriptor);
+}
+extern "C" {
+    pub fn libusb_get_ss_endpoint_companion_descriptor(
+        ctx: *mut libusb_context,
+        endpoint: *const libusb_endpoint_descriptor,
+        ep_comp: *mut *mut libusb_ss_endpoint_companion_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_ss_endpoint_companion_descriptor(
+        ep_comp: *mut libusb_ss_endpoint_companion_descriptor,
+    );
+}
+extern "C" {
+    pub fn libusb_get_bos_descriptor(
+        dev_handle: *mut libusb_device_handle,
+        bos: *mut *mut libusb_bos_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_bos_descriptor(bos: *mut libusb_bos_descriptor);
+}
+extern "C" {
+    pub fn libusb_get_usb_2_0_extension_descriptor(
+        ctx: *mut libusb_context,
+        dev_cap: *mut libusb_bos_dev_capability_descriptor,
+        usb_2_0_extension: *mut *mut libusb_usb_2_0_extension_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_usb_2_0_extension_descriptor(
+        usb_2_0_extension: *mut libusb_usb_2_0_extension_descriptor,
+    );
+}
+extern "C" {
+    pub fn libusb_get_ss_usb_device_capability_descriptor(
+        ctx: *mut libusb_context,
+        dev_cap: *mut libusb_bos_dev_capability_descriptor,
+        ss_usb_device_cap: *mut *mut libusb_ss_usb_device_capability_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_ss_usb_device_capability_descriptor(
+        ss_usb_device_cap: *mut libusb_ss_usb_device_capability_descriptor,
+    );
+}
+extern "C" {
+    pub fn libusb_get_container_id_descriptor(
+        ctx: *mut libusb_context,
+        dev_cap: *mut libusb_bos_dev_capability_descriptor,
+        container_id: *mut *mut libusb_container_id_descriptor,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_container_id_descriptor(container_id: *mut libusb_container_id_descriptor);
+}
+extern "C" {
+    pub fn libusb_get_bus_number(dev: *mut libusb_device) -> u8;
+}
+extern "C" {
+    pub fn libusb_get_port_number(dev: *mut libusb_device) -> u8;
+}
+extern "C" {
+    pub fn libusb_get_port_numbers(
+        dev: *mut libusb_device,
+        port_numbers: *mut u8,
+        port_numbers_len: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_port_path(
+        ctx: *mut libusb_context,
+        dev: *mut libusb_device,
+        path: *mut u8,
+        path_length: u8,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_parent(dev: *mut libusb_device) -> *mut libusb_device;
+}
+extern "C" {
+    pub fn libusb_get_device_address(dev: *mut libusb_device) -> u8;
+}
+extern "C" {
+    pub fn libusb_get_device_speed(dev: *mut libusb_device) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_max_packet_size(
+        dev: *mut libusb_device,
+        endpoint: ::std::os::raw::c_uchar,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_max_iso_packet_size(
+        dev: *mut libusb_device,
+        endpoint: ::std::os::raw::c_uchar,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_open(
+        dev: *mut libusb_device,
+        dev_handle: *mut *mut libusb_device_handle,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_close(dev_handle: *mut libusb_device_handle);
+}
+extern "C" {
+    pub fn libusb_get_device(dev_handle: *mut libusb_device_handle) -> *mut libusb_device;
+}
+extern "C" {
+    pub fn libusb_set_configuration(
+        dev_handle: *mut libusb_device_handle,
+        configuration: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_claim_interface(
+        dev_handle: *mut libusb_device_handle,
+        interface_number: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_release_interface(
+        dev_handle: *mut libusb_device_handle,
+        interface_number: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_open_device_with_vid_pid(
+        ctx: *mut libusb_context,
+        vendor_id: u16,
+        product_id: u16,
+    ) -> *mut libusb_device_handle;
+}
+extern "C" {
+    pub fn libusb_set_interface_alt_setting(
+        dev_handle: *mut libusb_device_handle,
+        interface_number: ::std::os::raw::c_int,
+        alternate_setting: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_clear_halt(
+        dev_handle: *mut libusb_device_handle,
+        endpoint: ::std::os::raw::c_uchar,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_reset_device(dev_handle: *mut libusb_device_handle) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_alloc_streams(
+        dev_handle: *mut libusb_device_handle,
+        num_streams: u32,
+        endpoints: *mut ::std::os::raw::c_uchar,
+        num_endpoints: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_streams(
+        dev_handle: *mut libusb_device_handle,
+        endpoints: *mut ::std::os::raw::c_uchar,
+        num_endpoints: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_dev_mem_alloc(
+        dev_handle: *mut libusb_device_handle,
+        length: usize,
+    ) -> *mut ::std::os::raw::c_uchar;
+}
+extern "C" {
+    pub fn libusb_dev_mem_free(
+        dev_handle: *mut libusb_device_handle,
+        buffer: *mut ::std::os::raw::c_uchar,
+        length: usize,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_kernel_driver_active(
+        dev_handle: *mut libusb_device_handle,
+        interface_number: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_detach_kernel_driver(
+        dev_handle: *mut libusb_device_handle,
+        interface_number: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_attach_kernel_driver(
+        dev_handle: *mut libusb_device_handle,
+        interface_number: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_set_auto_detach_kernel_driver(
+        dev_handle: *mut libusb_device_handle,
+        enable: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_alloc_transfer(iso_packets: ::std::os::raw::c_int) -> *mut libusb_transfer;
+}
+extern "C" {
+    pub fn libusb_submit_transfer(transfer: *mut libusb_transfer) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_cancel_transfer(transfer: *mut libusb_transfer) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_free_transfer(transfer: *mut libusb_transfer);
+}
+extern "C" {
+    pub fn libusb_transfer_set_stream_id(transfer: *mut libusb_transfer, stream_id: u32);
+}
+extern "C" {
+    pub fn libusb_transfer_get_stream_id(transfer: *mut libusb_transfer) -> u32;
+}
+extern "C" {
+    pub fn libusb_control_transfer(
+        dev_handle: *mut libusb_device_handle,
+        request_type: u8,
+        bRequest: u8,
+        wValue: u16,
+        wIndex: u16,
+        data: *mut ::std::os::raw::c_uchar,
+        wLength: u16,
+        timeout: ::std::os::raw::c_uint,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_bulk_transfer(
+        dev_handle: *mut libusb_device_handle,
+        endpoint: ::std::os::raw::c_uchar,
+        data: *mut ::std::os::raw::c_uchar,
+        length: ::std::os::raw::c_int,
+        actual_length: *mut ::std::os::raw::c_int,
+        timeout: ::std::os::raw::c_uint,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_interrupt_transfer(
+        dev_handle: *mut libusb_device_handle,
+        endpoint: ::std::os::raw::c_uchar,
+        data: *mut ::std::os::raw::c_uchar,
+        length: ::std::os::raw::c_int,
+        actual_length: *mut ::std::os::raw::c_int,
+        timeout: ::std::os::raw::c_uint,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_string_descriptor_ascii(
+        dev_handle: *mut libusb_device_handle,
+        desc_index: u8,
+        data: *mut ::std::os::raw::c_uchar,
+        length: ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_try_lock_events(ctx: *mut libusb_context) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_lock_events(ctx: *mut libusb_context);
+}
+extern "C" {
+    pub fn libusb_unlock_events(ctx: *mut libusb_context);
+}
+extern "C" {
+    pub fn libusb_event_handling_ok(ctx: *mut libusb_context) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_event_handler_active(ctx: *mut libusb_context) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_interrupt_event_handler(ctx: *mut libusb_context);
+}
+extern "C" {
+    pub fn libusb_lock_event_waiters(ctx: *mut libusb_context);
+}
+extern "C" {
+    pub fn libusb_unlock_event_waiters(ctx: *mut libusb_context);
+}
+extern "C" {
+    pub fn libusb_wait_for_event(
+        ctx: *mut libusb_context,
+        tv: *mut timeval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_handle_events_timeout(
+        ctx: *mut libusb_context,
+        tv: *mut timeval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_handle_events_timeout_completed(
+        ctx: *mut libusb_context,
+        tv: *mut timeval,
+        completed: *mut ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_handle_events(ctx: *mut libusb_context) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_handle_events_completed(
+        ctx: *mut libusb_context,
+        completed: *mut ::std::os::raw::c_int,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_handle_events_locked(
+        ctx: *mut libusb_context,
+        tv: *mut timeval,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_pollfds_handle_timeouts(ctx: *mut libusb_context) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    pub fn libusb_get_next_timeout(
+        ctx: *mut libusb_context,
+        tv: *mut timeval,
+    ) -> ::std::os::raw::c_int;
+}
+/// \ingroup libusb_poll
+/// File descriptor for polling
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct libusb_pollfd {
+    /// Numeric file descriptor
+    pub fd: ::std::os::raw::c_int,
+    /// Event flags to poll for from <poll.h>. POLLIN indicates that you
+    /// should monitor this file descriptor for becoming ready to read from,
+    /// and POLLOUT indicates that you should monitor this file descriptor for
+    /// nonblocking write readiness.
+    pub events: ::std::os::raw::c_short,
+}
+#[test]
+fn bindgen_test_layout_libusb_pollfd() {
+    assert_eq!(
+        ::std::mem::size_of::<libusb_pollfd>(),
+        8usize,
+        concat!("Size of: ", stringify!(libusb_pollfd))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<libusb_pollfd>(),
+        4usize,
+        concat!("Alignment of ", stringify!(libusb_pollfd))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_pollfd>())).fd as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_pollfd),
+            "::",
+            stringify!(fd)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<libusb_pollfd>())).events as *const _ as usize },
+        4usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(libusb_pollfd),
+            "::",
+            stringify!(events)
+        )
+    );
+}
+/// \ingroup libusb_poll
+/// Callback function, invoked when a new file descriptor should be added
+/// to the set of file descriptors monitored for events.
+/// \param fd the new file descriptor
+/// \param events events to monitor for, see \ref libusb_pollfd for a
+/// description
+/// \param user_data User data pointer specified in
+/// libusb_set_pollfd_notifiers() call
+/// \see libusb_set_pollfd_notifiers()
+pub type libusb_pollfd_added_cb = ::std::option::Option<
+    unsafe extern "C" fn(
+        fd: ::std::os::raw::c_int,
+        events: ::std::os::raw::c_short,
+        user_data: *mut ::std::os::raw::c_void,
+    ),
+>;
+/// \ingroup libusb_poll
+/// Callback function, invoked when a file descriptor should be removed from
+/// the set of file descriptors being monitored for events. After returning
+/// from this callback, do not use that file descriptor again.
+/// \param fd the file descriptor to stop monitoring
+/// \param user_data User data pointer specified in
+/// libusb_set_pollfd_notifiers() call
+/// \see libusb_set_pollfd_notifiers()
+pub type libusb_pollfd_removed_cb = ::std::option::Option<
+    unsafe extern "C" fn(fd: ::std::os::raw::c_int, user_data: *mut ::std::os::raw::c_void),
+>;
+extern "C" {
+    pub fn libusb_get_pollfds(ctx: *mut libusb_context) -> *mut *const libusb_pollfd;
+}
+extern "C" {
+    pub fn libusb_free_pollfds(pollfds: *mut *const libusb_pollfd);
+}
+extern "C" {
+    pub fn libusb_set_pollfd_notifiers(
+        ctx: *mut libusb_context,
+        added_cb: libusb_pollfd_added_cb,
+        removed_cb: libusb_pollfd_removed_cb,
+        user_data: *mut ::std::os::raw::c_void,
+    );
+}
+/// \ingroup libusb_hotplug
+/// Callback handle.
+///
+/// Callbacks handles are generated by libusb_hotplug_register_callback()
+/// and can be used to deregister callbacks. Callback handles are unique
+/// per libusb_context and it is safe to call libusb_hotplug_deregister_callback()
+/// on an already deregisted callback.
+///
+/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+///
+/// For more information, see \ref libusb_hotplug.
+pub type libusb_hotplug_callback_handle = ::std::os::raw::c_int;
+/// Default value when not using any flags.
+pub const LIBUSB_HOTPLUG_NO_FLAGS: libusb_hotplug_flag = 0;
+/// Arm the callback and fire it for all matching currently attached devices.
+pub const LIBUSB_HOTPLUG_ENUMERATE: libusb_hotplug_flag = 1;
+/// \ingroup libusb_hotplug
+///
+/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+///
+/// Flags for hotplug events
+pub type libusb_hotplug_flag = u32;
+/// A device has been plugged in and is ready to use
+pub const LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: libusb_hotplug_event = 1;
+/// A device has left and is no longer available.
+/// It is the user's responsibility to call libusb_close on any handle associated with a disconnected device.
+/// It is safe to call libusb_get_device_descriptor on a device that has left
+pub const LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: libusb_hotplug_event = 2;
+/// \ingroup libusb_hotplug
+///
+/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+///
+/// Hotplug events
+pub type libusb_hotplug_event = u32;
+/// \ingroup libusb_hotplug
+/// Hotplug callback function type. When requesting hotplug event notifications,
+/// you pass a pointer to a callback function of this type.
+///
+/// This callback may be called by an internal event thread and as such it is
+/// recommended the callback do minimal processing before returning.
+///
+/// libusb will call this function later, when a matching event had happened on
+/// a matching device. See \ref libusb_hotplug for more information.
+///
+/// It is safe to call either libusb_hotplug_register_callback() or
+/// libusb_hotplug_deregister_callback() from within a callback function.
+///
+/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+///
+/// \param ctx            context of this notification
+/// \param device         libusb_device this event occurred on
+/// \param event          event that occurred
+/// \param user_data      user data provided when this callback was registered
+/// \returns bool whether this callback is finished processing events.
+/// returning 1 will cause this callback to be deregistered
+pub type libusb_hotplug_callback_fn = ::std::option::Option<
+    unsafe extern "C" fn(
+        ctx: *mut libusb_context,
+        device: *mut libusb_device,
+        event: libusb_hotplug_event,
+        user_data: *mut ::std::os::raw::c_void,
+    ) -> ::std::os::raw::c_int,
+>;
+extern "C" {
+    /// \ingroup libusb_hotplug
+    /// Register a hotplug callback function
+    ///
+    /// Register a callback with the libusb_context. The callback will fire
+    /// when a matching event occurs on a matching device. The callback is
+    /// armed until either it is deregistered with libusb_hotplug_deregister_callback()
+    /// or the supplied callback returns 1 to indicate it is finished processing events.
+    ///
+    /// If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be
+    /// called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices
+    /// already plugged into the machine. Note that libusb modifies its internal
+    /// device list from a separate thread, while calling hotplug callbacks from
+    /// libusb_handle_events(), so it is possible for a device to already be present
+    /// on, or removed from, its internal device list, while the hotplug callbacks
+    /// still need to be dispatched. This means that when using \ref
+    /// LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival
+    /// of the same device, once from libusb_hotplug_register_callback() and once
+    /// from libusb_handle_events(); and/or your callback may be called for the
+    /// removal of a device for which an arrived call was never made.
+    ///
+    /// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+    ///
+    /// \param[in] ctx context to register this callback with
+    /// \param[in] events bitwise or of events that will trigger this callback. See \ref
+    /// libusb_hotplug_event
+    /// \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag
+    /// \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
+    /// \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
+    /// \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
+    /// \param[in] cb_fn the function to be invoked on a matching event/device
+    /// \param[in] user_data user data to pass to the callback function
+    /// \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL)
+    /// \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure
+    pub fn libusb_hotplug_register_callback(
+        ctx: *mut libusb_context,
+        events: libusb_hotplug_event,
+        flags: libusb_hotplug_flag,
+        vendor_id: ::std::os::raw::c_int,
+        product_id: ::std::os::raw::c_int,
+        dev_class: ::std::os::raw::c_int,
+        cb_fn: libusb_hotplug_callback_fn,
+        user_data: *mut ::std::os::raw::c_void,
+        callback_handle: *mut libusb_hotplug_callback_handle,
+    ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+    /// \ingroup libusb_hotplug
+    /// Deregisters a hotplug callback.
+    ///
+    /// Deregister a callback from a libusb_context. This function is safe to call from within
+    /// a hotplug callback.
+    ///
+    /// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+    ///
+    /// \param[in] ctx context this callback is registered with
+    /// \param[in] callback_handle the handle of the callback to deregister
+    pub fn libusb_hotplug_deregister_callback(
+        ctx: *mut libusb_context,
+        callback_handle: libusb_hotplug_callback_handle,
+    );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __locale_data {
+    pub _address: u8,
+}
diff --git a/usb_util/src/config_descriptor.rs b/usb_util/src/config_descriptor.rs
new file mode 100644
index 0000000..37bd7d6
--- /dev/null
+++ b/usb_util/src/config_descriptor.rs
@@ -0,0 +1,32 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use bindings;
+use bindings::libusb_config_descriptor;
+
+/// ConfigDescriptor wraps libusb_config_descriptor.
+/// TODO(jkwang) Add utility functions to make ConfigDescriptor actually useful.
+pub struct ConfigDescriptor {
+    descriptor: *mut libusb_config_descriptor,
+}
+
+impl Drop for ConfigDescriptor {
+    // Free configuration descriptor.
+    // Safe because 'self' is intialized with a valid libusb_config_descriptor from libusb
+    // functions.
+    fn drop(&mut self) {
+        unsafe {
+            bindings::libusb_free_config_descriptor(self.descriptor);
+        }
+    }
+}
+
+impl ConfigDescriptor {
+    /// Build ConfigDescriptor. 'descriptor' should be a valid pointer from
+    /// libusb_config_descriptor. This function will panic if it's null.
+    pub unsafe fn new(descriptor: *mut libusb_config_descriptor) -> ConfigDescriptor {
+        assert!(!descriptor.is_null());
+        ConfigDescriptor { descriptor }
+    }
+}
diff --git a/usb_util/src/device_handle.rs b/usb_util/src/device_handle.rs
new file mode 100644
index 0000000..e07f6f2
--- /dev/null
+++ b/usb_util/src/device_handle.rs
@@ -0,0 +1,129 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use std::os::raw::c_int;
+use std::sync::Arc;
+
+use bindings;
+use error::{Error, Result};
+use libusb_context::LibUsbContextInner;
+
+/// DeviceHandle wraps libusb_device_handle.
+pub struct DeviceHandle {
+    _context: Arc<LibUsbContextInner>,
+    handle: *mut bindings::libusb_device_handle,
+}
+
+unsafe impl Send for DeviceHandle {}
+
+impl Drop for DeviceHandle {
+    fn drop(&mut self) {
+        // Safe because self.handle is a valid pointer to libusb_device_handle.
+        unsafe {
+            bindings::libusb_close(self.handle);
+        }
+    }
+}
+
+impl DeviceHandle {
+    /// Create a new DeviceHande. 'handle' should be a valid pointer to libusb_device_handle.
+    pub unsafe fn new(
+        ctx: Arc<LibUsbContextInner>,
+        handle: *mut bindings::libusb_device_handle,
+    ) -> DeviceHandle {
+        DeviceHandle {
+            _context: ctx,
+            handle,
+        }
+    }
+
+    /// Get bConfigurationValue of the currently active configuration.
+    pub fn get_active_configuration(&self) -> Result<i32> {
+        let mut config: c_int = 0;
+        // Safe because 'self.handle' is a valid pointer to device handle and '&mut config' is a
+        // valid output location.
+        try_libusb!(unsafe { bindings::libusb_get_configuration(self.handle, &mut config) });
+        Ok(config as i32)
+    }
+
+    /// Set active configuration for a device.
+    pub fn set_active_configuration(&mut self, config: i32) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe { bindings::libusb_set_configuration(self.handle, config as c_int) });
+        Ok(())
+    }
+
+    /// Claim an interface on this deivce handle.
+    pub fn claim_interface(&self, interface_number: i32) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe { bindings::libusb_claim_interface(self.handle, interface_number) });
+        Ok(())
+    }
+
+    /// Release an interface previously claimed with libusb_claim_interface.
+    pub fn release_interface(&self, interface_number: i32) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe { bindings::libusb_release_interface(self.handle, interface_number) });
+        Ok(())
+    }
+
+    /// Perform a USB port reset to reinitialize a device.
+    pub fn reset_device(&self) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe { bindings::libusb_reset_device(self.handle) });
+        Ok(())
+    }
+
+    /// Determine if a kernel driver is active on an interface.
+    pub fn kernel_driver_active(&self, interface_number: i32) -> Result<bool> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        let v = try_libusb!(unsafe {
+            bindings::libusb_kernel_driver_active(self.handle, interface_number)
+        });
+        Ok(v != 0)
+    }
+
+    /// Detach a kernel driver from an interface.
+    pub fn detach_kernel_driver(&self, interface_number: i32) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe {
+            bindings::libusb_detach_kernel_driver(self.handle, interface_number)
+        });
+        Ok(())
+    }
+
+    /// Re-attach an interfae's kernel driver, which was previously detached using
+    /// detach_kernel_driver.
+    pub fn attach_kernel_driver(&self, interface_number: i32) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe {
+            bindings::libusb_attach_kernel_driver(self.handle, interface_number)
+        });
+        Ok(())
+    }
+
+    /// Active an alternate setting for an interface.
+    pub fn set_interface_alt_setting(
+        &self,
+        interface_number: i32,
+        alternative_setting: i32,
+    ) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe {
+            bindings::libusb_set_interface_alt_setting(
+                self.handle,
+                interface_number,
+                alternative_setting,
+            )
+        });
+        Ok(())
+    }
+
+    /// Clear the halt/stall condition for an endpoint.
+    pub fn clear_halt(&self, endpoint: u8) -> Result<()> {
+        // Safe because 'self.handle' is a valid pointer to device handle.
+        try_libusb!(unsafe { bindings::libusb_clear_halt(self.handle, endpoint) });
+        Ok(())
+    }
+}
diff --git a/usb_util/src/error.rs b/usb_util/src/error.rs
new file mode 100644
index 0000000..6ba5421
--- /dev/null
+++ b/usb_util/src/error.rs
@@ -0,0 +1,85 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use std;
+use std::fmt;
+
+use bindings;
+
+/// Error type for libusb.
+pub enum Error {
+    Success(i32),
+    IO,
+    InvalidParam,
+    Access,
+    NoDevice,
+    NotFound,
+    Busy,
+    Timeout,
+    Overflow,
+    Pipe,
+    Interrupted,
+    NoMem,
+    NotSupported,
+    Other,
+}
+
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            &Error::Success(_v) => write!(f, "Success (no error)"),
+            &Error::IO => write!(f, "Input/output error"),
+            &Error::InvalidParam => write!(f, "Invalid parameter"),
+            &Error::Access => write!(f, "Access denied (insufficient permissions)"),
+            &Error::NoDevice => write!(f, "No such device (it may have been disconnected)"),
+            &Error::NotFound => write!(f, "Entity not found"),
+            &Error::Busy => write!(f, "Resource busy"),
+            &Error::Timeout => write!(f, "Operation timed out"),
+            &Error::Overflow => write!(f, "Overflow"),
+            &Error::Pipe => write!(f, "Pipe error"),
+            &Error::Interrupted => write!(f, "System call interrupted (perhaps due to signal)"),
+            &Error::NoMem => write!(f, "Insufficient memory"),
+            &Error::NotSupported => write!(
+                f,
+                "Operation not supported or unimplemented on this platform"
+            ),
+            &Error::Other => write!(f, "Other error"),
+        }
+    }
+}
+
+impl From<bindings::libusb_error> for Error {
+    fn from(e: bindings::libusb_error) -> Self {
+        match e {
+            bindings::LIBUSB_ERROR_IO => Error::IO,
+            bindings::LIBUSB_ERROR_INVALID_PARAM => Error::InvalidParam,
+            bindings::LIBUSB_ERROR_ACCESS => Error::Access,
+            bindings::LIBUSB_ERROR_NO_DEVICE => Error::NoDevice,
+            bindings::LIBUSB_ERROR_NOT_FOUND => Error::NotFound,
+            bindings::LIBUSB_ERROR_BUSY => Error::Busy,
+            bindings::LIBUSB_ERROR_TIMEOUT => Error::Timeout,
+            bindings::LIBUSB_ERROR_OVERFLOW => Error::Overflow,
+            bindings::LIBUSB_ERROR_PIPE => Error::Pipe,
+            bindings::LIBUSB_ERROR_INTERRUPTED => Error::Interrupted,
+            bindings::LIBUSB_ERROR_NO_MEM => Error::NoMem,
+            bindings::LIBUSB_ERROR_NOT_SUPPORTED => Error::NotSupported,
+            bindings::LIBUSB_ERROR_OTHER => Error::Other,
+            // All possible errors are defined above, other values mean success,
+            // see libusb_get_device_list for example.
+            _ => Error::Success(e),
+        }
+    }
+}
+
+pub type Result<T> = std::result::Result<T, Error>;
+
+#[macro_export]
+macro_rules! try_libusb {
+    ($x:expr) => {
+        match Error::from($x as i32) {
+            Error::Success(e) => e,
+            err => return Err(err),
+        }
+    };
+}
diff --git a/usb_util/src/lib.rs b/usb_util/src/lib.rs
new file mode 100644
index 0000000..0860d71
--- /dev/null
+++ b/usb_util/src/lib.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Generated with bindgen libusb.h -no-prepend-enum-name -o bindings.rs.
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+mod bindings;
+
+extern crate data_model;
+#[macro_use]
+pub mod error;
+pub mod config_descriptor;
+pub mod device_handle;
+pub mod libusb_context;
+pub mod libusb_device;
+pub mod types;
diff --git a/usb_util/src/libusb_context.rs b/usb_util/src/libusb_context.rs
new file mode 100644
index 0000000..821d2ad
--- /dev/null
+++ b/usb_util/src/libusb_context.rs
@@ -0,0 +1,156 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use std;
+
+use bindings;
+use error::{Error, Result};
+use libusb_device::LibUsbDevice;
+use std::sync::Arc;
+
+pub struct LibUsbContextInner {
+    context: *mut bindings::libusb_context,
+}
+
+// Safe because libusb_context could be accessed from multiple threads safely.
+unsafe impl Send for LibUsbContextInner {}
+unsafe impl Sync for LibUsbContextInner {}
+
+impl Drop for LibUsbContextInner {
+    fn drop(&mut self) {
+        // Safe beacuse 'self.context' points to a valid context allocated by libusb_init.
+        unsafe {
+            bindings::libusb_exit(self.context);
+        }
+    }
+}
+
+/// Wrapper for libusb_context. The libusb libary initialization/deinitialization
+/// is managed by this context.
+/// See: http://libusb.sourceforge.net/api-1.0/group__libusb__lib.html
+#[derive(Clone)]
+pub struct LibUsbContext {
+    inner: Arc<LibUsbContextInner>,
+}
+
+impl LibUsbContext {
+    /// Create a new LibUsbContext.
+    pub fn new() -> Result<LibUsbContext> {
+        let mut ctx: *mut bindings::libusb_context = std::ptr::null_mut();
+        // Safe because '&mut ctx' points to a valid memory (on stack).
+        try_libusb!(unsafe { bindings::libusb_init(&mut ctx) });
+        Ok(LibUsbContext {
+            inner: Arc::new(LibUsbContextInner { context: ctx }),
+        })
+    }
+
+    /// Returns a list of USB devices currently attached to the system.
+    pub fn get_device_iter(&self) -> Result<DeviceIter> {
+        let mut list: *mut *mut bindings::libusb_device = std::ptr::null_mut();
+        // Safe because 'inner.context' points to a valid context and '&mut list' points to a valid
+        // memory.
+        try_libusb!(unsafe { bindings::libusb_get_device_list(self.inner.context, &mut list) });
+
+        Ok(DeviceIter {
+            context: self.inner.clone(),
+            list,
+            index: 0,
+        })
+    }
+
+    /// Check at runtime if the loaded library has a given capability.
+    pub fn has_capability(&self, cap: u32) -> bool {
+        // Safe because libusb_init is called before this call happens.
+        unsafe { bindings::libusb_has_capability(cap) != 0 }
+    }
+
+    /// Return an iter of poll fds. Those fds that should be polled to handle libusb events.
+    pub fn get_pollfd_iter(&self) -> PollFdIter {
+        // Safe because 'inner.context' is inited.
+        let list: *mut *const bindings::libusb_pollfd =
+            unsafe { bindings::libusb_get_pollfds(self.inner.context) };
+        PollFdIter { list, index: 0 }
+    }
+
+    /// Handle libusb events in a non block way.
+    pub fn handle_event_nonblock(&self) {
+        static mut zero_time: bindings::timeval = bindings::timeval {
+            tv_sec: 0,
+            tv_usec: 0,
+        };
+        // Safe because 'inner.context' points to valid context.
+        unsafe {
+            bindings::libusb_handle_events_timeout_completed(
+                self.inner.context,
+                &mut zero_time as *mut bindings::timeval,
+                std::ptr::null_mut(),
+            );
+        }
+    }
+}
+
+/// Iterator for device list.
+pub struct DeviceIter {
+    context: Arc<LibUsbContextInner>,
+    list: *mut *mut bindings::libusb_device,
+    index: isize,
+}
+
+impl Drop for DeviceIter {
+    fn drop(&mut self) {
+        // Safe because 'self.list' is inited by a valid pointer from libusb_get_device_list.
+        unsafe {
+            bindings::libusb_free_device_list(self.list, 1);
+        }
+    }
+}
+
+impl Iterator for DeviceIter {
+    type Item = LibUsbDevice;
+
+    fn next(&mut self) -> Option<LibUsbDevice> {
+        // Safe becuase 'self.list' is valid, the list is null terminated.
+        unsafe {
+            let current_ptr = self.list.offset(self.index);
+            if (*current_ptr).is_null() {
+                return None;
+            }
+            self.index += 1;
+            Some(LibUsbDevice::new(self.context.clone(), *current_ptr))
+        }
+    }
+}
+
+/// Iterator for pollfds.
+pub struct PollFdIter {
+    list: *mut *const bindings::libusb_pollfd,
+    index: isize,
+}
+
+impl Drop for PollFdIter {
+    fn drop(&mut self) {
+        // Safe because 'self.list' points to valid memory of pollfd list.
+        unsafe {
+            bindings::libusb_free_pollfds(self.list);
+        }
+    }
+}
+
+impl Iterator for PollFdIter {
+    type Item = bindings::libusb_pollfd;
+
+    fn next(&mut self) -> Option<bindings::libusb_pollfd> {
+        // Safe because 'self.index' never grow out of the null pointer index.
+        unsafe {
+            let current_ptr = self.list.offset(self.index);
+            if (*current_ptr).is_null() {
+                return None;
+            }
+
+            self.index += 1;
+            // Safe because 'current_ptr' is not null.
+            Some((**current_ptr).clone())
+        }
+    }
+}
diff --git a/usb_util/src/libusb_device.rs b/usb_util/src/libusb_device.rs
new file mode 100644
index 0000000..fa248df
--- /dev/null
+++ b/usb_util/src/libusb_device.rs
@@ -0,0 +1,109 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use std;
+
+use bindings;
+use config_descriptor::ConfigDescriptor;
+use device_handle::DeviceHandle;
+use error::{Error, Result};
+use libusb_context::LibUsbContextInner;
+use std::sync::Arc;
+use types::Speed;
+
+pub type DeviceDescriptor = bindings::libusb_device_descriptor;
+
+/// LibUsbDevice wraps libusb_device.
+pub struct LibUsbDevice {
+    _context: Arc<LibUsbContextInner>,
+    device: *mut bindings::libusb_device,
+}
+
+unsafe impl Send for LibUsbDevice {}
+
+impl Drop for LibUsbDevice {
+    fn drop(&mut self) {
+        // Safe because 'self.device' is a valid pointer and libusb_ref_device is invoked when
+        // 'self' is built.
+        unsafe {
+            bindings::libusb_unref_device(self.device);
+        }
+    }
+}
+
+impl LibUsbDevice {
+    /// Create a new LibUsbDevice. 'device' should be a valid pointer to libusb_device.
+    pub unsafe fn new(
+        ctx: Arc<LibUsbContextInner>,
+        device: *mut bindings::libusb_device,
+    ) -> LibUsbDevice {
+        bindings::libusb_ref_device(device);
+        LibUsbDevice {
+            _context: ctx,
+            device,
+        }
+    }
+
+    /// Get device descriptor of this device.
+    pub fn get_device_descriptor(&self) -> Result<DeviceDescriptor> {
+        // Safe because memory is initialized later.
+        let mut descriptor: bindings::libusb_device_descriptor =
+            unsafe { std::mem::uninitialized() };
+        // Safe because 'self.device' is valid and '&mut descriptor' is valid.
+        try_libusb!(unsafe {
+            bindings::libusb_get_device_descriptor(self.device, &mut descriptor)
+        });
+        Ok(descriptor)
+    }
+
+    /// Get config descriptor at index of idx.
+    pub fn get_config_descriptor(&self, idx: u8) -> Result<ConfigDescriptor> {
+        let mut descriptor: *mut bindings::libusb_config_descriptor = std::ptr::null_mut();
+        // Safe because 'self.device' is valid and '&mut descriptor' is valid.
+        try_libusb!(unsafe {
+            bindings::libusb_get_config_descriptor(self.device, idx, &mut descriptor)
+        });
+        // Safe because descriptor is inited with valid pointer.
+        Ok(unsafe { ConfigDescriptor::new(descriptor) })
+    }
+
+    /// Get active config descriptor of this device.
+    pub fn get_active_config_descriptor(&self) -> Result<ConfigDescriptor> {
+        let mut descriptor: *mut bindings::libusb_config_descriptor = std::ptr::null_mut();
+        // Safe because 'self.device' is valid and '&mut descriptor' is valid.
+        try_libusb!(unsafe {
+            bindings::libusb_get_active_config_descriptor(self.device, &mut descriptor)
+        });
+        // Safe becuase descriptor points to valid memory.
+        Ok(unsafe { ConfigDescriptor::new(descriptor) })
+    }
+
+    /// Get bus number of this device.
+    pub fn get_bus_number(&self) -> u8 {
+        // Safe because 'self.device' is valid.
+        unsafe { bindings::libusb_get_bus_number(self.device) }
+    }
+
+    /// Get address of this device.
+    pub fn get_address(&self) -> u8 {
+        // Safe because 'self.device' is valid.
+        unsafe { bindings::libusb_get_device_address(self.device) }
+    }
+
+    /// Get speed of this device.
+    pub fn get_speed(&self) -> Speed {
+        // Safe because 'self.device' is valid.
+        let speed = unsafe { bindings::libusb_get_device_speed(self.device) };
+        Speed::from(speed as u32)
+    }
+
+    /// Get device handle of this device.
+    pub fn open(&self) -> Result<DeviceHandle> {
+        let mut handle: *mut bindings::libusb_device_handle = std::ptr::null_mut();
+        // Safe because 'self.device' is valid and handle is on stack.
+        try_libusb!(unsafe { bindings::libusb_open(self.device, &mut handle) });
+        // Safe because handle points to valid memory.
+        Ok(unsafe { DeviceHandle::new(self._context.clone(), handle) })
+    }
+}
diff --git a/usb_util/src/types.rs b/usb_util/src/types.rs
new file mode 100644
index 0000000..59bb5ed
--- /dev/null
+++ b/usb_util/src/types.rs
@@ -0,0 +1,198 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use bindings;
+use data_model::DataInit;
+
+/// Speed of usb device. See usb spec for more details.
+#[derive(Debug)]
+pub enum Speed {
+    /// The OS doesn't report or know the device speed.
+    Unknown,
+    /// The device is operating at low speed (1.5MBit/s).
+    Low,
+    /// The device is operating at full speed (12MBit/s).
+    Full,
+    /// The device is operating at high speed (480MBit/s).
+    High,
+    /// The device is operating at super speed (5000MBit/s).
+    Super,
+}
+
+impl From<bindings::libusb_speed> for Speed {
+    fn from(speed: bindings::libusb_speed) -> Speed {
+        match speed {
+            bindings::LIBUSB_SPEED_LOW => Speed::Low,
+            bindings::LIBUSB_SPEED_FULL => Speed::Full,
+            bindings::LIBUSB_SPEED_HIGH => Speed::High,
+            bindings::LIBUSB_SPEED_SUPER => Speed::Super,
+            _ => Speed::Unknown,
+        }
+    }
+}
+
+/// Endpoint types.
+#[derive(PartialEq)]
+pub enum EndpointType {
+    Control,
+    Isochronous,
+    Bulk,
+    Interrupt,
+}
+
+/// Endpoint Directions.
+#[derive(PartialEq, Clone, Copy)]
+pub enum EndpointDirection {
+    HostToDevice = 0,
+    DeviceToHost = 1,
+}
+/// Endpoint direction offset.
+pub const ENDPOINT_DIRECTION_OFFSET: u8 = 7;
+
+/// Offset of data phase transfer direction.
+pub const DATA_PHASE_DIRECTION_OFFSET: u8 = 7;
+/// Bit mask of data phase transfer direction.
+pub const DATA_PHASE_DIRECTION: u8 = 1u8 << DATA_PHASE_DIRECTION_OFFSET;
+// Types of data phase transfer directions.
+#[derive(PartialEq)]
+pub enum ControlRequestDataPhaseTransferDirection {
+    HostToDevice = 0,
+    DeviceToHost = 1,
+}
+
+/// Offset of control request type.
+pub const CONTROL_REQUEST_TYPE_OFFSET: u8 = 5;
+/// Bit mask of control request type.
+pub const CONTROL_REQUEST_TYPE: u8 = 0b11 << CONTROL_REQUEST_TYPE_OFFSET;
+/// Request types.
+#[derive(PartialEq)]
+pub enum ControlRequestType {
+    Standard = 0,
+    Class = 1,
+    Vendor = 2,
+    Reserved = 3,
+}
+
+/// Recipient type bits.
+pub const REQUEST_RECIPIENT_TYPE: u8 = 0b1111;
+/// Recipient type of control request.
+#[derive(PartialEq)]
+pub enum ControlRequestRecipient {
+    Device = 0,
+    Interface = 1,
+    Endpoint = 2,
+    Other = 3,
+    Reserved,
+}
+
+/// Standard request defined in usb spec.
+#[derive(PartialEq)]
+pub enum StandardControlRequest {
+    GetStatus = 0x00,
+    ClearFeature = 0x01,
+    SetFeature = 0x03,
+    SetAddress = 0x05,
+    GetDescriptor = 0x06,
+    SetDescriptor = 0x07,
+    GetConfiguration = 0x08,
+    SetConfiguration = 0x09,
+    GetInterface = 0x0a,
+    SetInterface = 0x11,
+    SynchFrame = 0x12,
+}
+
+/// RequestSetup is first part of control transfer buffer.
+#[repr(C, packed)]
+#[derive(Copy, Clone, Debug)]
+pub struct UsbRequestSetup {
+    // USB Device Request. USB spec. rev. 2.0 9.3
+    pub request_type: u8, // bmRequestType
+    pub request: u8,      // bRequest
+    pub value: u16,       // wValue
+    pub index: u16,       // wIndex
+    pub length: u16,      // wLength
+}
+
+unsafe impl DataInit for UsbRequestSetup {}
+
+impl UsbRequestSetup {
+    pub fn new(
+        request_type: u8,
+        request: u8,
+        value: u16,
+        index: u16,
+        length: u16,
+    ) -> UsbRequestSetup {
+        UsbRequestSetup {
+            request_type,
+            request,
+            value,
+            index,
+            length,
+        }
+    }
+
+    /// Get type of request.
+    pub fn get_type(&self) -> Option<ControlRequestType> {
+        let ty = (self.request_type & CONTROL_REQUEST_TYPE) >> CONTROL_REQUEST_TYPE_OFFSET;
+        match ty {
+            0 => Some(ControlRequestType::Standard),
+            1 => Some(ControlRequestType::Class),
+            2 => Some(ControlRequestType::Vendor),
+            3 => Some(ControlRequestType::Reserved),
+            _ => None,
+        }
+    }
+
+    /// Get request direction.
+    pub fn get_direction(&self) -> Option<ControlRequestDataPhaseTransferDirection> {
+        let dir = (self.request_type & DATA_PHASE_DIRECTION) >> DATA_PHASE_DIRECTION_OFFSET;
+        match dir {
+            0 => Some(ControlRequestDataPhaseTransferDirection::HostToDevice),
+            1 => Some(ControlRequestDataPhaseTransferDirection::DeviceToHost),
+            _ => None,
+        }
+    }
+
+    /// Get recipient of this control transfer.
+    pub fn get_recipient(&self) -> ControlRequestRecipient {
+        let recipienet = self.request_type & REQUEST_RECIPIENT_TYPE;
+        match recipienet {
+            0 => ControlRequestRecipient::Device,
+            1 => ControlRequestRecipient::Interface,
+            2 => ControlRequestRecipient::Endpoint,
+            3 => ControlRequestRecipient::Other,
+            _ => ControlRequestRecipient::Reserved,
+        }
+    }
+
+    /// Return the type of standard control request.
+    pub fn get_standard_request(&self) -> Option<StandardControlRequest> {
+        match self.request {
+            0x00 => Some(StandardControlRequest::GetStatus),
+            0x01 => Some(StandardControlRequest::ClearFeature),
+            0x03 => Some(StandardControlRequest::SetFeature),
+            0x05 => Some(StandardControlRequest::SetAddress),
+            0x06 => Some(StandardControlRequest::GetDescriptor),
+            0x07 => Some(StandardControlRequest::SetDescriptor),
+            0x08 => Some(StandardControlRequest::GetConfiguration),
+            0x09 => Some(StandardControlRequest::SetConfiguration),
+            0x0a => Some(StandardControlRequest::GetInterface),
+            0x11 => Some(StandardControlRequest::SetInterface),
+            0x12 => Some(StandardControlRequest::SynchFrame),
+            _ => None,
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::mem::size_of;
+
+    #[test]
+    fn check_request_setup_size() {
+        assert_eq!(size_of::<UsbRequestSetup>(), 8);
+    }
+}