summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2011-03-09 00:35:55 +0000
committerPete Batard <pbatard@gmail.com>2011-03-09 00:35:55 +0000
commit328439204a53a81ec8f11fbb7218a612e5a6e0c9 (patch)
treebc915aed63510c37d19237767104c26ea924b493
parentfc8743533d6cc5beccf00d276cfcdd3af4793bd0 (diff)
downloadlibusb-328439204a53a81ec8f11fbb7218a612e5a6e0c9.tar.gz
merge -> pbr336
-rw-r--r--_README.txt14
-rw-r--r--_bd.cmd2
-rw-r--r--_bm.sh8
-rwxr-xr-xautogen.sh4
-rw-r--r--configure.ac103
-rw-r--r--examples/xusb.c322
-rw-r--r--libusb/Makefile.am6
-rw-r--r--libusb/core.c1
-rw-r--r--libusb/io.c63
-rw-r--r--libusb/libusb-1.0.def368
-rw-r--r--libusb/libusb.h3
-rw-r--r--libusb/libusbi.h6
-rw-r--r--libusb/os/darwin_usb.c57
-rw-r--r--libusb/os/darwin_usb.h2
-rw-r--r--libusb/os/linux_usbfs.c162
-rw-r--r--libusb/os/poll_posix.h2
-rw-r--r--libusb/os/poll_windows.h2
-rw-r--r--libusb/os/windows_usb.c1223
-rw-r--r--libusb/os/windows_usb.h182
-rw-r--r--libusb/sync.c8
-rw-r--r--msvc/config.h10
21 files changed, 524 insertions, 2024 deletions
diff --git a/_README.txt b/_README.txt
index fd9d809..00bf27f 100644
--- a/_README.txt
+++ b/_README.txt
@@ -7,9 +7,9 @@
o Visual Studio:
- Open existing or create a new project for your application
- - Copy the libusb.h into your project and make sure that the location where
- the file reside appears in the 'Additional Include Directories' section
- (Configuration Properties -> C/C++ -> General).
+ - Copy libusb.h, from the include\libusb-1.0\ directory, into your project and
+ make sure that the location where the file reside appears in the 'Additional
+ Include Directories' section (Configuration Properties -> C/C++ -> General).
- Copy the relevant .lib file from MS32\ or MS64\ and add 'libusb-1.0.lib' to
your 'Additional Dependencies' (Configuration Properties -> Linker -> Input)
Also make sure that the directory where libusb-1.0.lib resides is added to
@@ -43,10 +43,10 @@ o WDK/DDK:
easily be achieved, in the DDK environment, by running 'ddk_build /MT'
o MinGW/cygwin
- - Copy libusb.h to your default include directory and the relevant MinGW32\ or
- MinGW64\ .a file to your default library directory. Or, if you don't want to
- use the default locations, make sure that you feed the relevant -I and -L
- options to the compiler.
+ - Copy libusb.h, from include/libusb-1.0/ to your default include directory,
+ and copy the MinGW32/ or MinGW64/ .a files to your default library directory.
+ Or, if you don't want to use the default locations, make sure that you feed
+ the relevant -I and -L options to the compiler.
- Add the '-lusb-1.0' linker option when compiling.
o Additional information:
diff --git a/_bd.cmd b/_bd.cmd
index 7e148cd..1f4bbcb 100644
--- a/_bd.cmd
+++ b/_bd.cmd
@@ -9,8 +9,6 @@ for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A
for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A\static
for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A\dll
for %%A in (source bin32 bin64) do mkdir E:\dailies\%DATE%\examples\%%A
-copy libusb\libusb.h E:\dailies\%DATE%\
-copy libusb\libusb-1.0.def E:\dailies\%DATE%\
copy examples\lsusb.c E:\dailies\%DATE%\examples\source
copy examples\xusb.c E:\dailies\%DATE%\examples\source
copy msvc\stdint.h E:\dailies\%DATE%\examples\source
diff --git a/_bm.sh b/_bm.sh
index 346d58e..df10267 100644
--- a/_bm.sh
+++ b/_bm.sh
@@ -3,12 +3,16 @@
# !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!!
date=`date +%Y.%m.%d`
+target=e:/dailies/$date
+mkdir -p $target/include/libusb-1.0
+cp -v libusb/libusb-1.0.def $target
+cp -v libusb/libusb.h $target/include/libusb-1.0
#
# 32 bit binaries
#
target=e:/dailies/$date/MinGW32
-git clean -f -d -x
+git clean -fdx
# Not using debug (-g) in CFLAGS DRAMATICALLY reduces the size of the binaries
export CFLAGS="-O2 -m32"
export LDFLAGS="-m32"
@@ -44,4 +48,4 @@ mkdir -p $target/static
mkdir -p $target/dll
cp -v libusb/.libs/libusb-1.0.a $target/static
cp -v libusb/.libs/libusb-1.0.dll $target/dll
-cp -v libusb/.libs/libusb-1.0.dll.a $target/dll \ No newline at end of file
+cp -v libusb/.libs/libusb-1.0.dll.a $target/dll
diff --git a/autogen.sh b/autogen.sh
index 739ebf8..5e13c09 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -6,7 +6,7 @@ create_def()
echo "rebuidling libusb-1.0.def file"
echo "LIBRARY" > libusb/libusb-1.0.def
echo "EXPORTS" >> libusb/libusb-1.0.def
- sed -n -e "s/.*API_EXPORTED.*\([[:blank:]]\)\(libusb.*\)(.*/ \2/p" libusb/*.c >> libusb/libusb-1.0.def~
+ sed -n -e "s/.*API_EXPORTED.*\([[:blank:]]\)\(libusb.*\)(.*/ \2/p" libusb/*.c > libusb/libusb-1.0.def~
sed -n -e "s/.*LIBUSB_CALL.*\([[:blank:]]\)\(libusb.*\)(.*/ \2/p" libusb/*.c >> libusb/libusb-1.0.def~
# We need to manually define a whole set of DLL aliases if we want the MS
# DLLs to be usable with dynamically linked MinGW executables. This is
@@ -14,7 +14,7 @@ create_def()
# calls in MinGW generated objects, and .def based MS generated DLLs don't
# have such a decoration => linking to MS DLL will fail without aliases.
# Currently, the maximum size is 32 and all sizes are multiples of 4
- for i in 00 04 08 12 16 20 24 28 32
+ for i in 0 4 8 12 16 20 24 28 32
do
sed -n -e "s/.*API_EXPORTED.*\([[:blank:]]\)\(libusb.*\)(.*/ \2@$i = \2/p" libusb/*.c >> libusb/libusb-1.0.def~
sed -n -e "s/.*LIBUSB_CALL.*\([[:blank:]]\)\(libusb.*\)(.*/ \2@$i = \2/p" libusb/*.c >> libusb/libusb-1.0.def~
diff --git a/configure.ac b/configure.ac
index cac9846..9540575 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,11 +17,11 @@ AC_SUBST([LIBUSB_VERSION_NANO], [LIBUSB_NANO])
lt_current="1"
lt_revision="0"
lt_age="1"
-AC_SUBST(lt_current)
-AC_SUBST(lt_revision)
-AC_SUBST(lt_age)
+LTLDFLAGS="-version-info ${lt_current}:${lt_revision}:${lt_age}"
AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
AC_CONFIG_SRCDIR([libusb/core.c])
AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER([config.h])
@@ -32,75 +32,71 @@ AC_PROG_CC
AC_PROG_LIBTOOL
AC_C_INLINE
AM_PROG_CC_C_O
-AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
+AC_DEFINE([_GNU_SOURCE], 1, [Use GNU extensions])
-AM_MAINTAINER_MODE
+LTLDFLAGS="${LTLDFLAGS} -no-undefined"
AC_MSG_CHECKING([operating system])
-PC_LIBS_PRIVATE=
case $host in
*-linux*)
- AC_DEFINE(OS_LINUX, [], [Linux backend])
+ AC_DEFINE(OS_LINUX, 1, [Linux backend])
AC_SUBST(OS_LINUX)
- AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
AC_MSG_RESULT([Linux])
backend="linux"
AC_CHECK_LIB(rt, clock_gettime, PC_LIBS_PRIVATE="-lrt")
- LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
threads="posix"
THREAD_CFLAGS="-pthread"
PC_LIBS_PRIVATE="${PC_LIBS_PRIVATE} -pthread"
- AM_CFLAGS="-std=gnu99"
- AM_LDFLAGS=""
+ AC_CHECK_HEADERS([poll.h])
+ AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
;;
*-darwin*)
- AC_DEFINE(OS_DARWIN, [], [Darwin backend])
+ AC_DEFINE(OS_DARWIN, 1, [Darwin backend])
AC_SUBST(OS_DARWIN)
- AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
- AC_MSG_RESULT([Darwin/MacOS X])
+ AC_MSG_RESULT([Darwin/Mac OS X])
backend="darwin"
threads="posix"
- THREAD_CFLAGS="-pthread"
- AM_CFLAGS="-std=gnu99"
- PC_LIBS_PRIVATE="-Wl,-framework,IOKit -Wl,-framework,CoreFoundation -Wl,-prebind -no-undefined -pthread"
- AM_LDFLAGS=${PC_LIBS_PRIVATE}
+ PC_LIBS_PRIVATE="-Wl,-framework,IOKit -Wl,-framework,CoreFoundation"
+ LTLDFLAGS="${LTLDFLAGS} -Wl,-prebind"
+ AC_CHECK_HEADERS([poll.h])
+ AC_CHECK_TYPE([nfds_t],
+ [AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])],
+ [AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument])],
+ [#include <poll.h>])
;;
*-mingw*)
- AC_DEFINE(OS_WINDOWS, [], [Windows backend])
- AC_SUBST(OS_WINDOWS)
AC_MSG_RESULT([Windows])
backend="windows"
- threads="windows"
- create_import_lib="yes"
- LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
- # -avoid-version to avoid a naming scheme such as libusb-0.dll
- AM_LDFLAGS="-no-undefined -avoid-version -Wl,--add-stdcall-alias"
- AM_CFLAGS="-std=c99"
- AC_CHECK_TOOL(RC, windres, no)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
;;
*-cygwin*)
- AC_DEFINE(OS_WINDOWS, [], [Windows backend])
- AC_SUBST(OS_WINDOWS)
- AC_DEFINE([THREADS_POSIX], [], [Use Posix Threads])
- AC_MSG_RESULT([Windows])
+ AC_MSG_RESULT([Cygwin (using Windows backend)])
backend="windows"
threads="posix"
- LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
- AM_CFLAGS="-std=gnu99"
- AM_LDFLAGS="-no-undefined -avoid-version"
- AC_CHECK_TOOL(RC, windres, no)
;;
*)
AC_MSG_ERROR([unsupported operating system])
esac
+if test "$backend" = windows; then
+ AC_DEFINE(OS_WINDOWS, 1, [Windows backend])
+ AC_SUBST(OS_WINDOWS)
+ PC_LIBS_PRIVATE=""
+ LTLDFLAGS="${LTLDFLAGS} -avoid-version -Wl,--add-stdcall-alias"
+ AC_CHECK_TOOL(RC, windres, no)
+ AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument])
+fi
+AC_SUBST(THREAD_CFLAGS)
AC_SUBST(PC_LIBS_PRIVATE)
-
-AM_CONDITIONAL([OS_LINUX], [test "x$backend" = "xlinux"])
-AM_CONDITIONAL([OS_DARWIN], [test "x$backend" = "xdarwin"])
-AM_CONDITIONAL([OS_WINDOWS], [test "x$backend" = "xwindows"])
-AM_CONDITIONAL([THREADS_POSIX], [test "x$threads" = "xposix"])
-AM_CONDITIONAL([CREATE_IMPORT_LIB], [test "x$create_import_lib" = "xyes"])
+LIBS="${LIBS} ${PC_LIBS_PRIVATE}"
+
+AM_CONDITIONAL(OS_LINUX, test "x$backend" = xlinux)
+AM_CONDITIONAL(OS_DARWIN, test "x$backend" = xdarwin)
+AM_CONDITIONAL(OS_WINDOWS, test "x$backend" = xwindows)
+AM_CONDITIONAL(THREADS_POSIX, test "x$threads" = xposix)
+AM_CONDITIONAL(CREATE_IMPORT_LIB, test "x$create_import_lib" = "xyes")
+if test "$threads" = posix; then
+ AC_DEFINE(THREADS_POSIX, 1, [Use POSIX Threads])
+fi
# timerfd
AC_CHECK_HEADER([sys/timerfd.h], [timerfd_h=1], [timerfd_h=0])
@@ -124,7 +120,7 @@ if test "x$use_timerfd" = "xno"; then
else
if test "x$timerfd_h" = "x1" -a "x$tfd_hdr_ok" = "xyes"; then
AC_MSG_RESULT([yes])
- AC_DEFINE(USBI_TIMERFD_AVAILABLE, [], [timerfd headers available])
+ AC_DEFINE(USBI_TIMERFD_AVAILABLE, 1, [timerfd headers available])
else
AC_MSG_RESULT([no (header not available)])
fi
@@ -168,14 +164,14 @@ AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
# Restore gnu89 inline semantics on gcc 4.3 and newer
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fgnu89-inline"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="")
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], inline_cflags="-fgnu89-inline", inline_cflags="")
CFLAGS="$saved_cflags"
# check for -fvisibility=hidden compiler support (GCC >= 3.4)
saved_cflags="$CFLAGS"
# -Werror required for cygwin
CFLAGS="$CFLAGS -Werror -fvisibility=hidden"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
[VISIBILITY_CFLAGS="-fvisibility=hidden"
AC_DEFINE([DEFAULT_VISIBILITY], [__attribute__((visibility("default")))], [Default visibility]) ],
[ VISIBILITY_CFLAGS=""
@@ -186,7 +182,7 @@ CFLAGS="$saved_cflags"
# check for -Wno-pointer-sign compiler support (GCC >= 4)
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -Wno-pointer-sign"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
nopointersign_cflags="-Wno-pointer-sign", nopointersign_cflags="")
CFLAGS="$saved_cflags"
@@ -197,14 +193,17 @@ AM_CONDITIONAL([HAVE_SIGACTION], [test "x$have_sigaction" = "xyes"])
# headers not available on all platforms but required on others
AC_CHECK_HEADERS([sys/time.h])
-AC_SUBST([THREAD_CFLAGS])
-
-AM_CFLAGS="$AM_CFLAGS $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow"
+AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow"
AC_SUBST(VISIBILITY_CFLAGS)
AC_SUBST(AM_CFLAGS)
-AC_SUBST(AM_LDFLAGS)
-
-AC_CONFIG_FILES([libusb-1.0.pc] [Makefile] [libusb/Makefile] [libusb/libusb_version.h] [examples/Makefile] [doc/Makefile] [doc/doxygen.cfg])
+AC_SUBST(LTLDFLAGS)
+
+AC_CONFIG_FILES([libusb-1.0.pc])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([libusb/Makefile])
+AC_CONFIG_FILES([libusb/libusb_version.h])
+AC_CONFIG_FILES([examples/Makefile])
+AC_CONFIG_FILES([doc/Makefile])
+AC_CONFIG_FILES([doc/doxygen.cfg])
AC_OUTPUT
-
diff --git a/examples/xusb.c b/examples/xusb.c
index ed69f5a..0c03fb6 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -1,12 +1,9 @@
/*
- * xusb: libusb-winusb specific test program
- * Copyright (c) 2009-2010 Pete Batard <pbatard@gmail.com>
+ * xusb: Generic USB test program
+ * Copyright (c) 2009-2011 Pete Batard <pbatard@gmail.com>
* Based on lsusb, copyright (c) 2007 Daniel Drake <dsd@gentoo.org>
* With contributions to Mass Storage test by Alan Stern.
*
- * This test program tries to access an USB device through WinUSB.
- * To access your device, modify this source and add your VID/PID.
- *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -22,7 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <config.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -31,7 +27,7 @@
#include "libusb.h"
-#ifdef OS_WINDOWS
+#if defined(_MSC_VER)
#define msleep(msecs) Sleep(msecs)
#else
#include <unistd.h>
@@ -85,14 +81,9 @@ inline static int perr(char const *format, ...)
// HID Class-Specific Requests values. See section 7.2 of the HID specifications
#define HID_GET_REPORT 0x01
-#define HID_GET_IDLE 0x02
-#define HID_GET_PROTOCOL 0x03
#define HID_SET_REPORT 0x09
-#define HID_SET_IDLE 0x0A
-#define HID_SET_PROTOCOL 0x0B
#define HID_REPORT_TYPE_INPUT 0x01
#define HID_REPORT_TYPE_OUTPUT 0x02
-#define HID_REPORT_TYPE_FEATURE 0x03
// Mass Storage Requests values. See section 3 of the Bulk-Only Mass Storage Class specifications
#define BOMS_RESET 0xFF
@@ -138,10 +129,10 @@ static uint8_t cdb_length[256] = {
};
enum test_type {
+ USE_GENERIC,
+ USE_PS3,
USE_XBOX,
- USE_KEY,
- USE_JTAG,
- USE_HID,
+ USE_SCSI,
} test_mode;
uint16_t VID, PID;
@@ -173,7 +164,96 @@ void display_buffer_hex(unsigned char *buffer, unsigned size)
printf("\n" );
}
+int initalize_ps3(libusb_device_handle *handle)
+{
+ int r;
+ uint8_t input_report[49];
+ CALL_CHECK(libusb_control_transfer(handle, 0x80, 0x06, 0x0001, 0x0, input_report, 0x12, 1000));
+ CALL_CHECK(libusb_control_transfer(handle, 0x80, 0x06, 0x0002, 0x0, input_report, 0x09, 1000));
+ CALL_CHECK(libusb_control_transfer(handle, 0x80, 0x06, 0x0002, 0x0, input_report, 0x29, 1000));
+ CALL_CHECK(libusb_control_transfer(handle, 0xa1, 0x01, 0x03f2, 0x0, input_report, 0x11, 1000));
+ CALL_CHECK(libusb_control_transfer(handle, 0xa1, 0x01, 0x03f5, 0x0, input_report, 0x08, 1000));
+ return 0;
+}
+// The PS3 Controller is really a HID device that got its HID Report Descriptors
+// removed by Sony
+int display_ps3_status(libusb_device_handle *handle)
+{
+ int r;
+ uint8_t input_report[49];
+
+ //Ensure the controller is initialized and ready to send its state
+ initalize_ps3(handle);
+
+ printf("\nReading PS3 Input Report...\n");
+ CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
+ HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x01, 0, input_report, 49, 1000));
+ switch(input_report[2]){ /** Direction pad plus start, select, and joystick buttons */
+ case 0x01:
+ printf("\tSELECT pressed\n");
+ break;
+ case 0x02:
+ printf("\tLEFT 3 pressed\n");
+ break;
+ case 0x04:
+ printf("\tRIGHT 3 pressed\n");
+ break;
+ case 0x08:
+ printf("\tSTART presed\n");
+ break;
+ case 0x10:
+ printf("\tUP pressed\n");
+ break;
+ case 0x20:
+ printf("\tRIGHT pressed\n");
+ break;
+ case 0x40:
+ printf("\tDOWN pressed\n");
+ break;
+ case 0x80:
+ printf("\tLEFT pressed\n");
+ break;
+ }
+ switch(input_report[3]){ /** Shapes plus top right and left buttons */
+ case 0x01:
+ printf("\tLEFT 2 pressed\n");
+ break;
+ case 0x02:
+ printf("\tRIGHT 2 pressed\n");
+ break;
+ case 0x04:
+ printf("\tLEFT 1 pressed\n");
+ break;
+ case 0x08:
+ printf("\tRIGHT 1 presed\n");
+ break;
+ case 0x10:
+ printf("\tTRIANGLE pressed\n");
+ break;
+ case 0x20:
+ printf("\tCIRCLE pressed\n");
+ break;
+ case 0x40:
+ printf("\tCROSS pressed\n");
+ break;
+ case 0x80:
+ printf("\tSQUARE pressed\n");
+ break;
+ }
+ printf("\tPS button: %d\n", input_report[4]);
+ printf("\tLeft Analog (X,Y): (%d,%d)\n", input_report[6], input_report[7]);
+ printf("\tRight Analog (X,Y): (%d,%d)\n", input_report[8], input_report[9]);
+ printf("\tL2 Value: %d\tR2 Value: %d\n", input_report[18], input_report[19]);
+ printf("\tL1 Value: %d\tR1 Value: %d\n", input_report[20], input_report[21]);
+ printf("\tRoll (x axis): %d Yaw (y axis): %d Pitch (z axis) %d\n",
+ //(((input_report[42] + 128) % 256) - 128),
+ (int8_t)(input_report[42]),
+ (int8_t)(input_report[44]),
+ (int8_t)(input_report[46]));
+ printf("\tAcceleration: %d\n\n", (int8_t)(input_report[48]));
+ return 0;
+}
// The XBOX Controller is really a HID device that got its HID Report Descriptors
// removed by Microsoft.
// Input/Output reports described at http://euc.jp/periphs/xbox-controller.ja.html
@@ -441,166 +521,11 @@ int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t
fclose(fd);
}
}
+ free(data);
return 0;
}
-// HID
-int get_hid_record_size(uint8_t *hid_report_descriptor, int size, int type)
-{
- uint8_t i, j = 0;
- uint8_t offset;
- int record_size[3] = {0, 0, 0};
- int nb_bits = 0, nb_items = 0;
- bool found_bits, found_items, found_record_marker;
-
- found_bits = false;
- found_items = false;
- found_record_marker = false;
- for (i = hid_report_descriptor[0]+1; i < size; i += offset) {
- offset = (hid_report_descriptor[i]&0x03) + 1;
- if (offset == 4)
- offset = 5;
- switch (hid_report_descriptor[i] & 0xFC) {
- case 0x74: // bitsize
- nb_bits = hid_report_descriptor[i+1];
- found_bits = true;
- break;
- case 0x94: // count
- nb_items = 0;
- for (j=1; j<offset; j++) {
- nb_items = ((uint32_t)hid_report_descriptor[i+j]) << (8*(j-1));
- }
- found_items = true;
- break;
- case 0x80: // input
- found_record_marker = true;
- j = 0;
- break;
- case 0x90: // output
- found_record_marker = true;
- j = 1;
- break;
- case 0xb0: // feature
- found_record_marker = true;
- j = 2;
- break;
- case 0xC0: // end of collection
- nb_items = 0;
- nb_bits = 0;
- break;
- default:
- continue;
- }
- if (found_record_marker) {
- found_bits = false;
- found_items = false;
- found_record_marker = false;
- record_size[j] += nb_items*nb_bits;
- }
- }
- if ((type < HID_REPORT_TYPE_INPUT) || (type > HID_REPORT_TYPE_FEATURE)) {
- return 0;
- } else {
- return (record_size[type - HID_REPORT_TYPE_INPUT]+7)/8;
- }
-}
-
-int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
-{
- int r, size, descriptor_size;
- uint8_t hid_report_descriptor[256];
- uint8_t *report_buffer;
- FILE *fd;
- size_t junk;
-
- printf("\nReading HID Report Descriptors:\n");
- descriptor_size = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_INTERFACE,
- LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_REPORT<<8, 0, hid_report_descriptor, 256, 1000);
- if (descriptor_size < 0) {
- printf("failed\n");
- return -1;
- }
- display_buffer_hex(hid_report_descriptor, descriptor_size);
- if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) {
- junk = fwrite(hid_report_descriptor, 1, descriptor_size, fd);
- fclose(fd);
- }
-
- size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_FEATURE);
- if (size <= 0) {
- printf("\nSkipping Feature Report readout (None detected)\n");
- } else {
- report_buffer = calloc(size, 1);
- if (report_buffer == NULL) {
- return -1;
- }
-
- printf("\nReading Feature Report (length %d)...\n", size);
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
- HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer, (uint16_t)size, 5000);
- if (r >= 0) {
- display_buffer_hex(report_buffer, size);
- } else {
- switch(r) {
- case LIBUSB_ERROR_NOT_FOUND:
- printf(" No Feature Report available for this device\n");
- break;
- case LIBUSB_ERROR_PIPE:
- printf(" Detected stall - resetting pipe...\n");
- libusb_clear_halt(handle, 0);
- break;
- default:
- printf(" Error: %s\n", libusb_strerror(r));
- break;
- }
- }
- free(report_buffer);
- }
-
- size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT);
- if (size <= 0) {
- printf("\nSkipping Input Report readout (None detected)\n");
- } else {
- report_buffer = calloc(size, 1);
- if (report_buffer == NULL) {
- return -1;
- }
-
- printf("\nReading Input Report (length %d)...\n", size);
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, report_buffer, (uint16_t)size, 5000);
- if (r >= 0) {
- display_buffer_hex(report_buffer, size);
- } else {
- switch(r) {
- case LIBUSB_ERROR_TIMEOUT:
- printf(" Timeout! Please make sure you act on the device within the 5 seconds allocated...\n");
- break;
- case LIBUSB_ERROR_PIPE:
- printf(" Detected stall - resetting pipe...\n");
- libusb_clear_halt(handle, 0);
- break;
- default:
- printf(" Error: %s\n", libusb_strerror(r));
- break;
- }
- }
-
- // Attempt a bulk read from endpoint 0 (this should just return a raw input report)
- printf("\nTesting interrupt read using endpoint %02X...\n", endpoint_in);
- r = libusb_interrupt_transfer(handle, endpoint_in, report_buffer, size, &size, 5000);
- if (r >= 0) {
- display_buffer_hex(report_buffer, size);
- } else {
- printf(" %s\n", libusb_strerror(r));
- }
-
- free(report_buffer);
- }
- return 0;
-}
-
int test_device(uint16_t vid, uint16_t pid)
{
libusb_device_handle *handle;
@@ -614,7 +539,6 @@ int test_device(uint16_t vid, uint16_t pid)
// Attaching/detaching the kernel driver is only relevant for Linux
int iface_detached = -1;
#endif
- bool test_scsi = false;
struct libusb_device_descriptor dev_desc;
char string[128];
uint8_t string_index[3]; // indexes of the string descriptors
@@ -670,7 +594,7 @@ int test_device(uint16_t vid, uint16_t pid)
|| (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) )
&& (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) {
// Mass storage devices that can use basic SCSI commands
- test_scsi = true;
+ test_mode = USE_SCSI;
}
for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) {
endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k];
@@ -718,23 +642,21 @@ int test_device(uint16_t vid, uint16_t pid)
}
switch(test_mode) {
+ case USE_PS3:
+ CALL_CHECK(display_ps3_status(handle));
+ break;
case USE_XBOX:
CALL_CHECK(display_xbox_status(handle));
CALL_CHECK(set_xbox_actuators(handle, 128, 222));
msleep(2000);
CALL_CHECK(set_xbox_actuators(handle, 0, 0));
break;
- case USE_HID:
- test_hid(handle, endpoint_in);
- break;
+ case USE_SCSI:
+ CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out));
default:
break;
}
- if (test_scsi) {
- CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out));
- }
-
printf("\n");
for (iface = 0; iface<nb_ifaces; iface++) {
printf("Releasing interface %d...\n", iface);
@@ -765,10 +687,10 @@ int main(int argc, char** argv)
unsigned tmp_vid, tmp_pid;
uint16_t endian_test = 0xBE00;
- // Default to HID, expecting VID:PID
+ // Default to generic, expecting VID:PID
VID = 0;
PID = 0;
- test_mode = USE_HID;
+ test_mode = USE_GENERIC;
if (((uint8_t*)&endian_test)[0] == 0xBE) {
printf("Despite their natural superiority for end users, big endian\n"
@@ -793,13 +715,7 @@ int main(int argc, char** argv)
}
binary_dump = true;
break;
- case 'i':
- // IBM HID Optical mouse - 1 interface
- if (!VID && !PID) {
- VID = 0x04B3;
- PID = 0x3108;
- }
- test_mode = USE_HID;
+ case 'g':
break;
case 'j':
// OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
@@ -807,7 +723,6 @@ int main(int argc, char** argv)
VID = 0x15BA;
PID = 0x0004;
}
- test_mode = USE_JTAG;
break;
case 'k':
// Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
@@ -815,20 +730,13 @@ int main(int argc, char** argv)
VID = 0x0204;
PID = 0x6025;
}
- test_mode = USE_KEY;
break;
// The following tests will force VID:PID if already provided
- case 'l':
- // Plantronics DSP 400, 2 channel HID composite device - 1 HID interface
- VID = 0x047F;
- PID = 0x0CA1;
- test_mode = USE_HID;
- break;
- case 's':
- // Microsoft Sidewinder Precision Pro Joystick - 1 HID interface
- VID = 0x045E;
- PID = 0x0008;
- test_mode = USE_HID;
+ case 'p':
+ // Sony PS3 Controller - 1 interface
+ VID = 0x054C;
+ PID = 0x0268;
+ test_mode = USE_PS3;
break;
case 'x':
// Microsoft XBox Controller Type S - 1 interface
@@ -861,15 +769,14 @@ int main(int argc, char** argv)
}
if ((show_help) || (argc == 1) || (argc > 7)) {
- printf("usage: %s [-d] [-b [file]] [-h] [-i] [-j] [-k] [-l] [-s] [-x] [vid:pid]\n", argv[0]);
+ printf("usage: %s [-d] [-b [file]] [-h] [-i] [-j] [-k] [-x] [vid:pid]\n", argv[0]);
printf(" -h: display usage\n");
printf(" -d: enable debug output (if library was compiled with debug enabled)\n");
- printf(" -b: dump raw HID report descriptor or Mass Storage first block to binary file\n");
- printf(" -i: test generic HID device (default)\n");
+ printf(" -b: dump Mass Storage first block to binary file\n");
+ printf(" -g: short generic test (default)\n");
printf(" -k: test generic Mass Storage USB device (using WinUSB)\n");
printf(" -j: test FTDI based JTAG device (using WinUSB)\n");
- printf(" -l: test Plantronics Headset (using HID)\n");
- printf(" -s: test Microsoft Sidewinder Precision Pro (using HID)\n");
+ printf(" -p: test Sony PS3 SixAxis controller (using WinUSB)\n");
printf(" -x: test Microsoft XBox Controller Type S (using WinUSB)\n");
return 0;
}
@@ -889,4 +796,3 @@ int main(int argc, char** argv)
return 0;
}
-
diff --git a/libusb/Makefile.am b/libusb/Makefile.am
index 59eb5c4..2b6ca7b 100644
--- a/libusb/Makefile.am
+++ b/libusb/Makefile.am
@@ -1,7 +1,7 @@
all: libusb-1.0.la
if CREATE_IMPORT_LIB
# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
- $(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def libusb-1.0.def --dllname libusb-1.0.dll --output-lib .libs/libusb-1.0.dll.a
+ $(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname libusb-1.0.dll --output-lib .libs/libusb-1.0.dll.a
endif
lib_LTLIBRARIES = libusb-1.0.la
@@ -30,11 +30,11 @@ OS_SRC += os/threads_windows.c
endif
.rc.lo:
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(RC) $(RCFLAGS) -I. -i $< -o $@
endif
libusb_1_0_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) $(THREAD_CFLAGS)
-libusb_1_0_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(lt_current):$(lt_revision):$(lt_age)
+libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c sync.c $(OS_SRC) \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h \
os/threads_posix.h os/threads_windows.h \
diff --git a/libusb/core.c b/libusb/core.c
index f09c6cd..32811c1 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -706,7 +706,6 @@ int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev, u
// TODO: see how the other backends want to implement HCDs as parents
if (dev->port_number == 0)
break;
- usbi_dbg("another one (addy: %d)", dev->device_address);
if (--i<0) {
return LIBUSB_ERROR_OVERFLOW;
}
diff --git a/libusb/io.c b/libusb/io.c
index b23c76b..dd56857 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1793,7 +1793,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
{
int r;
struct usbi_pollfd *ipollfd;
- nfds_t nfds = 0;
+ POLL_NFDS_TYPE nfds = 0;
struct pollfd *fds;
int i = -1;
int timeout_ms;
@@ -1937,8 +1937,8 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
* non-blocking mode
* \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
-int API_EXPORTED libusb_handle_events_timeout_check(libusb_context *ctx,
- struct timeval *tv, int *completed)
+int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
+ struct timeval *tv)
{
int r;
struct timeval poll_timeout;
@@ -1952,12 +1952,8 @@ int API_EXPORTED libusb_handle_events_timeout_check(libusb_context *ctx,
retry:
if (libusb_try_lock_events(ctx) == 0) {
- r = 0;
- if (completed == NULL || !*completed) {
- /* we obtained the event lock: do our own event handling */
- usbi_dbg("doing our own event handling");
- r = handle_events(ctx, &poll_timeout);
- }
+ /* we obtained the event lock: do our own event handling */
+ r = handle_events(ctx, &poll_timeout);
libusb_unlock_events(ctx);
return r;
}
@@ -1966,18 +1962,16 @@ retry:
* notify event completion. */
libusb_lock_event_waiters(ctx);
- if (completed == NULL || !*completed) {
- if (!libusb_event_handler_active(ctx)) {
- /* we hit a race: whoever was event handling earlier finished in the
- * time it took us to reach this point. try the cycle again. */
- libusb_unlock_event_waiters(ctx);
- usbi_dbg("event handler was active but went away, retrying");
- goto retry;
- }
-
- usbi_dbg("another thread is doing event handling, wait for notification");
- r = libusb_wait_for_event(ctx, &poll_timeout);
+ if (!libusb_event_handler_active(ctx)) {
+ /* we hit a race: whoever was event handling earlier finished in the
+ * time it took us to reach this point. try the cycle again. */
+ libusb_unlock_event_waiters(ctx);
+ usbi_dbg("event handler was active but went away, retrying");
+ goto retry;
}
+
+ usbi_dbg("another thread is doing event handling");
+ r = libusb_wait_for_event(ctx, &poll_timeout);
libusb_unlock_event_waiters(ctx);
if (r < 0)
@@ -1988,21 +1982,6 @@ retry:
return 0;
}
-int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
- struct timeval *tv)
-{
- return libusb_handle_events_timeout_check(ctx, tv, NULL);
-}
-
-int API_EXPORTED libusb_handle_events_check(libusb_context *ctx,
- int *completed)
-{
- struct timeval tv;
- tv.tv_sec = 60;
- tv.tv_usec = 0;
- return libusb_handle_events_timeout_check(ctx, &tv, completed);
-}
-
/** \ingroup poll
* Handle any pending events in blocking mode. There is currently a timeout
* hardcoded at 60 seconds but we plan to make it unlimited in future. For
@@ -2017,7 +1996,7 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx)
struct timeval tv;
tv.tv_sec = 60;
tv.tv_usec = 0;
- return libusb_handle_events_timeout_check(ctx, &tv, NULL);
+ return libusb_handle_events_timeout(ctx, &tv);
}
/** \ingroup poll
@@ -2145,24 +2124,22 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
if (transfer->flags & (USBI_TRANSFER_TIMED_OUT | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
continue;
+ /* no timeout for this transfer? */
+ if (!timerisset(&transfer->timeout))
+ continue;
+
found = 1;
break;
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (!found) {
- usbi_dbg("all URBs have already been processed for timeouts");
+ usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
return 0;
}
next_timeout = &transfer->timeout;
- /* no timeout for next transfer */
- if (!timerisset(next_timeout)) {
- usbi_dbg("no URBs with timeouts, no timeout!");
- return 0;
- }
-
r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
if (r < 0) {
usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def
index d437796..1ae2756 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -1,602 +1,582 @@
LIBRARY
EXPORTS
libusb_alloc_transfer
- libusb_alloc_transfer@00 = libusb_alloc_transfer
- libusb_alloc_transfer@04 = libusb_alloc_transfer
- libusb_alloc_transfer@08 = libusb_alloc_transfer
+ libusb_alloc_transfer@0 = libusb_alloc_transfer
libusb_alloc_transfer@12 = libusb_alloc_transfer
libusb_alloc_transfer@16 = libusb_alloc_transfer
libusb_alloc_transfer@20 = libusb_alloc_transfer
libusb_alloc_transfer@24 = libusb_alloc_transfer
libusb_alloc_transfer@28 = libusb_alloc_transfer
libusb_alloc_transfer@32 = libusb_alloc_transfer
+ libusb_alloc_transfer@4 = libusb_alloc_transfer
+ libusb_alloc_transfer@8 = libusb_alloc_transfer
libusb_attach_kernel_driver
- libusb_attach_kernel_driver@00 = libusb_attach_kernel_driver
- libusb_attach_kernel_driver@04 = libusb_attach_kernel_driver
- libusb_attach_kernel_driver@08 = libusb_attach_kernel_driver
+ libusb_attach_kernel_driver@0 = libusb_attach_kernel_driver
libusb_attach_kernel_driver@12 = libusb_attach_kernel_driver
libusb_attach_kernel_driver@16 = libusb_attach_kernel_driver
libusb_attach_kernel_driver@20 = libusb_attach_kernel_driver
libusb_attach_kernel_driver@24 = libusb_attach_kernel_driver
libusb_attach_kernel_driver@28 = libusb_attach_kernel_driver
libusb_attach_kernel_driver@32 = libusb_attach_kernel_driver
+ libusb_attach_kernel_driver@4 = libusb_attach_kernel_driver
+ libusb_attach_kernel_driver@8 = libusb_attach_kernel_driver
libusb_bulk_transfer
- libusb_bulk_transfer@00 = libusb_bulk_transfer
- libusb_bulk_transfer@04 = libusb_bulk_transfer
- libusb_bulk_transfer@08 = libusb_bulk_transfer
+ libusb_bulk_transfer@0 = libusb_bulk_transfer
libusb_bulk_transfer@12 = libusb_bulk_transfer
libusb_bulk_transfer@16 = libusb_bulk_transfer
libusb_bulk_transfer@20 = libusb_bulk_transfer
libusb_bulk_transfer@24 = libusb_bulk_transfer
libusb_bulk_transfer@28 = libusb_bulk_transfer
libusb_bulk_transfer@32 = libusb_bulk_transfer
+ libusb_bulk_transfer@4 = libusb_bulk_transfer
+ libusb_bulk_transfer@8 = libusb_bulk_transfer
libusb_cancel_transfer
- libusb_cancel_transfer@00 = libusb_cancel_transfer
- libusb_cancel_transfer@04 = libusb_cancel_transfer
- libusb_cancel_transfer@08 = libusb_cancel_transfer
+ libusb_cancel_transfer@0 = libusb_cancel_transfer
libusb_cancel_transfer@12 = libusb_cancel_transfer
libusb_cancel_transfer@16 = libusb_cancel_transfer
libusb_cancel_transfer@20 = libusb_cancel_transfer
libusb_cancel_transfer@24 = libusb_cancel_transfer
libusb_cancel_transfer@28 = libusb_cancel_transfer
libusb_cancel_transfer@32 = libusb_cancel_transfer
+ libusb_cancel_transfer@4 = libusb_cancel_transfer
+ libusb_cancel_transfer@8 = libusb_cancel_transfer
libusb_claim_interface
- libusb_claim_interface@00 = libusb_claim_interface
- libusb_claim_interface@04 = libusb_claim_interface
- libusb_claim_interface@08 = libusb_claim_interface
+ libusb_claim_interface@0 = libusb_claim_interface
libusb_claim_interface@12 = libusb_claim_interface
libusb_claim_interface@16 = libusb_claim_interface
libusb_claim_interface@20 = libusb_claim_interface
libusb_claim_interface@24 = libusb_claim_interface
libusb_claim_interface@28 = libusb_claim_interface
libusb_claim_interface@32 = libusb_claim_interface
+ libusb_claim_interface@4 = libusb_claim_interface
+ libusb_claim_interface@8 = libusb_claim_interface
libusb_clear_halt
- libusb_clear_halt@00 = libusb_clear_halt
- libusb_clear_halt@04 = libusb_clear_halt
- libusb_clear_halt@08 = libusb_clear_halt
+ libusb_clear_halt@0 = libusb_clear_halt
libusb_clear_halt@12 = libusb_clear_halt
libusb_clear_halt@16 = libusb_clear_halt
libusb_clear_halt@20 = libusb_clear_halt
libusb_clear_halt@24 = libusb_clear_halt
libusb_clear_halt@28 = libusb_clear_halt
libusb_clear_halt@32 = libusb_clear_halt
+ libusb_clear_halt@4 = libusb_clear_halt
+ libusb_clear_halt@8 = libusb_clear_halt
libusb_close
- libusb_close@00 = libusb_close
- libusb_close@04 = libusb_close
- libusb_close@08 = libusb_close
+ libusb_close@0 = libusb_close
libusb_close@12 = libusb_close
libusb_close@16 = libusb_close
libusb_close@20 = libusb_close
libusb_close@24 = libusb_close
libusb_close@28 = libusb_close
libusb_close@32 = libusb_close
+ libusb_close@4 = libusb_close
+ libusb_close@8 = libusb_close
libusb_control_transfer
- libusb_control_transfer@00 = libusb_control_transfer
- libusb_control_transfer@04 = libusb_control_transfer
- libusb_control_transfer@08 = libusb_control_transfer
+ libusb_control_transfer@0 = libusb_control_transfer
libusb_control_transfer@12 = libusb_control_transfer
libusb_control_transfer@16 = libusb_control_transfer
libusb_control_transfer@20 = libusb_control_transfer
libusb_control_transfer@24 = libusb_control_transfer
libusb_control_transfer@28 = libusb_control_transfer
libusb_control_transfer@32 = libusb_control_transfer
+ libusb_control_transfer@4 = libusb_control_transfer
+ libusb_control_transfer@8 = libusb_control_transfer
libusb_detach_kernel_driver
- libusb_detach_kernel_driver@00 = libusb_detach_kernel_driver
- libusb_detach_kernel_driver@04 = libusb_detach_kernel_driver
- libusb_detach_kernel_driver@08 = libusb_detach_kernel_driver
+ libusb_detach_kernel_driver@0 = libusb_detach_kernel_driver
libusb_detach_kernel_driver@12 = libusb_detach_kernel_driver
libusb_detach_kernel_driver@16 = libusb_detach_kernel_driver
libusb_detach_kernel_driver@20 = libusb_detach_kernel_driver
libusb_detach_kernel_driver@24 = libusb_detach_kernel_driver
libusb_detach_kernel_driver@28 = libusb_detach_kernel_driver
libusb_detach_kernel_driver@32 = libusb_detach_kernel_driver
+ libusb_detach_kernel_driver@4 = libusb_detach_kernel_driver
+ libusb_detach_kernel_driver@8 = libusb_detach_kernel_driver
libusb_event_handler_active
- libusb_event_handler_active@00 = libusb_event_handler_active
- libusb_event_handler_active@04 = libusb_event_handler_active
- libusb_event_handler_active@08 = libusb_event_handler_active
+ libusb_event_handler_active@0 = libusb_event_handler_active
libusb_event_handler_active@12 = libusb_event_handler_active
libusb_event_handler_active@16 = libusb_event_handler_active
libusb_event_handler_active@20 = libusb_event_handler_active
libusb_event_handler_active@24 = libusb_event_handler_active
libusb_event_handler_active@28 = libusb_event_handler_active
libusb_event_handler_active@32 = libusb_event_handler_active
+ libusb_event_handler_active@4 = libusb_event_handler_active
+ libusb_event_handler_active@8 = libusb_event_handler_active
libusb_event_handling_ok
- libusb_event_handling_ok@00 = libusb_event_handling_ok
- libusb_event_handling_ok@04 = libusb_event_handling_ok
- libusb_event_handling_ok@08 = libusb_event_handling_ok
+ libusb_event_handling_ok@0 = libusb_event_handling_ok
libusb_event_handling_ok@12 = libusb_event_handling_ok
libusb_event_handling_ok@16 = libusb_event_handling_ok
libusb_event_handling_ok@20 = libusb_event_handling_ok
libusb_event_handling_ok@24 = libusb_event_handling_ok
libusb_event_handling_ok@28 = libusb_event_handling_ok
libusb_event_handling_ok@32 = libusb_event_handling_ok
+ libusb_event_handling_ok@4 = libusb_event_handling_ok
+ libusb_event_handling_ok@8 = libusb_event_handling_ok
libusb_exit
- libusb_exit@00 = libusb_exit
- libusb_exit@04 = libusb_exit
- libusb_exit@08 = libusb_exit
+ libusb_exit@0 = libusb_exit
libusb_exit@12 = libusb_exit
libusb_exit@16 = libusb_exit
libusb_exit@20 = libusb_exit
libusb_exit@24 = libusb_exit
libusb_exit@28 = libusb_exit
libusb_exit@32 = libusb_exit
+ libusb_exit@4 = libusb_exit
+ libusb_exit@8 = libusb_exit
libusb_free_config_descriptor
- libusb_free_config_descriptor@00 = libusb_free_config_descriptor
- libusb_free_config_descriptor@04 = libusb_free_config_descriptor
- libusb_free_config_descriptor@08 = libusb_free_config_descriptor
+ libusb_free_config_descriptor@0 = libusb_free_config_descriptor
libusb_free_config_descriptor@12 = libusb_free_config_descriptor
libusb_free_config_descriptor@16 = libusb_free_config_descriptor
libusb_free_config_descriptor@20 = libusb_free_config_descriptor
libusb_free_config_descriptor@24 = libusb_free_config_descriptor
libusb_free_config_descriptor@28 = libusb_free_config_descriptor
libusb_free_config_descriptor@32 = libusb_free_config_descriptor
+ libusb_free_config_descriptor@4 = libusb_free_config_descriptor
+ libusb_free_config_descriptor@8 = libusb_free_config_descriptor
libusb_free_device_list
- libusb_free_device_list@00 = libusb_free_device_list
- libusb_free_device_list@04 = libusb_free_device_list
- libusb_free_device_list@08 = libusb_free_device_list
+ libusb_free_device_list@0 = libusb_free_device_list
libusb_free_device_list@12 = libusb_free_device_list
libusb_free_device_list@16 = libusb_free_device_list
libusb_free_device_list@20 = libusb_free_device_list
libusb_free_device_list@24 = libusb_free_device_list
libusb_free_device_list@28 = libusb_free_device_list
libusb_free_device_list@32 = libusb_free_device_list
+ libusb_free_device_list@4 = libusb_free_device_list
+ libusb_free_device_list@8 = libusb_free_device_list
libusb_free_transfer
- libusb_free_transfer@00 = libusb_free_transfer
- libusb_free_transfer@04 = libusb_free_transfer
- libusb_free_transfer@08 = libusb_free_transfer
+ libusb_free_transfer@0 = libusb_free_transfer
libusb_free_transfer@12 = libusb_free_transfer
libusb_free_transfer@16 = libusb_free_transfer
libusb_free_transfer@20 = libusb_free_transfer
libusb_free_transfer@24 = libusb_free_transfer
libusb_free_transfer@28 = libusb_free_transfer
libusb_free_transfer@32 = libusb_free_transfer
+ libusb_free_transfer@4 = libusb_free_transfer
+ libusb_free_transfer@8 = libusb_free_transfer
libusb_get_active_config_descriptor
- libusb_get_active_config_descriptor@00 = libusb_get_active_config_descriptor
- libusb_get_active_config_descriptor@04 = libusb_get_active_config_descriptor
- libusb_get_active_config_descriptor@08 = libusb_get_active_config_descriptor
+ libusb_get_active_config_descriptor@0 = libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@12 = libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@16 = libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@20 = libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@24 = libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@28 = libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@32 = libusb_get_active_config_descriptor
+ libusb_get_active_config_descriptor@4 = libusb_get_active_config_descriptor
+ libusb_get_active_config_descriptor@8 = libusb_get_active_config_descriptor
libusb_get_bus_number
- libusb_get_bus_number@00 = libusb_get_bus_number
- libusb_get_bus_number@04 = libusb_get_bus_number
- libusb_get_bus_number@08 = libusb_get_bus_number
+ libusb_get_bus_number@0 = libusb_get_bus_number
libusb_get_bus_number@12 = libusb_get_bus_number
libusb_get_bus_number@16 = libusb_get_bus_number
libusb_get_bus_number@20 = libusb_get_bus_number
libusb_get_bus_number@24 = libusb_get_bus_number
libusb_get_bus_number@28 = libusb_get_bus_number
libusb_get_bus_number@32 = libusb_get_bus_number
+ libusb_get_bus_number@4 = libusb_get_bus_number
+ libusb_get_bus_number@8 = libusb_get_bus_number
libusb_get_config_descriptor
- libusb_get_config_descriptor@00 = libusb_get_config_descriptor
- libusb_get_config_descriptor@04 = libusb_get_config_descriptor
- libusb_get_config_descriptor@08 = libusb_get_config_descriptor
+ libusb_get_config_descriptor@0 = libusb_get_config_descriptor
libusb_get_config_descriptor@12 = libusb_get_config_descriptor
libusb_get_config_descriptor@16 = libusb_get_config_descriptor
libusb_get_config_descriptor@20 = libusb_get_config_descriptor
libusb_get_config_descriptor@24 = libusb_get_config_descriptor
libusb_get_config_descriptor@28 = libusb_get_config_descriptor
libusb_get_config_descriptor@32 = libusb_get_config_descriptor
+ libusb_get_config_descriptor@4 = libusb_get_config_descriptor
+ libusb_get_config_descriptor@8 = libusb_get_config_descriptor
libusb_get_config_descriptor_by_value
- libusb_get_config_descriptor_by_value@00 = libusb_get_config_descriptor_by_value
- libusb_get_config_descriptor_by_value@04 = libusb_get_config_descriptor_by_value
- libusb_get_config_descriptor_by_value@08 = libusb_get_config_descriptor_by_value
+ libusb_get_config_descriptor_by_value@0 = libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@12 = libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@16 = libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@20 = libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@24 = libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@28 = libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@32 = libusb_get_config_descriptor_by_value
+ libusb_get_config_descriptor_by_value@4 = libusb_get_config_descriptor_by_value
+ libusb_get_config_descriptor_by_value@8 = libusb_get_config_descriptor_by_value
libusb_get_configuration
- libusb_get_configuration@00 = libusb_get_configuration
- libusb_get_configuration@04 = libusb_get_configuration
- libusb_get_configuration@08 = libusb_get_configuration
+ libusb_get_configuration@0 = libusb_get_configuration
libusb_get_configuration@12 = libusb_get_configuration
libusb_get_configuration@16 = libusb_get_configuration
libusb_get_configuration@20 = libusb_get_configuration
libusb_get_configuration@24 = libusb_get_configuration
libusb_get_configuration@28 = libusb_get_configuration
libusb_get_configuration@32 = libusb_get_configuration
+ libusb_get_configuration@4 = libusb_get_configuration
+ libusb_get_configuration@8 = libusb_get_configuration
libusb_get_device
- libusb_get_device@00 = libusb_get_device
- libusb_get_device@04 = libusb_get_device
- libusb_get_device@08 = libusb_get_device
+ libusb_get_device@0 = libusb_get_device
libusb_get_device@12 = libusb_get_device
libusb_get_device@16 = libusb_get_device
libusb_get_device@20 = libusb_get_device
libusb_get_device@24 = libusb_get_device
libusb_get_device@28 = libusb_get_device
libusb_get_device@32 = libusb_get_device
+ libusb_get_device@4 = libusb_get_device
+ libusb_get_device@8 = libusb_get_device
libusb_get_device_address
- libusb_get_device_address@00 = libusb_get_device_address
- libusb_get_device_address@04 = libusb_get_device_address
- libusb_get_device_address@08 = libusb_get_device_address
+ libusb_get_device_address@0 = libusb_get_device_address
libusb_get_device_address@12 = libusb_get_device_address
libusb_get_device_address@16 = libusb_get_device_address
libusb_get_device_address@20 = libusb_get_device_address
libusb_get_device_address@24 = libusb_get_device_address
libusb_get_device_address@28 = libusb_get_device_address
libusb_get_device_address@32 = libusb_get_device_address
+ libusb_get_device_address@4 = libusb_get_device_address
+ libusb_get_device_address@8 = libusb_get_device_address
libusb_get_device_descriptor
- libusb_get_device_descriptor@00 = libusb_get_device_descriptor
- libusb_get_device_descriptor@04 = libusb_get_device_descriptor
- libusb_get_device_descriptor@08 = libusb_get_device_descriptor
+ libusb_get_device_descriptor@0 = libusb_get_device_descriptor
libusb_get_device_descriptor@12 = libusb_get_device_descriptor
libusb_get_device_descriptor@16 = libusb_get_device_descriptor
libusb_get_device_descriptor@20 = libusb_get_device_descriptor
libusb_get_device_descriptor@24 = libusb_get_device_descriptor
libusb_get_device_descriptor@28 = libusb_get_device_descriptor
libusb_get_device_descriptor@32 = libusb_get_device_descriptor
+ libusb_get_device_descriptor@4 = libusb_get_device_descriptor
+ libusb_get_device_descriptor@8 = libusb_get_device_descriptor
libusb_get_device_list
- libusb_get_device_list@00 = libusb_get_device_list
- libusb_get_device_list@04 = libusb_get_device_list
- libusb_get_device_list@08 = libusb_get_device_list
+ libusb_get_device_list@0 = libusb_get_device_list
libusb_get_device_list@12 = libusb_get_device_list
libusb_get_device_list@16 = libusb_get_device_list
libusb_get_device_list@20 = libusb_get_device_list
libusb_get_device_list@24 = libusb_get_device_list
libusb_get_device_list@28 = libusb_get_device_list
libusb_get_device_list@32 = libusb_get_device_list
+ libusb_get_device_list@4 = libusb_get_device_list
+ libusb_get_device_list@8 = libusb_get_device_list
libusb_get_max_iso_packet_size
- libusb_get_max_iso_packet_size@00 = libusb_get_max_iso_packet_size
- libusb_get_max_iso_packet_size@04 = libusb_get_max_iso_packet_size
- libusb_get_max_iso_packet_size@08 = libusb_get_max_iso_packet_size
+ libusb_get_max_iso_packet_size@0 = libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@12 = libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@16 = libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@20 = libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@24 = libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@28 = libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@32 = libusb_get_max_iso_packet_size
+ libusb_get_max_iso_packet_size@4 = libusb_get_max_iso_packet_size
+ libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
libusb_get_max_packet_size
- libusb_get_max_packet_size@00 = libusb_get_max_packet_size
- libusb_get_max_packet_size@04 = libusb_get_max_packet_size
- libusb_get_max_packet_size@08 = libusb_get_max_packet_size
+ libusb_get_max_packet_size@0 = libusb_get_max_packet_size
libusb_get_max_packet_size@12 = libusb_get_max_packet_size
libusb_get_max_packet_size@16 = libusb_get_max_packet_size
libusb_get_max_packet_size@20 = libusb_get_max_packet_size
libusb_get_max_packet_size@24 = libusb_get_max_packet_size
libusb_get_max_packet_size@28 = libusb_get_max_packet_size
libusb_get_max_packet_size@32 = libusb_get_max_packet_size
+ libusb_get_max_packet_size@4 = libusb_get_max_packet_size
+ libusb_get_max_packet_size@8 = libusb_get_max_packet_size
libusb_get_next_timeout
- libusb_get_next_timeout@00 = libusb_get_next_timeout
- libusb_get_next_timeout@04 = libusb_get_next_timeout
- libusb_get_next_timeout@08 = libusb_get_next_timeout
+ libusb_get_next_timeout@0 = libusb_get_next_timeout
libusb_get_next_timeout@12 = libusb_get_next_timeout
libusb_get_next_timeout@16 = libusb_get_next_timeout
libusb_get_next_timeout@20 = libusb_get_next_timeout
libusb_get_next_timeout@24 = libusb_get_next_timeout
libusb_get_next_timeout@28 = libusb_get_next_timeout
libusb_get_next_timeout@32 = libusb_get_next_timeout
+ libusb_get_next_timeout@4 = libusb_get_next_timeout
+ libusb_get_next_timeout@8 = libusb_get_next_timeout
libusb_get_parent
- libusb_get_parent@00 = libusb_get_parent
- libusb_get_parent@04 = libusb_get_parent
- libusb_get_parent@08 = libusb_get_parent
+ libusb_get_parent@0 = libusb_get_parent
libusb_get_parent@12 = libusb_get_parent
libusb_get_parent@16 = libusb_get_parent
libusb_get_parent@20 = libusb_get_parent
libusb_get_parent@24 = libusb_get_parent
libusb_get_parent@28 = libusb_get_parent
libusb_get_parent@32 = libusb_get_parent
+ libusb_get_parent@4 = libusb_get_parent
+ libusb_get_parent@8 = libusb_get_parent
libusb_get_pollfds
- libusb_get_pollfds@00 = libusb_get_pollfds
- libusb_get_pollfds@04 = libusb_get_pollfds
- libusb_get_pollfds@08 = libusb_get_pollfds
+ libusb_get_pollfds@0 = libusb_get_pollfds
libusb_get_pollfds@12 = libusb_get_pollfds
libusb_get_pollfds@16 = libusb_get_pollfds
libusb_get_pollfds@20 = libusb_get_pollfds
libusb_get_pollfds@24 = libusb_get_pollfds
libusb_get_pollfds@28 = libusb_get_pollfds
libusb_get_pollfds@32 = libusb_get_pollfds
+ libusb_get_pollfds@4 = libusb_get_pollfds
+ libusb_get_pollfds@8 = libusb_get_pollfds
libusb_get_port_number
- libusb_get_port_number@00 = libusb_get_port_number
- libusb_get_port_number@04 = libusb_get_port_number
- libusb_get_port_number@08 = libusb_get_port_number
+ libusb_get_port_number@0 = libusb_get_port_number
libusb_get_port_number@12 = libusb_get_port_number
libusb_get_port_number@16 = libusb_get_port_number
libusb_get_port_number@20 = libusb_get_port_number
libusb_get_port_number@24 = libusb_get_port_number
libusb_get_port_number@28 = libusb_get_port_number
libusb_get_port_number@32 = libusb_get_port_number
+ libusb_get_port_number@4 = libusb_get_port_number
+ libusb_get_port_number@8 = libusb_get_port_number
libusb_get_port_path
- libusb_get_port_path@00 = libusb_get_port_path
- libusb_get_port_path@04 = libusb_get_port_path
- libusb_get_port_path@08 = libusb_get_port_path
+ libusb_get_port_path@0 = libusb_get_port_path
libusb_get_port_path@12 = libusb_get_port_path
libusb_get_port_path@16 = libusb_get_port_path
libusb_get_port_path@20 = libusb_get_port_path
libusb_get_port_path@24 = libusb_get_port_path
libusb_get_port_path@28 = libusb_get_port_path
libusb_get_port_path@32 = libusb_get_port_path
+ libusb_get_port_path@4 = libusb_get_port_path
+ libusb_get_port_path@8 = libusb_get_port_path
libusb_get_string_descriptor_ascii
- libusb_get_string_descriptor_ascii@00 = libusb_get_string_descriptor_ascii
- libusb_get_string_descriptor_ascii@04 = libusb_get_string_descriptor_ascii
- libusb_get_string_descriptor_ascii@08 = libusb_get_string_descriptor_ascii
+ libusb_get_string_descriptor_ascii@0 = libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@12 = libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@16 = libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@20 = libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@24 = libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@28 = libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@32 = libusb_get_string_descriptor_ascii
+ libusb_get_string_descriptor_ascii@4 = libusb_get_string_descriptor_ascii
+ libusb_get_string_descriptor_ascii@8 = libusb_get_string_descriptor_ascii
libusb_getversion
- libusb_getversion@00 = libusb_getversion
- libusb_getversion@04 = libusb_getversion
- libusb_getversion@08 = libusb_getversion
+ libusb_getversion@0 = libusb_getversion
libusb_getversion@12 = libusb_getversion
libusb_getversion@16 = libusb_getversion
libusb_getversion@20 = libusb_getversion
libusb_getversion@24 = libusb_getversion
libusb_getversion@28 = libusb_getversion
libusb_getversion@32 = libusb_getversion
+ libusb_getversion@4 = libusb_getversion
+ libusb_getversion@8 = libusb_getversion
libusb_handle_events
- libusb_handle_events@00 = libusb_handle_events
- libusb_handle_events@04 = libusb_handle_events
- libusb_handle_events@08 = libusb_handle_events
+ libusb_handle_events@0 = libusb_handle_events
libusb_handle_events@12 = libusb_handle_events
libusb_handle_events@16 = libusb_handle_events
libusb_handle_events@20 = libusb_handle_events
libusb_handle_events@24 = libusb_handle_events
libusb_handle_events@28 = libusb_handle_events
libusb_handle_events@32 = libusb_handle_events
- libusb_handle_events_check
- libusb_handle_events_check@00 = libusb_handle_events_check
- libusb_handle_events_check@04 = libusb_handle_events_check
- libusb_handle_events_check@08 = libusb_handle_events_check
- libusb_handle_events_check@12 = libusb_handle_events_check
- libusb_handle_events_check@16 = libusb_handle_events_check
- libusb_handle_events_check@20 = libusb_handle_events_check
- libusb_handle_events_check@24 = libusb_handle_events_check
- libusb_handle_events_check@28 = libusb_handle_events_check
- libusb_handle_events_check@32 = libusb_handle_events_check
+ libusb_handle_events@4 = libusb_handle_events
+ libusb_handle_events@8 = libusb_handle_events
libusb_handle_events_locked
- libusb_handle_events_locked@00 = libusb_handle_events_locked
- libusb_handle_events_locked@04 = libusb_handle_events_locked
- libusb_handle_events_locked@08 = libusb_handle_events_locked
+ libusb_handle_events_locked@0 = libusb_handle_events_locked
libusb_handle_events_locked@12 = libusb_handle_events_locked
libusb_handle_events_locked@16 = libusb_handle_events_locked
libusb_handle_events_locked@20 = libusb_handle_events_locked
libusb_handle_events_locked@24 = libusb_handle_events_locked
libusb_handle_events_locked@28 = libusb_handle_events_locked
libusb_handle_events_locked@32 = libusb_handle_events_locked
+ libusb_handle_events_locked@4 = libusb_handle_events_locked
+ libusb_handle_events_locked@8 = libusb_handle_events_locked
libusb_handle_events_timeout
- libusb_handle_events_timeout@00 = libusb_handle_events_timeout
- libusb_handle_events_timeout@04 = libusb_handle_events_timeout
- libusb_handle_events_timeout@08 = libusb_handle_events_timeout
+ libusb_handle_events_timeout@0 = libusb_handle_events_timeout
libusb_handle_events_timeout@12 = libusb_handle_events_timeout
libusb_handle_events_timeout@16 = libusb_handle_events_timeout
libusb_handle_events_timeout@20 = libusb_handle_events_timeout
libusb_handle_events_timeout@24 = libusb_handle_events_timeout
libusb_handle_events_timeout@28 = libusb_handle_events_timeout
libusb_handle_events_timeout@32 = libusb_handle_events_timeout
- libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@00 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@04 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@08 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@12 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@16 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@20 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@24 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@28 = libusb_handle_events_timeout_check
- libusb_handle_events_timeout_check@32 = libusb_handle_events_timeout_check
+ libusb_handle_events_timeout@4 = libusb_handle_events_timeout
+ libusb_handle_events_timeout@8 = libusb_handle_events_timeout
libusb_init
- libusb_init@00 = libusb_init
- libusb_init@04 = libusb_init
- libusb_init@08 = libusb_init
+ libusb_init@0 = libusb_init
libusb_init@12 = libusb_init
libusb_init@16 = libusb_init
libusb_init@20 = libusb_init
libusb_init@24 = libusb_init
libusb_init@28 = libusb_init
libusb_init@32 = libusb_init
+ libusb_init@4 = libusb_init
+ libusb_init@8 = libusb_init
libusb_interrupt_transfer
- libusb_interrupt_transfer@00 = libusb_interrupt_transfer
- libusb_interrupt_transfer@04 = libusb_interrupt_transfer
- libusb_interrupt_transfer@08 = libusb_interrupt_transfer
+ libusb_interrupt_transfer@0 = libusb_interrupt_transfer
libusb_interrupt_transfer@12 = libusb_interrupt_transfer
libusb_interrupt_transfer@16 = libusb_interrupt_transfer
libusb_interrupt_transfer@20 = libusb_interrupt_transfer
libusb_interrupt_transfer@24 = libusb_interrupt_transfer
libusb_interrupt_transfer@28 = libusb_interrupt_transfer
libusb_interrupt_transfer@32 = libusb_interrupt_transfer
+ libusb_interrupt_transfer@4 = libusb_interrupt_transfer
+ libusb_interrupt_transfer@8 = libusb_interrupt_transfer
libusb_kernel_driver_active
- libusb_kernel_driver_active@00 = libusb_kernel_driver_active
- libusb_kernel_driver_active@04 = libusb_kernel_driver_active
- libusb_kernel_driver_active@08 = libusb_kernel_driver_active
+ libusb_kernel_driver_active@0 = libusb_kernel_driver_active
libusb_kernel_driver_active@12 = libusb_kernel_driver_active
libusb_kernel_driver_active@16 = libusb_kernel_driver_active
libusb_kernel_driver_active@20 = libusb_kernel_driver_active
libusb_kernel_driver_active@24 = libusb_kernel_driver_active
libusb_kernel_driver_active@28 = libusb_kernel_driver_active
libusb_kernel_driver_active@32 = libusb_kernel_driver_active
+ libusb_kernel_driver_active@4 = libusb_kernel_driver_active
+ libusb_kernel_driver_active@8 = libusb_kernel_driver_active
libusb_lock_event_waiters
- libusb_lock_event_waiters@00 = libusb_lock_event_waiters
- libusb_lock_event_waiters@04 = libusb_lock_event_waiters
- libusb_lock_event_waiters@08 = libusb_lock_event_waiters
+ libusb_lock_event_waiters@0 = libusb_lock_event_waiters
libusb_lock_event_waiters@12 = libusb_lock_event_waiters
libusb_lock_event_waiters@16 = libusb_lock_event_waiters
libusb_lock_event_waiters@20 = libusb_lock_event_waiters
libusb_lock_event_waiters@24 = libusb_lock_event_waiters
libusb_lock_event_waiters@28 = libusb_lock_event_waiters
libusb_lock_event_waiters@32 = libusb_lock_event_waiters
+ libusb_lock_event_waiters@4 = libusb_lock_event_waiters
+ libusb_lock_event_waiters@8 = libusb_lock_event_waiters
libusb_lock_events
- libusb_lock_events@00 = libusb_lock_events
- libusb_lock_events@04 = libusb_lock_events
- libusb_lock_events@08 = libusb_lock_events
+ libusb_lock_events@0 = libusb_lock_events
libusb_lock_events@12 = libusb_lock_events
libusb_lock_events@16 = libusb_lock_events
libusb_lock_events@20 = libusb_lock_events
libusb_lock_events@24 = libusb_lock_events
libusb_lock_events@28 = libusb_lock_events
libusb_lock_events@32 = libusb_lock_events
+ libusb_lock_events@4 = libusb_lock_events
+ libusb_lock_events@8 = libusb_lock_events
libusb_open
- libusb_open@00 = libusb_open
- libusb_open@04 = libusb_open
- libusb_open@08 = libusb_open
+ libusb_open@0 = libusb_open
libusb_open@12 = libusb_open
libusb_open@16 = libusb_open
libusb_open@20 = libusb_open
libusb_open@24 = libusb_open
libusb_open@28 = libusb_open
libusb_open@32 = libusb_open
+ libusb_open@4 = libusb_open
+ libusb_open@8 = libusb_open
libusb_open_device_with_vid_pid
- libusb_open_device_with_vid_pid@00 = libusb_open_device_with_vid_pid
- libusb_open_device_with_vid_pid@04 = libusb_open_device_with_vid_pid
- libusb_open_device_with_vid_pid@08 = libusb_open_device_with_vid_pid
+ libusb_open_device_with_vid_pid@0 = libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@12 = libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@16 = libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@20 = libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@24 = libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@28 = libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@32 = libusb_open_device_with_vid_pid
+ libusb_open_device_with_vid_pid@4 = libusb_open_device_with_vid_pid
+ libusb_open_device_with_vid_pid@8 = libusb_open_device_with_vid_pid
libusb_pollfds_handle_timeouts
- libusb_pollfds_handle_timeouts@00 = libusb_pollfds_handle_timeouts
- libusb_pollfds_handle_timeouts@04 = libusb_pollfds_handle_timeouts
- libusb_pollfds_handle_timeouts@08 = libusb_pollfds_handle_timeouts
+ libusb_pollfds_handle_timeouts@0 = libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@12 = libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@16 = libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@20 = libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@24 = libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@28 = libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@32 = libusb_pollfds_handle_timeouts
+ libusb_pollfds_handle_timeouts@4 = libusb_pollfds_handle_timeouts
+ libusb_pollfds_handle_timeouts@8 = libusb_pollfds_handle_timeouts
libusb_ref_device
- libusb_ref_device@00 = libusb_ref_device
- libusb_ref_device@04 = libusb_ref_device
- libusb_ref_device@08 = libusb_ref_device
+ libusb_ref_device@0 = libusb_ref_device
libusb_ref_device@12 = libusb_ref_device
libusb_ref_device@16 = libusb_ref_device
libusb_ref_device@20 = libusb_ref_device
libusb_ref_device@24 = libusb_ref_device
libusb_ref_device@28 = libusb_ref_device
libusb_ref_device@32 = libusb_ref_device
+ libusb_ref_device@4 = libusb_ref_device
+ libusb_ref_device@8 = libusb_ref_device
libusb_release_interface
- libusb_release_interface@00 = libusb_release_interface
- libusb_release_interface@04 = libusb_release_interface
- libusb_release_interface@08 = libusb_release_interface
+ libusb_release_interface@0 = libusb_release_interface
libusb_release_interface@12 = libusb_release_interface
libusb_release_interface@16 = libusb_release_interface
libusb_release_interface@20 = libusb_release_interface
libusb_release_interface@24 = libusb_release_interface
libusb_release_interface@28 = libusb_release_interface
libusb_release_interface@32 = libusb_release_interface
+ libusb_release_interface@4 = libusb_release_interface
+ libusb_release_interface@8 = libusb_release_interface
libusb_reset_device
- libusb_reset_device@00 = libusb_reset_device
- libusb_reset_device@04 = libusb_reset_device
- libusb_reset_device@08 = libusb_reset_device
+ libusb_reset_device@0 = libusb_reset_device
libusb_reset_device@12 = libusb_reset_device
libusb_reset_device@16 = libusb_reset_device
libusb_reset_device@20 = libusb_reset_device
libusb_reset_device@24 = libusb_reset_device
libusb_reset_device@28 = libusb_reset_device
libusb_reset_device@32 = libusb_reset_device
+ libusb_reset_device@4 = libusb_reset_device
+ libusb_reset_device@8 = libusb_reset_device
libusb_set_configuration
- libusb_set_configuration@00 = libusb_set_configuration
- libusb_set_configuration@04 = libusb_set_configuration
- libusb_set_configuration@08 = libusb_set_configuration
+ libusb_set_configuration@0 = libusb_set_configuration
libusb_set_configuration@12 = libusb_set_configuration
libusb_set_configuration@16 = libusb_set_configuration
libusb_set_configuration@20 = libusb_set_configuration
libusb_set_configuration@24 = libusb_set_configuration
libusb_set_configuration@28 = libusb_set_configuration
libusb_set_configuration@32 = libusb_set_configuration
+ libusb_set_configuration@4 = libusb_set_configuration
+ libusb_set_configuration@8 = libusb_set_configuration
libusb_set_debug
- libusb_set_debug@00 = libusb_set_debug
- libusb_set_debug@04 = libusb_set_debug
- libusb_set_debug@08 = libusb_set_debug
+ libusb_set_debug@0 = libusb_set_debug
libusb_set_debug@12 = libusb_set_debug
libusb_set_debug@16 = libusb_set_debug
libusb_set_debug@20 = libusb_set_debug
libusb_set_debug@24 = libusb_set_debug
libusb_set_debug@28 = libusb_set_debug
libusb_set_debug@32 = libusb_set_debug
+ libusb_set_debug@4 = libusb_set_debug
+ libusb_set_debug@8 = libusb_set_debug
libusb_set_interface_alt_setting
- libusb_set_interface_alt_setting@00 = libusb_set_interface_alt_setting
- libusb_set_interface_alt_setting@04 = libusb_set_interface_alt_setting
- libusb_set_interface_alt_setting@08 = libusb_set_interface_alt_setting
+ libusb_set_interface_alt_setting@0 = libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@16 = libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@20 = libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@24 = libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@28 = libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@32 = libusb_set_interface_alt_setting
+ libusb_set_interface_alt_setting@4 = libusb_set_interface_alt_setting
+ libusb_set_interface_alt_setting@8 = libusb_set_interface_alt_setting
libusb_set_pollfd_notifiers
- libusb_set_pollfd_notifiers@00 = libusb_set_pollfd_notifiers
- libusb_set_pollfd_notifiers@04 = libusb_set_pollfd_notifiers
- libusb_set_pollfd_notifiers@08 = libusb_set_pollfd_notifiers
+ libusb_set_pollfd_notifiers@0 = libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@12 = libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@20 = libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@24 = libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@28 = libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@32 = libusb_set_pollfd_notifiers
+ libusb_set_pollfd_notifiers@4 = libusb_set_pollfd_notifiers
+ libusb_set_pollfd_notifiers@8 = libusb_set_pollfd_notifiers
libusb_strerror
- libusb_strerror@00 = libusb_strerror
- libusb_strerror@04 = libusb_strerror
- libusb_strerror@08 = libusb_strerror
+ libusb_strerror@0 = libusb_strerror
libusb_strerror@12 = libusb_strerror
libusb_strerror@16 = libusb_strerror
libusb_strerror@20 = libusb_strerror
libusb_strerror@24 = libusb_strerror
libusb_strerror@28 = libusb_strerror
libusb_strerror@32 = libusb_strerror
+ libusb_strerror@4 = libusb_strerror
+ libusb_strerror@8 = libusb_strerror
libusb_submit_transfer
- libusb_submit_transfer@00 = libusb_submit_transfer
- libusb_submit_transfer@04 = libusb_submit_transfer
- libusb_submit_transfer@08 = libusb_submit_transfer
+ libusb_submit_transfer@0 = libusb_submit_transfer
libusb_submit_transfer@12 = libusb_submit_transfer
libusb_submit_transfer@16 = libusb_submit_transfer
libusb_submit_transfer@20 = libusb_submit_transfer
libusb_submit_transfer@24 = libusb_submit_transfer
libusb_submit_transfer@28 = libusb_submit_transfer
libusb_submit_transfer@32 = libusb_submit_transfer
+ libusb_submit_transfer@4 = libusb_submit_transfer
+ libusb_submit_transfer@8 = libusb_submit_transfer
libusb_try_lock_events
- libusb_try_lock_events@00 = libusb_try_lock_events
- libusb_try_lock_events@04 = libusb_try_lock_events
- libusb_try_lock_events@08 = libusb_try_lock_events
+ libusb_try_lock_events@0 = libusb_try_lock_events
libusb_try_lock_events@12 = libusb_try_lock_events
libusb_try_lock_events@16 = libusb_try_lock_events
libusb_try_lock_events@20 = libusb_try_lock_events
libusb_try_lock_events@24 = libusb_try_lock_events
libusb_try_lock_events@28 = libusb_try_lock_events
libusb_try_lock_events@32 = libusb_try_lock_events
+ libusb_try_lock_events@4 = libusb_try_lock_events
+ libusb_try_lock_events@8 = libusb_try_lock_events
libusb_unlock_event_waiters
- libusb_unlock_event_waiters@00 = libusb_unlock_event_waiters
- libusb_unlock_event_waiters@04 = libusb_unlock_event_waiters
- libusb_unlock_event_waiters@08 = libusb_unlock_event_waiters
+ libusb_unlock_event_waiters@0 = libusb_unlock_event_waiters
libusb_unlock_event_waiters@12 = libusb_unlock_event_waiters
libusb_unlock_event_waiters@16 = libusb_unlock_event_waiters
libusb_unlock_event_waiters@20 = libusb_unlock_event_waiters
libusb_unlock_event_waiters@24 = libusb_unlock_event_waiters
libusb_unlock_event_waiters@28 = libusb_unlock_event_waiters
libusb_unlock_event_waiters@32 = libusb_unlock_event_waiters
+ libusb_unlock_event_waiters@4 = libusb_unlock_event_waiters
+ libusb_unlock_event_waiters@8 = libusb_unlock_event_waiters
libusb_unlock_events
- libusb_unlock_events@00 = libusb_unlock_events
- libusb_unlock_events@04 = libusb_unlock_events
- libusb_unlock_events@08 = libusb_unlock_events
+ libusb_unlock_events@0 = libusb_unlock_events
libusb_unlock_events@12 = libusb_unlock_events
libusb_unlock_events@16 = libusb_unlock_events
libusb_unlock_events@20 = libusb_unlock_events
libusb_unlock_events@24 = libusb_unlock_events
libusb_unlock_events@28 = libusb_unlock_events
libusb_unlock_events@32 = libusb_unlock_events
+ libusb_unlock_events@4 = libusb_unlock_events
+ libusb_unlock_events@8 = libusb_unlock_events
libusb_unref_device
- libusb_unref_device@00 = libusb_unref_device
- libusb_unref_device@04 = libusb_unref_device
- libusb_unref_device@08 = libusb_unref_device
+ libusb_unref_device@0 = libusb_unref_device
libusb_unref_device@12 = libusb_unref_device
libusb_unref_device@16 = libusb_unref_device
libusb_unref_device@20 = libusb_unref_device
libusb_unref_device@24 = libusb_unref_device
libusb_unref_device@28 = libusb_unref_device
libusb_unref_device@32 = libusb_unref_device
+ libusb_unref_device@4 = libusb_unref_device
+ libusb_unref_device@8 = libusb_unref_device
libusb_wait_for_event
- libusb_wait_for_event@00 = libusb_wait_for_event
- libusb_wait_for_event@04 = libusb_wait_for_event
- libusb_wait_for_event@08 = libusb_wait_for_event
+ libusb_wait_for_event@0 = libusb_wait_for_event
libusb_wait_for_event@12 = libusb_wait_for_event
libusb_wait_for_event@16 = libusb_wait_for_event
libusb_wait_for_event@20 = libusb_wait_for_event
libusb_wait_for_event@24 = libusb_wait_for_event
libusb_wait_for_event@28 = libusb_wait_for_event
libusb_wait_for_event@32 = libusb_wait_for_event
+ libusb_wait_for_event@4 = libusb_wait_for_event
+ libusb_wait_for_event@8 = libusb_wait_for_event
diff --git a/libusb/libusb.h b/libusb/libusb.h
index 4719dd1..d466109 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -1296,10 +1296,7 @@ int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv);
int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx,
struct timeval *tv);
-int LIBUSB_CALL libusb_handle_events_timeout_check(libusb_context *ctx,
- struct timeval *tv, int *completed);
int LIBUSB_CALL libusb_handle_events(libusb_context *ctx);
-int LIBUSB_CALL libusb_handle_events_check(libusb_context *ctx, int *completed);
int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx,
struct timeval *tv);
int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx);
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 8ade9c7..322ebbc 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -26,6 +26,9 @@
#include <stddef.h>
#include <stdint.h>
#include <time.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#include <libusb.h>
#include "libusb_version.h"
@@ -194,6 +197,7 @@ static inline void usbi_dbg(const char *format, ...)
#endif
#if defined(OS_LINUX) || defined(OS_DARWIN)
+#include <unistd.h>
#include <os/poll_posix.h>
#elif defined(OS_WINDOWS)
#include <os/poll_windows.h>
@@ -831,7 +835,7 @@ struct usbi_os_backend {
* Return 0 on success, or a LIBUSB_ERROR code on failure.
*/
int (*handle_events)(struct libusb_context *ctx,
- struct pollfd *fds, nfds_t nfds, int num_ready);
+ struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
/* Get time from specified clock. At least two clocks must be implemented
by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index 37b8e2c..169fa1a 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -672,10 +672,19 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
return darwin_to_libusb (kresult);
}
} else {
- priv->is_open = 1;
-
/* create async event source */
kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
+ if (kresult != kIOReturnSuccess) {
+ usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
+
+ (*(dpriv->device))->USBDeviceClose (dpriv->device);
+ (*(dpriv->device))->Release (dpriv->device);
+
+ dpriv->device = NULL;
+ return darwin_to_libusb (kresult);
+ }
+
+ priv->is_open = 1;
CFRetain (libusb_darwin_acfl);
@@ -1173,10 +1182,18 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
/* are we reading or writing? */
is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
- /* construct an array of IOUSBIsocFrames */
- tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
- if (!tpriv->isoc_framelist)
- return LIBUSB_ERROR_NO_MEM;
+ /* construct an array of IOUSBIsocFrames, reuse the old one if possible */
+ if (tpriv->isoc_framelist && tpriv->num_iso_packets != transfer->num_iso_packets) {
+ free(tpriv->isoc_framelist);
+ tpriv->isoc_framelist = NULL;
+ }
+
+ if (!tpriv->isoc_framelist) {
+ tpriv->num_iso_packets = transfer->num_iso_packets;
+ tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
+ if (!tpriv->isoc_framelist)
+ return LIBUSB_ERROR_NO_MEM;
+ }
/* copy the frame list from the libusb descriptor (the structures differ only is member order) */
for (i = 0 ; i < transfer->num_iso_packets ; i++)
@@ -1202,7 +1219,10 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
}
/* schedule for a frame a little in the future */
- frame += 2;
+ frame += 4;
+
+ if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
+ frame = cInterface->frames[transfer->endpoint];
/* submit the request */
if (is_read)
@@ -1214,6 +1234,8 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
itransfer);
+ cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets / 8;
+
if (kresult != kIOReturnSuccess) {
usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", is_read ? "In" : "Out",
darwin_error_str(kresult));
@@ -1228,6 +1250,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
+ struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
IOReturn kresult;
@@ -1249,7 +1272,23 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
/* all transfers in libusb-1.0 are async */
- kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
+
+ if (transfer->endpoint) {
+ struct __darwin_interface *cInterface;
+ uint8_t pipeRef, iface;
+
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
+ usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
+
+ return LIBUSB_ERROR_NOT_FOUND;
+ }
+
+ cInterface = &priv->interfaces[iface];
+
+ kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
+ } else
+ /* control request on endpoint 0 */
+ kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
if (kresult != kIOReturnSuccess)
usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
@@ -1421,7 +1460,7 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
}
-static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, int num_ready) {
+static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
struct usbi_transfer *itransfer;
UInt32 io_size;
IOReturn kresult;
diff --git a/libusb/os/darwin_usb.h b/libusb/os/darwin_usb.h
index a71d464..9ffd6df 100644
--- a/libusb/os/darwin_usb.h
+++ b/libusb/os/darwin_usb.h
@@ -139,6 +139,7 @@ struct darwin_device_handle_priv {
usb_interface_t **interface;
uint8_t num_endpoints;
CFRunLoopSourceRef cfSource;
+ uint64_t frames[256];
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
} interfaces[USB_MAXINTERFACES];
};
@@ -146,6 +147,7 @@ struct darwin_device_handle_priv {
struct darwin_transfer_priv {
/* Isoc */
IOUSBIsocFrame *isoc_framelist;
+ size_t num_iso_packets;
/* Control */
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 867893c..72db57a 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -363,7 +363,7 @@ static int sysfs_get_active_config(struct libusb_device *dev, int *config)
char tmp[4] = {0, 0, 0, 0};
long num;
int fd;
- size_t r;
+ ssize_t r;
fd = __open_sysfs_attr(dev, "bConfigurationValue");
if (fd < 0)
@@ -407,7 +407,7 @@ static int seek_to_next_config(struct libusb_context *ctx, int fd,
struct libusb_config_descriptor config;
unsigned char tmp[6];
off_t off;
- int r;
+ ssize_t r;
/* read first 6 bytes of descriptor */
r = read(fd, tmp, sizeof(tmp));
@@ -1331,6 +1331,39 @@ static void op_destroy_device(struct libusb_device *dev)
free(priv->sysfs_dir);
}
+/* URBs are discarded in reverse order of submission to avoid races. */
+static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plus_one)
+{
+ struct libusb_transfer *transfer =
+ __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ struct linux_transfer_priv *tpriv =
+ usbi_transfer_get_os_priv(itransfer);
+ struct linux_device_handle_priv *dpriv =
+ __device_handle_priv(transfer->dev_handle);
+ int i, ret = 0;
+ struct usbfs_urb *urb;
+
+ for (i = last_plus_one - 1; i >= first; i--) {
+ if (LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type)
+ urb = tpriv->iso_urbs[i];
+ else
+ urb = &tpriv->urbs[i];
+
+ if (0 == ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urb))
+ continue;
+
+ if (EINVAL == errno) {
+ usbi_dbg("URB not found --> assuming ready to be reaped");
+ ret = LIBUSB_ERROR_NOT_FOUND;
+ } else {
+ usbi_warn(TRANSFER_CTX(transfer),
+ "unrecognised discard errno %d", errno);
+ ret = LIBUSB_ERROR_OTHER;
+ }
+ }
+ return ret;
+}
+
static void free_iso_urbs(struct linux_transfer_priv *tpriv)
{
int i;
@@ -1409,8 +1442,6 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
if (r < 0) {
- int j;
-
if (errno == ENODEV) {
r = LIBUSB_ERROR_NO_DEVICE;
} else {
@@ -1454,14 +1485,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
if (COMPLETED_EARLY == tpriv->reap_action)
return 0;
- /* The URBs are discarded in reverse order of
- * submission, to avoid races. */
- for (j = i - 1; j >= 0; j--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, &urbs[j]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
+ discard_urbs(itransfer, 0, i);
usbi_dbg("reporting successful submission but waiting for %d "
"discards before reporting error", i);
@@ -1577,8 +1601,6 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
for (i = 0; i < num_urbs; i++) {
int r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urbs[i]);
if (r < 0) {
- int j;
-
if (errno == ENODEV) {
r = LIBUSB_ERROR_NO_DEVICE;
} else {
@@ -1613,12 +1635,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
/* The URBs we haven't submitted yet we count as already
* retired. */
tpriv->num_retired = num_urbs - i;
- for (j = i - 1; j >= 0; j--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urbs[j]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
+ discard_urbs(itransfer, 0, i);
usbi_dbg("reporting successful submission but waiting for %d "
"discards before reporting error", i);
@@ -1650,6 +1667,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
return LIBUSB_ERROR_NO_MEM;
memset(urb, 0, sizeof(struct usbfs_urb));
tpriv->urbs = urb;
+ tpriv->num_urbs = 1;
tpriv->reap_action = NORMAL;
urb->usercontext = itransfer;
@@ -1693,98 +1711,32 @@ static int op_submit_transfer(struct usbi_transfer *itransfer)
}
}
-static int cancel_control_transfer(struct usbi_transfer *itransfer)
-{
- struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
- struct libusb_transfer *transfer =
- __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv =
- __device_handle_priv(transfer->dev_handle);
- int r;
-
- if (!tpriv->urbs)
- return LIBUSB_ERROR_NOT_FOUND;
-
- tpriv->reap_action = CANCELLED;
- r = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, tpriv->urbs);
- if(r) {
- if (errno == EINVAL) {
- usbi_dbg("URB not found --> assuming ready to be reaped");
- return 0;
- } else {
- usbi_err(TRANSFER_CTX(transfer),
- "unrecognised DISCARD code %d", errno);
- return LIBUSB_ERROR_OTHER;
- }
- }
-
- return 0;
-}
-
-static int cancel_bulk_transfer(struct usbi_transfer *itransfer)
-{
- struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
- struct libusb_transfer *transfer =
- __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv =
- __device_handle_priv(transfer->dev_handle);
- int i;
-
- if (!tpriv->urbs)
- return LIBUSB_ERROR_NOT_FOUND;
-
- if (tpriv->reap_action != ERROR)
- tpriv->reap_action = CANCELLED;
-
- for (i = tpriv->num_urbs - 1; i >= 0; i--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, &tpriv->urbs[i]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
- return 0;
-}
-
-static int cancel_iso_transfer(struct usbi_transfer *itransfer)
-{
- struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
- struct libusb_transfer *transfer =
- __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv =
- __device_handle_priv(transfer->dev_handle);
- int i;
-
- if (!tpriv->iso_urbs)
- return LIBUSB_ERROR_NOT_FOUND;
-
- tpriv->reap_action = CANCELLED;
- for (i = tpriv->num_urbs - 1; i >= 0; i--) {
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, tpriv->iso_urbs[i]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
- return 0;
-}
-
static int op_cancel_transfer(struct usbi_transfer *itransfer)
{
+ struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
struct libusb_transfer *transfer =
__USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
switch (transfer->type) {
- case LIBUSB_TRANSFER_TYPE_CONTROL:
- return cancel_control_transfer(itransfer);
case LIBUSB_TRANSFER_TYPE_BULK:
+ if (tpriv->reap_action == ERROR)
+ break;
+ /* else, fall through */
+ case LIBUSB_TRANSFER_TYPE_CONTROL:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
- return cancel_bulk_transfer(itransfer);
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
- return cancel_iso_transfer(itransfer);
+ tpriv->reap_action = CANCELLED;
+ break;
default:
usbi_err(TRANSFER_CTX(transfer),
"unknown endpoint type %d", transfer->type);
return LIBUSB_ERROR_INVALID_PARAM;
}
+
+ if (!tpriv->urbs)
+ return LIBUSB_ERROR_NOT_FOUND;
+
+ return discard_urbs(itransfer, 0, tpriv->num_urbs);
}
static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
@@ -1814,7 +1766,6 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
{
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct linux_device_handle_priv *dpriv = __device_handle_priv(transfer->dev_handle);
int urb_idx = urb - tpriv->urbs;
usbi_mutex_lock(&itransfer->lock);
@@ -1928,16 +1879,7 @@ cancel_remaining:
/* cancel remaining urbs and wait for their completion before
* reporting results */
- for (int i = tpriv->num_urbs - 1; i > urb_idx; i--) {
- /* remaining URBs with continuation flag are
- * automatically cancelled by the kernel */
- if (tpriv->urbs[i].flags & USBFS_URB_BULK_CONTINUATION)
- continue;
- int tmp = ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, &tpriv->urbs[i]);
- if (tmp && errno != EINVAL)
- usbi_warn(TRANSFER_CTX(transfer),
- "unrecognised discard errno %d", errno);
- }
+ discard_urbs(itransfer, urb_idx + 1, tpriv->num_urbs);
out_unlock:
usbi_mutex_unlock(&itransfer->lock);
@@ -2142,7 +2084,7 @@ static int reap_for_handle(struct libusb_device_handle *handle)
}
static int op_handle_events(struct libusb_context *ctx,
- struct pollfd *fds, nfds_t nfds, int num_ready)
+ struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
int r;
int i = 0;
diff --git a/libusb/os/poll_posix.h b/libusb/os/poll_posix.h
index 17298a5..f8c9e21 100644
--- a/libusb/os/poll_posix.h
+++ b/libusb/os/poll_posix.h
@@ -1,8 +1,6 @@
#ifndef __LIBUSB_POLL_POSIX_H__
#define __LIBUSB_POLL_POSIX_H__
-#include <unistd.h>
-#include <poll.h>
#define usbi_write write
#define usbi_read read
#define usbi_close close
diff --git a/libusb/os/poll_windows.h b/libusb/os/poll_windows.h
index 36e3915..fee89f5 100644
--- a/libusb/os/poll_windows.h
+++ b/libusb/os/poll_windows.h
@@ -63,8 +63,6 @@ struct pollfd {
short revents; /* returned events */
};
-typedef unsigned int nfds_t;
-
// access modes
enum rw_type {
RW_NONE,
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index f2532a9..6d3da1e 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -3,7 +3,6 @@
* Copyright (c) 2009-2010 Pete Batard <pbatard@gmail.com>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
- * HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
* Hash table functions adapted from glibc, by Ulrich Drepper et al.
* Major code testing contribution by Xiaofan Chen
*
@@ -68,16 +67,12 @@ static int windows_clock_gettime(int clk_id, struct timespec *tp);
unsigned __stdcall windows_clock_gettime_threaded(void* param);
// Common calls
static int common_configure_endpoints(struct libusb_device_handle *dev_handle, int iface);
-// HUB (limited) API prototypes
-static int hub_open(struct libusb_device_handle *dev_handle);
-static void hub_close(struct libusb_device_handle *dev_handle);
// WinUSB, libusbK API prototypes
static int winusb_init(struct libusb_context *ctx);
static int winusb_exit(void);
static int winusb_open(struct libusb_device_handle *dev_handle);
static void winusb_close(struct libusb_device_handle *dev_handle);
static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface);
-static int winusb_configure_endpoints(struct libusb_device_handle *dev_handle, int iface);
static int winusb_claim_interface(struct libusb_device_handle *dev_handle, int iface);
static int winusb_release_interface(struct libusb_device_handle *dev_handle, int iface);
static int winusb_submit_control_transfer(struct usbi_transfer *itransfer);
@@ -104,21 +99,6 @@ static int libusbk_abort_transfers(struct usbi_transfer *itransfer);
static int libusbk_abort_control(struct usbi_transfer *itransfer);
static int libusbk_reset_device(struct libusb_device_handle *dev_handle);
static int libusbk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size);
-
-// HID API prototypes
-static int hid_init(struct libusb_context *ctx);
-static int hid_exit(void);
-static int hid_open(struct libusb_device_handle *dev_handle);
-static void hid_close(struct libusb_device_handle *dev_handle);
-static int hid_claim_interface(struct libusb_device_handle *dev_handle, int iface);
-static int hid_release_interface(struct libusb_device_handle *dev_handle, int iface);
-static int hid_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting);
-static int hid_submit_control_transfer(struct usbi_transfer *itransfer);
-static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer);
-static int hid_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
-static int hid_abort_transfers(struct usbi_transfer *itransfer);
-static int hid_reset_device(struct libusb_device_handle *dev_handle);
-static int hid_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size);
// Composite API prototypes
static int composite_init(struct libusb_context *ctx);
static int composite_exit(void);
@@ -185,8 +165,6 @@ bool api_winusb_available = false;
bool api_libusbk_available = false;
#define CHECK_WINUSB_AVAILABLE do { if ( ((!k) && (!api_winusb_available)) || ((k) && (!api_libusbk_available)) ) \
return LIBUSB_ERROR_ACCESS; } while (0)
-bool api_hid_available = false;
-#define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0)
static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) {
if ((guid1 != NULL) && (guid2 != NULL)) {
@@ -709,7 +687,6 @@ static int auto_claim(struct libusb_transfer *transfer, int *interface_number, i
switch(api_type) {
case USB_API_WINUSB:
case USB_API_LIBUSBK:
- case USB_API_HID:
break;
default:
return LIBUSB_ERROR_INVALID_PARAM;
@@ -1097,8 +1074,12 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
priv->depth = parent_priv->depth + 1;
priv->parent_dev = parent_dev;
dev->parent_dev = parent_dev;
- memset(&conn_info, 0, sizeof(conn_info));
+ // If the device address is already set, we can stop here
+ if (dev->device_address != 0) {
+ return LIBUSB_SUCCESS;
+ }
+ memset(&conn_info, 0, sizeof(conn_info));
if (priv->depth != 0) { // Not a HCD hub
handle = CreateFileA(parent_priv->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
@@ -1213,7 +1194,7 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev
return LIBUSB_ERROR_NO_DEVICE;
}
- // Because MI_## are not necessarily in sequential order (some composite HID
+ // Because MI_## are not necessarily in sequential order (some composite
// devices will have only MI_00 & MI_03 for instance), we retrieve the actual
// interface number from the path's MI value
interface_number = 0;
@@ -1231,44 +1212,19 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev
device_id, interface_number);
}
- // HID devices can have multiple collections (COL##) for each MI_## interface
if (priv->usb_interface[interface_number].path != NULL) {
- if (api != USB_API_HID) {
- usbi_warn(ctx, "program assertion failed %s is not an USB HID collection", device_id);
- return LIBUSB_ERROR_OTHER;
- }
- usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
- interface_number, device_id);
+ usbi_warn(ctx, "interface[%d] already set - ignoring: %s", interface_number, device_id);
return LIBUSB_ERROR_ACCESS;
}
usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
priv->usb_interface[interface_number].path = dev_interface_path;
priv->usb_interface[interface_number].apib = &usb_api_backend[api];
- if ((api == USB_API_HID) && (priv->hid == NULL)) {
- priv->hid = calloc(1, sizeof(struct hid_device_priv));
- }
priv->composite_api_flags |= 1<<api;
return LIBUSB_SUCCESS;
}
-static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
- char* dev_interface_path)
-{
- struct windows_device_priv *priv = __device_priv(dev);
-
- if (priv->hid == NULL) {
- usbi_err(ctx, "program assertion failed: parent is not HID");
- return LIBUSB_ERROR_NO_DEVICE;
- }
- priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
- priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
- usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path);
- priv->hid->nb_interfaces++;
- return LIBUSB_SUCCESS;
-}
-
/*
* get_device_list: libusb backend device enumeration function
*/
@@ -1278,14 +1234,12 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
HDEVINFO dev_info;
SP_DEVINFO_DATA dev_info_data;
SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
- GUID hid_guid;
#define MAX_ENUM_GUIDS 64
const GUID* guid[MAX_ENUM_GUIDS];
#define HCD_PASS 0
#define HUB_PASS 1
#define GEN_PASS 2
#define DEV_PASS 3
-#define HID_PASS 4
int r = LIBUSB_SUCCESS;
unsigned int nb_guids, pass, i, j, ancestor;
char path[MAX_PATH_LENGTH];
@@ -1311,17 +1265,14 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
// PASS 3 : (re)enumerate generic USB devices (including driverless)
// and list additional USB device interface GUIDs to explore
// PASS 4 : (re)enumerate master USB devices that have a device interface
- // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and
- // set the device interfaces.
+ // PASS 5+: (re)enumerate device interfaced GUIDs and set the device interfaces.
// Init the GUID table
guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB;
guid[GEN_PASS] = NULL;
guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE;
- HidD_GetHidGuid(&hid_guid);
- guid[HID_PASS] = &hid_guid;
- nb_guids = HID_PASS+1;
+ nb_guids = DEV_PASS+1;
unref_list = malloc(unref_size*sizeof(libusb_device*));
if (unref_list == NULL) {
@@ -1344,9 +1295,6 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
case GEN_PASS:
usbi_dbg("PROCESSING GENs");
break;
- case HID_PASS:
- usbi_dbg("PROCESSING HIDs %s", guid_to_string(guid[pass]));
- break;
default:
usbi_dbg("PROCESSING EXTs %s", guid_to_string(guid[pass]));
break;
@@ -1450,9 +1398,6 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
}
}
break;
- case HID_PASS:
- api = USB_API_HID;
- break;
default:
// Get the API type (after checking that the driver installation is OK)
if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE,
@@ -1486,7 +1431,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
parent_dev = usbi_get_device_by_session_id(ctx, session_id);
}
if (parent_dev == NULL) {
- usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id_path);
+ usbi_dbg("unlisted ancestor for '%s' (newly connected, etc.) - ignoring", dev_id_path);
continue;
}
parent_priv = __device_priv(parent_dev);
@@ -1525,7 +1470,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
}
}
} else {
- usbi_dbg("found existing device for session [%X]", session_id);
+ usbi_dbg("found existing device for session [%X] (%d.%d)",
+ session_id, dev->bus_number, dev->device_address);
}
priv = __device_priv(dev);
}
@@ -1541,20 +1487,15 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
priv->path = dev_interface_path; dev_interface_path = NULL;
break;
case DEV_PASS:
+ // If the device has already been setup, don't do it again
+ if (priv->path != NULL)
+ break;
// Take care of API initialization
priv->path = dev_interface_path; dev_interface_path = NULL;
priv->apib = &usb_api_backend[api];
switch(api) {
case USB_API_COMPOSITE:
break;
- case USB_API_HID:
- safe_free(priv->hid);
- priv->hid = calloc(1, sizeof(struct hid_device_priv));
- if (priv->hid == NULL) {
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
- }
- priv->hid->nb_interfaces = 0;
- break;
default:
// For other devices, the first interface is the same as the device
priv->usb_interface[0].path = malloc(safe_strlen(priv->path)+1);
@@ -1588,13 +1529,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
r = LIBUSB_SUCCESS;
}
break;
- default: // HID_PASS and later
- if (parent_priv->apib->id == USB_API_HID) {
- usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
- r = set_hid_interface(ctx, parent_dev, dev_interface_path);
- if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
- dev_interface_path = NULL;
- } else if (parent_priv->apib->id == USB_API_COMPOSITE) {
+ default: // later passes
+ if (parent_priv->apib->id == USB_API_COMPOSITE) {
usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api)) {
case LIBUSB_SUCCESS:
@@ -1614,7 +1550,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
}
// Free any additional GUIDs
- for (pass = HID_PASS+1; pass < nb_guids; pass++) {
+ for (pass = DEV_PASS+1; pass < nb_guids; pass++) {
safe_free(guid[pass]);
}
@@ -1871,7 +1807,6 @@ static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
usbi_free_fd(transfer_priv->pollable_fd.fd);
- safe_free(transfer_priv->hid_buffer);
#if defined(AUTO_CLAIM)
// When auto claim is in use, attempt to release the auto-claimed interface
auto_release(itransfer);
@@ -2056,10 +1991,10 @@ static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t i
}
}
-static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, int num_ready)
+static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
struct windows_transfer_priv* transfer_priv = NULL;
- nfds_t i = 0;
+ POLL_NFDS_TYPE i = 0;
bool found = false;
struct usbi_transfer *transfer;
DWORD io_size, io_result;
@@ -2336,7 +2271,6 @@ const char* hub_driver_names[] = {"USBHUB"};
const char* composite_driver_names[] = {"USBCCGP"};
const char* winusb_driver_names[] = {"WINUSB"};
const char* libusbK_driver_names[] = {"LIBUSBK"};
-const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
{
USB_API_UNSUPPORTED,
@@ -2368,8 +2302,8 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
sizeof(hub_driver_names)/sizeof(hub_driver_names[0]),
unsupported_init,
unsupported_exit,
- hub_open,
- hub_close,
+ unsupported_open,
+ unsupported_close,
unsupported_configure_endpoints,
unsupported_claim_interface,
unsupported_set_interface_altsetting,
@@ -2448,46 +2382,11 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
libusbk_abort_control,
libusbk_abort_transfers,
libusbk_copy_transfer_data,
- }, {
- USB_API_HID,
- "HID API",
- &CLASS_GUID_HID,
- hid_driver_names,
- sizeof(hid_driver_names)/sizeof(hid_driver_names[0]),
- hid_init,
- hid_exit,
- hid_open,
- hid_close,
- common_configure_endpoints,
- hid_claim_interface,
- hid_set_interface_altsetting,
- hid_release_interface,
- hid_clear_halt,
- hid_reset_device,
- hid_submit_bulk_transfer,
- unsupported_submit_iso_transfer,
- hid_submit_control_transfer,
- hid_abort_transfers,
- hid_abort_transfers,
- hid_copy_transfer_data,
},
};
/*
- * HUB API functions - only cached descriptors readout for now
- * might be expanded if
- */
-static int hub_open(struct libusb_device_handle *dev_handle)
-{
- return LIBUSB_SUCCESS;
-}
-
-static void hub_close(struct libusb_device_handle *dev_handle)
-{
-}
-
-/*
* WinUSB, libusbK API functions
*/
@@ -2807,23 +2706,16 @@ static int libusbk_release_interface(struct libusb_device_handle *dev_handle, in
/*
* Return the first valid interface (of the same API type), for control transfers
*/
-static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_id)
+static int winusb_get_valid_interface(struct libusb_device_handle *dev_handle)
{
struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
int i;
- if ((api_id < USB_API_WINUSB) || (api_id > USB_API_HID)) {
- usbi_dbg("unsupported API ID");
- return -1;
- }
-
for (i=0; i<USB_MAXINTERFACES; i++) {
if ( (handle_priv->interface_handle[i].dev_handle != 0)
&& (handle_priv->interface_handle[i].dev_handle != INVALID_HANDLE_VALUE)
&& (handle_priv->interface_handle[i].api_handle != 0)
- && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE)
- && (priv->usb_interface[i].apib->id == api_id) ) {
+ && (handle_priv->interface_handle[i].api_handle != INVALID_HANDLE_VALUE) ) {
return i;
}
}
@@ -2875,7 +2767,7 @@ static int _winusb_submit_control_transfer(struct usbi_transfer *itransfer, bool
if (size > MAX_CTRL_BUFFER_LENGTH)
return LIBUSB_ERROR_INVALID_PARAM;
- current_interface = get_valid_interface(transfer->dev_handle, k?USB_API_LIBUSBK:USB_API_WINUSB);
+ current_interface = winusb_get_valid_interface(transfer->dev_handle);
if (current_interface < 0) {
#if defined(AUTO_CLAIM)
if (auto_claim(transfer, &current_interface, k?USB_API_LIBUSBK:USB_API_WINUSB) != LIBUSB_SUCCESS) {
@@ -2897,7 +2789,7 @@ static int _winusb_submit_control_transfer(struct usbi_transfer *itransfer, bool
}
// Sending of set configuration control requests from WinUSB creates issues
- if ( (LIBUSB_REQ_TYPE(setup->request_type) == LIBUSB_REQUEST_TYPE_STANDARD)
+ if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD)
&& (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
if (setup->value != priv->active_config) {
usbi_warn(ctx, "cannot set configuration other than the default one");
@@ -3224,1049 +3116,6 @@ static int libusbk_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t
}
/*
- * Internal HID Support functions (from libusb-win32)
- * Note that functions that complete data transfer synchronously must return
- * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS
- */
-static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
-static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size);
-
-static int _hid_wcslen(WCHAR *str)
-{
- int i = 0;
- while (str[i] && (str[i] != 0x409)) {
- i++;
- }
- return i;
-}
-
-static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
-{
- struct libusb_device_descriptor d;
-
- d.bLength = LIBUSB_DT_DEVICE_SIZE;
- d.bDescriptorType = LIBUSB_DT_DEVICE;
- d.bcdUSB = 0x0200; /* 2.00 */
- d.bDeviceClass = 0;
- d.bDeviceSubClass = 0;
- d.bDeviceProtocol = 0;
- d.bMaxPacketSize0 = 64; /* fix this! */
- d.idVendor = (uint16_t)dev->vid;
- d.idProduct = (uint16_t)dev->pid;
- d.bcdDevice = 0x0100;
- d.iManufacturer = dev->string_index[0];
- d.iProduct = dev->string_index[1];
- d.iSerialNumber = dev->string_index[2];
- d.bNumConfigurations = 1;
-
- if (*size > LIBUSB_DT_DEVICE_SIZE)
- *size = LIBUSB_DT_DEVICE_SIZE;
- memcpy(data, &d, *size);
- return LIBUSB_COMPLETED;
-}
-
-static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
-{
- char num_endpoints = 0;
- size_t config_total_len = 0;
- char tmp[HID_MAX_CONFIG_DESC_SIZE];
- struct libusb_config_descriptor *cd;
- struct libusb_interface_descriptor *id;
- struct libusb_hid_descriptor *hd;
- struct libusb_endpoint_descriptor *ed;
- size_t tmp_size;
-
- if (dev->input_report_size)
- num_endpoints++;
- if (dev->output_report_size)
- num_endpoints++;
-
- config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE
- + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE;
-
-
- cd = (struct libusb_config_descriptor *)tmp;
- id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE);
- hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
- + LIBUSB_DT_INTERFACE_SIZE);
- ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE
- + LIBUSB_DT_INTERFACE_SIZE
- + LIBUSB_DT_HID_SIZE);
-
- cd->bLength = LIBUSB_DT_CONFIG_SIZE;
- cd->bDescriptorType = LIBUSB_DT_CONFIG;
- cd->wTotalLength = (uint16_t) config_total_len;
- cd->bNumInterfaces = 1;
- cd->bConfigurationValue = 1;
- cd->iConfiguration = 0;
- cd->bmAttributes = 1 << 7; /* bus powered */
- cd->MaxPower = 50;
-
- id->bLength = LIBUSB_DT_INTERFACE_SIZE;
- id->bDescriptorType = LIBUSB_DT_INTERFACE;
- id->bInterfaceNumber = 0;
- id->bAlternateSetting = 0;
- id->bNumEndpoints = num_endpoints;
- id->bInterfaceClass = 3;
- id->bInterfaceSubClass = 0;
- id->bInterfaceProtocol = 0;
- id->iInterface = 0;
-
- tmp_size = LIBUSB_DT_HID_SIZE;
- _hid_get_hid_descriptor(dev, hd, &tmp_size);
-
- if (dev->input_report_size) {
- ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
- ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
- ed->bEndpointAddress = HID_IN_EP;
- ed->bmAttributes = 3;
- ed->wMaxPacketSize = dev->input_report_size - 1;
- ed->bInterval = 10;
-
- ed++;
- }
-
- if (dev->output_report_size) {
- ed->bLength = LIBUSB_DT_ENDPOINT_SIZE;
- ed->bDescriptorType = LIBUSB_DT_ENDPOINT;
- ed->bEndpointAddress = HID_OUT_EP;
- ed->bmAttributes = 3;
- ed->wMaxPacketSize = dev->output_report_size - 1;
- ed->bInterval = 10;
- }
-
- if (*size > config_total_len)
- *size = config_total_len;
- memcpy(data, tmp, *size);
- return LIBUSB_COMPLETED;
-}
-
-static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index,
- void *data, size_t *size)
-{
- void *tmp = NULL;
- size_t tmp_size = 0;
- int i;
-
- /* language ID, EN-US */
- char string_langid[] = {
- 0x09,
- 0x04
- };
-
- if ((*size < 2) || (*size > 255)) {
- return LIBUSB_ERROR_OVERFLOW;
- }
-
- if (_index == 0) {
- tmp = string_langid;
- tmp_size = sizeof(string_langid)+2;
- } else {
- for (i=0; i<3; i++) {
- if (_index == (dev->string_index[i])) {
- tmp = dev->string[i];
- tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR);
- break;
- }
- }
- if (i == 3) { // not found
- return LIBUSB_ERROR_INVALID_PARAM;
- }
- }
-
- if(!tmp_size) {
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- if (tmp_size < *size) {
- *size = tmp_size;
- }
- // 2 byte header
- ((uint8_t*)data)[0] = (uint8_t)*size;
- ((uint8_t*)data)[1] = LIBUSB_DT_STRING;
- memcpy((uint8_t*)data+2, tmp, *size-2);
- return LIBUSB_COMPLETED;
-}
-
-static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
-{
- struct libusb_hid_descriptor d;
- uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE];
- size_t report_len = MAX_HID_DESCRIPTOR_SIZE;
-
- _hid_get_report_descriptor(dev, tmp, &report_len);
-
- d.bLength = LIBUSB_DT_HID_SIZE;
- d.bDescriptorType = LIBUSB_DT_HID;
- d.bcdHID = 0x0110; /* 1.10 */
- d.bCountryCode = 0;
- d.bNumDescriptors = 1;
- d.bClassDescriptorType = LIBUSB_DT_REPORT;
- d.wClassDescriptorLength = (uint16_t)report_len;
-
- if (*size > LIBUSB_DT_HID_SIZE)
- *size = LIBUSB_DT_HID_SIZE;
- memcpy(data, &d, *size);
- return LIBUSB_COMPLETED;
-}
-
-static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size)
-{
- uint8_t d[MAX_HID_DESCRIPTOR_SIZE];
- size_t i = 0;
-
- /* usage page (0xFFA0 == vendor defined) */
- d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF;
- /* usage (vendor defined) */
- d[i++] = 0x09; d[i++] = 0x01;
- /* start collection (application) */
- d[i++] = 0xA1; d[i++] = 0x01;
- /* input report */
- if (dev->input_report_size) {
- /* usage (vendor defined) */
- d[i++] = 0x09; d[i++] = 0x01;
- /* logical minimum (0) */
- d[i++] = 0x15; d[i++] = 0x00;
- /* logical maximum (255) */
- d[i++] = 0x25; d[i++] = 0xFF;
- /* report size (8 bits) */
- d[i++] = 0x75; d[i++] = 0x08;
- /* report count */
- d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1;
- /* input (data, variable, absolute) */
- d[i++] = 0x81; d[i++] = 0x00;
- }
- /* output report */
- if (dev->output_report_size) {
- /* usage (vendor defined) */
- d[i++] = 0x09; d[i++] = 0x02;
- /* logical minimum (0) */
- d[i++] = 0x15; d[i++] = 0x00;
- /* logical maximum (255) */
- d[i++] = 0x25; d[i++] = 0xFF;
- /* report size (8 bits) */
- d[i++] = 0x75; d[i++] = 0x08;
- /* report count */
- d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1;
- /* output (data, variable, absolute) */
- d[i++] = 0x91; d[i++] = 0x00;
- }
- /* feature report */
- if (dev->feature_report_size) {
- /* usage (vendor defined) */
- d[i++] = 0x09; d[i++] = 0x03;
- /* logical minimum (0) */
- d[i++] = 0x15; d[i++] = 0x00;
- /* logical maximum (255) */
- d[i++] = 0x25; d[i++] = 0xFF;
- /* report size (8 bits) */
- d[i++] = 0x75; d[i++] = 0x08;
- /* report count */
- d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1;
- /* feature (data, variable, absolute) */
- d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01;
- }
-
- /* end collection */
- d[i++] = 0xC0;
-
- if (*size > i)
- *size = i;
- memcpy(data, d, *size);
- return LIBUSB_COMPLETED;
-}
-
-static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient,
- int type, int _index, void *data, size_t *size)
-{
- switch(type) {
- case LIBUSB_DT_DEVICE:
- usbi_dbg("LIBUSB_DT_DEVICE");
- return _hid_get_device_descriptor(dev, data, size);
- case LIBUSB_DT_CONFIG:
- usbi_dbg("LIBUSB_DT_CONFIG");
- if (!_index)
- return _hid_get_config_descriptor(dev, data, size);
- return LIBUSB_ERROR_INVALID_PARAM;
- case LIBUSB_DT_STRING:
- usbi_dbg("LIBUSB_DT_STRING");
- return _hid_get_string_descriptor(dev, _index, data, size);
- case LIBUSB_DT_HID:
- usbi_dbg("LIBUSB_DT_HID");
- if (!_index)
- return _hid_get_hid_descriptor(dev, data, size);
- return LIBUSB_ERROR_INVALID_PARAM;
- case LIBUSB_DT_REPORT:
- usbi_dbg("LIBUSB_DT_REPORT");
- if (!_index)
- return _hid_get_report_descriptor(dev, data, size);
- return LIBUSB_ERROR_INVALID_PARAM;
- case LIBUSB_DT_PHYSICAL:
- usbi_dbg("LIBUSB_DT_PHYSICAL");
- if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
- return LIBUSB_COMPLETED;
- return LIBUSB_ERROR_OTHER;
- }
- usbi_dbg("unsupported");
- return LIBUSB_ERROR_INVALID_PARAM;
-}
-
-static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
- struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
- int report_type)
-{
- uint8_t *buf;
- DWORD ioctl_code, read_size, expected_size = (DWORD)*size;
- int r = LIBUSB_SUCCESS;
-
- if (tp->hid_buffer != NULL) {
- usbi_dbg("program assertion failed: hid_buffer is not NULL");
- }
-
- if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
- usbi_dbg("invalid size (%d)", *size);
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- switch (report_type) {
- case HID_REPORT_TYPE_INPUT:
- ioctl_code = IOCTL_HID_GET_INPUT_REPORT;
- break;
- case HID_REPORT_TYPE_FEATURE:
- ioctl_code = IOCTL_HID_GET_FEATURE;
- break;
- default:
- usbi_dbg("unknown HID report type %d", report_type);
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- // Add a trailing byte to detect overflows
- buf = (uint8_t*)calloc(expected_size+1, 1);
- if (buf == NULL) {
- return LIBUSB_ERROR_NO_MEM;
- }
- buf[0] = (uint8_t)id; // Must be set always
- usbi_dbg("report ID: 0x%02X", buf[0]);
-
- tp->hid_expected_size = expected_size;
- read_size = expected_size;
-
- // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
- if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1,
- buf, expected_size+1, &read_size, overlapped)) {
- if (GetLastError() != ERROR_IO_PENDING) {
- usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0));
- safe_free(buf);
- return LIBUSB_ERROR_IO;
- }
- // Asynchronous wait
- tp->hid_buffer = buf;
- tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer
- return LIBUSB_SUCCESS;
- }
-
- // Transfer completed synchronously => copy and discard extra buffer
- if (read_size == 0) {
- usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read");
- *size = 0;
- } else {
- if (buf[0] != id) {
- usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
- }
- if ((size_t)read_size > expected_size) {
- r = LIBUSB_ERROR_OVERFLOW;
- usbi_dbg("OVERFLOW!");
- } else {
- r = LIBUSB_COMPLETED;
- }
-
- *size = MIN((size_t)read_size, *size);
- if (id == 0) {
- // Discard report ID
- memcpy(data, buf+1, *size);
- } else {
- memcpy(data, buf, *size);
- }
- }
- safe_free(buf);
- return r;
-}
-
-static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
- struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped,
- int report_type)
-{
- uint8_t *buf = NULL;
- DWORD ioctl_code, write_size= (DWORD)*size;
-
- if (tp->hid_buffer != NULL) {
- usbi_dbg("program assertion failed: hid_buffer is not NULL");
- }
-
- if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) {
- usbi_dbg("invalid size (%d)", *size);
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- switch (report_type) {
- case HID_REPORT_TYPE_OUTPUT:
- ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT;
- break;
- case HID_REPORT_TYPE_FEATURE:
- ioctl_code = IOCTL_HID_SET_FEATURE;
- break;
- default:
- usbi_dbg("unknown HID report type %d", report_type);
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- usbi_dbg("report ID: 0x%02X", id);
- // When report IDs are not used (i.e. when id == 0), we must add
- // a null report ID. Otherwise, we just use original data buffer
- if (id == 0) {
- write_size++;
- }
- buf = malloc(write_size);
- if (buf == NULL) {
- return LIBUSB_ERROR_NO_MEM;
- }
- if (id == 0) {
- buf[0] = 0;
- memcpy(buf + 1, data, *size);
- } else {
- // This seems like a waste, but if we don't duplicate the
- // data, we'll get issues when freeing hid_buffer
- memcpy(buf, data, *size);
- if (buf[0] != id) {
- usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id);
- }
- }
-
- // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
- if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size,
- buf, write_size, &write_size, overlapped)) {
- if (GetLastError() != ERROR_IO_PENDING) {
- usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0));
- safe_free(buf);
- return LIBUSB_ERROR_IO;
- }
- tp->hid_buffer = buf;
- tp->hid_dest = NULL;
- return LIBUSB_SUCCESS;
- }
-
- // Transfer completed synchronously
- *size = write_size;
- if (write_size == 0) {
- usbi_dbg("program assertion failed - write completed synchronously, but no data was written");
- }
- safe_free(buf);
- return LIBUSB_COMPLETED;
-}
-
-static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type,
- int request, int value, int _index, void *data, struct windows_transfer_priv *tp,
- size_t *size, OVERLAPPED* overlapped)
-{
- int report_type = (value >> 8) & 0xFF;
- int report_id = value & 0xFF;
-
- if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE)
- && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) )
- return LIBUSB_ERROR_INVALID_PARAM;
-
- if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT)
- return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
-
- if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT)
- return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type);
-
- return LIBUSB_ERROR_INVALID_PARAM;
-}
-
-
-/*
- * HID API functions
- */
-static int hid_init(struct libusb_context *ctx)
-{
- DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
- DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
- DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
- DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
- DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
- DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
- DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
- DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
- DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
- DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
- DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
- DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
- DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
- DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
- DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
- DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
-
- api_hid_available = true;
- return LIBUSB_SUCCESS;
-}
-
-static int hid_exit(void)
-{
- return LIBUSB_SUCCESS;
-}
-
-// NB: open and close must ensure that they only handle interface of
-// the right API type, as these functions can be called wholesale from
-// composite_open(), with interfaces belonging to different APIs
-static int hid_open(struct libusb_device_handle *dev_handle)
-{
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
-
- HIDD_ATTRIBUTES hid_attributes;
- PHIDP_PREPARSED_DATA preparsed_data = NULL;
- HIDP_CAPS capabilities;
- HIDP_VALUE_CAPS *value_caps;
-
- HANDLE hid_handle = INVALID_HANDLE_VALUE;
- int i, j;
- // report IDs handling
- ULONG size[3];
- char* type[3] = {"input", "output", "feature"};
- int nb_ids[2]; // zero and nonzero report IDs
-
- CHECK_HID_AVAILABLE;
- if (priv->hid == NULL) {
- usbi_err(ctx, "program assertion failed - private HID structure is unitialized");
- return LIBUSB_ERROR_NOT_FOUND;
- }
-
- for (i = 0; i < USB_MAXINTERFACES; i++) {
- if ( (priv->usb_interface[i].path != NULL)
- && (priv->usb_interface[i].apib->id == USB_API_HID) ) {
- hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
- /*
- * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID?
- * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system
- * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not
- * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and
- * HidD_GetFeature (if the device supports Feature reports)."
- */
- if (hid_handle == INVALID_HANDLE_VALUE) {
- usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without");
- hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
- if (hid_handle == INVALID_HANDLE_VALUE) {
- usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
- switch(GetLastError()) {
- case ERROR_FILE_NOT_FOUND: // The device was disconnected
- return LIBUSB_ERROR_NO_DEVICE;
- case ERROR_ACCESS_DENIED:
- return LIBUSB_ERROR_ACCESS;
- default:
- return LIBUSB_ERROR_IO;
- }
- }
- priv->usb_interface[i].restricted_functionality = true;
- }
- handle_priv->interface_handle[i].api_handle = hid_handle;
- }
- }
-
- hid_attributes.Size = sizeof(hid_attributes);
- do {
- if (!HidD_GetAttributes(hid_handle, &hid_attributes)) {
- usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)");
- break;
- }
-
- priv->hid->vid = hid_attributes.VendorID;
- priv->hid->pid = hid_attributes.ProductID;
-
- // Set the maximum available input buffer size
- for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2);
- usbi_dbg("set maximum input buffer size to %d", i/2);
-
- // Get the maximum input and output report size
- if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
- usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)");
- break;
- }
- if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) {
- usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)");
- break;
- }
-
- // Find out if interrupt will need report IDs
- size[0] = capabilities.NumberInputValueCaps;
- size[1] = capabilities.NumberOutputValueCaps;
- size[2] = capabilities.NumberFeatureValueCaps;
- for (j=0; j<3; j++) {
- usbi_dbg("%d HID %s report value(s) found", size[j], type[j]);
- priv->hid->uses_report_ids[j] = false;
- if (size[j] > 0) {
- value_caps = malloc(size[j] * sizeof(HIDP_VALUE_CAPS));
- if ( (value_caps != NULL)
- && (HidP_GetValueCaps(j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS)
- && (size[j] >= 1) ) {
- nb_ids[0] = 0;
- nb_ids[1] = 0;
- for (i=0; i<(int)size[j]; i++) {
- usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID);
- if (value_caps[i].ReportID != 0) {
- nb_ids[1]++;
- } else {
- nb_ids[0]++;
- }
- }
- if (nb_ids[1] != 0) {
- if (nb_ids[0] != 0) {
- usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s",
- type[j]);
- }
- priv->hid->uses_report_ids[j] = true;
- }
- } else {
- usbi_warn(ctx, " could not process %s report IDs", type[j]);
- }
- safe_free(value_caps);
- }
- }
-
- // Set the report sizes
- priv->hid->input_report_size = capabilities.InputReportByteLength;
- priv->hid->output_report_size = capabilities.OutputReportByteLength;
- priv->hid->feature_report_size = capabilities.FeatureReportByteLength;
-
- // Fetch string descriptors
- priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer;
- if (priv->hid->string_index[0] != 0) {
- HidD_GetManufacturerString(hid_handle, priv->hid->string[0],
- sizeof(priv->hid->string[0]));
- } else {
- priv->hid->string[0][0] = 0;
- }
- priv->hid->string_index[1] = priv->dev_descriptor.iProduct;
- if (priv->hid->string_index[1] != 0) {
- HidD_GetProductString(hid_handle, priv->hid->string[1],
- sizeof(priv->hid->string[1]));
- } else {
- priv->hid->string[1][0] = 0;
- }
- priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber;
- if (priv->hid->string_index[2] != 0) {
- HidD_GetSerialNumberString(hid_handle, priv->hid->string[2],
- sizeof(priv->hid->string[2]));
- } else {
- priv->hid->string[2][0] = 0;
- }
- } while(0);
-
- if (preparsed_data) {
- HidD_FreePreparsedData(preparsed_data);
- }
-
- return LIBUSB_SUCCESS;
-}
-
-static void hid_close(struct libusb_device_handle *dev_handle)
-{
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
- HANDLE file_handle;
- int i;
-
- if (!api_hid_available)
- return;
-
- for (i = 0; i < USB_MAXINTERFACES; i++) {
- if (priv->usb_interface[i].apib->id == USB_API_HID) {
- file_handle = handle_priv->interface_handle[i].api_handle;
- if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
- CloseHandle(file_handle);
- }
- }
- }
-}
-
-static int hid_claim_interface(struct libusb_device_handle *dev_handle, int iface)
-{
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
-
- CHECK_HID_AVAILABLE;
-
- // NB: Disconnection detection is not possible in this function
- if (priv->usb_interface[iface].path == NULL) {
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
- }
-
- // We use dev_handle as a flag for interface claimed
- if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) {
- return LIBUSB_ERROR_BUSY; // already claimed
- }
-
- handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
-
- usbi_dbg("claimed interface %d", iface);
- handle_priv->active_interface = iface;
-
- return LIBUSB_SUCCESS;
-}
-
-static int hid_release_interface(struct libusb_device_handle *dev_handle, int iface)
-{
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
-
- CHECK_HID_AVAILABLE;
-
- if (priv->usb_interface[iface].path == NULL) {
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
- }
-
- if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) {
- return LIBUSB_ERROR_NOT_FOUND; // invalid iface
- }
-
- handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE;
-
- return LIBUSB_SUCCESS;
-}
-
-static int hid_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting)
-{
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
-
- CHECK_HID_AVAILABLE;
-
- if (altsetting > 255) {
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- if (altsetting != 0) {
- usbi_err(ctx, "set interface altsetting not supported for altsetting >0");
- return LIBUSB_ERROR_NOT_SUPPORTED;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-static int hid_submit_control_transfer(struct usbi_transfer *itransfer)
-{
- struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(transfer->dev_handle);
- struct windows_device_priv *priv = __device_priv(transfer->dev_handle->dev);
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
- WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
- HANDLE hid_handle;
- struct winfd wfd;
- int current_interface, config;
- size_t size;
- int r = LIBUSB_ERROR_INVALID_PARAM;
-
- CHECK_HID_AVAILABLE;
-
- transfer_priv->pollable_fd = INVALID_WINFD;
- safe_free(transfer_priv->hid_buffer);
- transfer_priv->hid_dest = NULL;
- size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
-
- if (size > MAX_CTRL_BUFFER_LENGTH) {
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-
- current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID);
- if (current_interface < 0) {
-#if defined(AUTO_CLAIM)
- if (auto_claim(transfer, &current_interface, USB_API_HID) != LIBUSB_SUCCESS) {
- return LIBUSB_ERROR_NOT_FOUND;
- }
-#else
- usbi_warn(ctx, "no interface available for control transfer");
- return LIBUSB_ERROR_NOT_FOUND;
-#endif
- }
-
- usbi_dbg("will use interface %d", current_interface);
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
- // Always use the handle returned from usbi_create_fd (wfd.handle)
- wfd = usbi_create_fd(hid_handle, _O_RDONLY);
- if (wfd.fd < 0) {
- return LIBUSB_ERROR_NO_MEM;
- }
-
- switch(LIBUSB_REQ_TYPE(setup->request_type)) {
- case LIBUSB_REQUEST_TYPE_STANDARD:
- switch(setup->request) {
- case LIBUSB_REQUEST_GET_DESCRIPTOR:
- r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type),
- (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
- break;
- case LIBUSB_REQUEST_GET_CONFIGURATION:
- r = windows_get_configuration(transfer->dev_handle, &config);
- if (r == LIBUSB_SUCCESS) {
- size = 1;
- ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config;
- r = LIBUSB_COMPLETED;
- }
- break;
- case LIBUSB_REQUEST_SET_CONFIGURATION:
- if (setup->value == priv->active_config) {
- r = LIBUSB_COMPLETED;
- } else {
- usbi_warn(ctx, "cannot set configuration other than the default one");
- r = LIBUSB_ERROR_INVALID_PARAM;
- }
- break;
- case LIBUSB_REQUEST_GET_INTERFACE:
- size = 1;
- ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0;
- r = LIBUSB_COMPLETED;
- break;
- case LIBUSB_REQUEST_SET_INTERFACE:
- r = hid_set_interface_altsetting(transfer->dev_handle, setup->index, setup->value);
- if (r == LIBUSB_SUCCESS) {
- r = LIBUSB_COMPLETED;
- }
- break;
- default:
- usbi_warn(ctx, "unsupported HID control request");
- r = LIBUSB_ERROR_INVALID_PARAM;
- break;
- }
- break;
- case LIBUSB_REQUEST_TYPE_CLASS:
- r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value,
- setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv,
- &size, wfd.overlapped);
- break;
- default:
- usbi_warn(ctx, "unsupported HID control request");
- r = LIBUSB_ERROR_INVALID_PARAM;
- break;
- }
-
- if (r == LIBUSB_COMPLETED) {
- // Force request to be completed synchronously. Transferred size has been set by previous call
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
- // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx
- // set InternalHigh to the number of bytes transferred
- wfd.overlapped->InternalHigh = (DWORD)size;
- r = LIBUSB_SUCCESS;
- }
-
- if (r == LIBUSB_SUCCESS) {
- // Use priv_transfer to store data needed for async polling
- transfer_priv->pollable_fd = wfd;
- transfer_priv->interface_number = (uint8_t)current_interface;
- } else {
- usbi_free_fd(wfd.fd);
- }
-
- return r;
-}
-
-static int hid_submit_bulk_transfer(struct usbi_transfer *itransfer) {
- struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(transfer->dev_handle);
- struct windows_device_priv *priv = __device_priv(transfer->dev_handle->dev);
- struct winfd wfd;
- HANDLE hid_handle;
- bool direction_in, ret;
- int current_interface, length;
- DWORD size;
- int r = LIBUSB_SUCCESS;
-
- CHECK_HID_AVAILABLE;
-
- transfer_priv->pollable_fd = INVALID_WINFD;
- transfer_priv->hid_dest = NULL;
- safe_free(transfer_priv->hid_buffer);
-
- current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
- if (current_interface < 0) {
- usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
- return LIBUSB_ERROR_NOT_FOUND;
- }
-
- usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
-
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
- direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
-
- wfd = usbi_create_fd(hid_handle, direction_in?_O_RDONLY:_O_WRONLY);
- // Always use the handle returned from usbi_create_fd (wfd.handle)
- if (wfd.fd < 0) {
- return LIBUSB_ERROR_NO_MEM;
- }
-
- // If report IDs are not in use, an extra prefix byte must be added
- if ( ((direction_in) && (!priv->hid->uses_report_ids[0]))
- || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) {
- length = transfer->length+1;
- } else {
- length = transfer->length;
- }
- // Add a trailing byte to detect overflows on input
- transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1);
- if (transfer_priv->hid_buffer == NULL) {
- return LIBUSB_ERROR_NO_MEM;
- }
- transfer_priv->hid_expected_size = length;
-
- if (direction_in) {
- transfer_priv->hid_dest = transfer->buffer;
- usbi_dbg("reading %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
- ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
- } else {
- if (!priv->hid->uses_report_ids[1]) {
- memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length);
- } else {
- // We could actually do without the calloc and memcpy in this case
- memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
- }
- usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
- ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped);
- }
- if (!ret) {
- if (GetLastError() != ERROR_IO_PENDING) {
- usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
- usbi_free_fd(wfd.fd);
- safe_free(transfer_priv->hid_buffer);
- return LIBUSB_ERROR_IO;
- }
- } else {
- // Only write operations that completed synchronously need to free up
- // hid_buffer. For reads, copy_transfer_data() handles that process.
- if (!direction_in) {
- safe_free(transfer_priv->hid_buffer);
- }
- if (size == 0) {
- usbi_err(ctx, "program assertion failed - no data was transferred");
- size = 1;
- }
- if (size > (size_t)length) {
- usbi_err(ctx, "OVERFLOW!");
- r = LIBUSB_ERROR_OVERFLOW;
- }
- wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
- wfd.overlapped->InternalHigh = size;
- }
-
- transfer_priv->pollable_fd = wfd;
- transfer_priv->interface_number = (uint8_t)current_interface;
-
- return r;
-}
-
-static int hid_abort_transfers(struct usbi_transfer *itransfer)
-{
- struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(transfer->dev_handle);
- HANDLE hid_handle;
- int current_interface;
-
- CHECK_HID_AVAILABLE;
-
- current_interface = transfer_priv->interface_number;
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
- CancelIo(hid_handle);
-
- return LIBUSB_SUCCESS;
-}
-
-static int hid_reset_device(struct libusb_device_handle *dev_handle)
-{
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
- HANDLE hid_handle;
- int current_interface;
-
- CHECK_HID_AVAILABLE;
-
- // Flushing the queues on all interfaces is the best we can achieve
- for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) {
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
- if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) {
- HidD_FlushQueue(hid_handle);
- }
- }
- return LIBUSB_SUCCESS;
-}
-
-static int hid_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
-{
- struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
- struct windows_device_handle_priv *handle_priv = __device_handle_priv(dev_handle);
- struct windows_device_priv *priv = __device_priv(dev_handle->dev);
- HANDLE hid_handle;
- int current_interface;
-
- CHECK_HID_AVAILABLE;
-
- current_interface = interface_by_endpoint(priv, handle_priv, endpoint);
- if (current_interface < 0) {
- usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear");
- return LIBUSB_ERROR_NOT_FOUND;
- }
-
- usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
- hid_handle = handle_priv->interface_handle[current_interface].api_handle;
-
- // No endpoint selection with Microsoft's implementation, so we try to flush the
- // whole interface. Should be OK for most case scenarios
- if (!HidD_FlushQueue(hid_handle)) {
- usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0));
- // Device was probably disconnected
- return LIBUSB_ERROR_NO_DEVICE;
- }
-
- return LIBUSB_SUCCESS;
-}
-
-// This extra function is only needed for HID
-static int hid_copy_transfer_data(struct usbi_transfer *itransfer, uint32_t io_size) {
- struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
- struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
- int r = LIBUSB_TRANSFER_COMPLETED;
- uint32_t corrected_size = io_size;
-
- if (transfer_priv->hid_buffer != NULL) {
- // If we have a valid hid_buffer, it means the transfer was async
- if (transfer_priv->hid_dest != NULL) { // Data readout
- // First, check for overflow
- if (corrected_size > transfer_priv->hid_expected_size) {
- usbi_err(ctx, "OVERFLOW!");
- corrected_size = (uint32_t)transfer_priv->hid_expected_size;
- r = LIBUSB_TRANSFER_OVERFLOW;
- }
-
- if (transfer_priv->hid_buffer[0] == 0) {
- // Discard the 1 byte report ID prefix
- corrected_size--;
- memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size);
- } else {
- memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size);
- }
- transfer_priv->hid_dest = NULL;
- }
- // For write, we just need to free the hid buffer
- safe_free(transfer_priv->hid_buffer);
- }
- itransfer->transferred += corrected_size;
- return r;
-}
-
-
-/*
* Composite API functions
*/
static int composite_init(struct libusb_context *ctx)
@@ -4335,20 +3184,12 @@ static int composite_submit_control_transfer(struct usbi_transfer *itransfer)
struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
struct windows_device_priv *priv = __device_priv(transfer->dev_handle->dev);
- int i, pass;
-
- // Interface shouldn't matter for control, but it does in practice, with Windows'
- // restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
- for (pass = 0; pass < 2; pass++) {
- for (i=0; i<USB_MAXINTERFACES; i++) {
- if (priv->usb_interface[i].path != NULL) {
- if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
- usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
- continue;
- }
- usbi_dbg("using interface %d", i);
- return priv->usb_interface[i].apib->submit_control_transfer(itransfer);
- }
+ int i;
+
+ for (i=0; i<USB_MAXINTERFACES; i++) {
+ if (priv->usb_interface[i].path != NULL) {
+ usbi_dbg("using interface %d", i);
+ return priv->usb_interface[i].apib->submit_control_transfer(itransfer);
}
}
diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h
index 644ab6a..fc2c5b7 100644
--- a/libusb/os/windows_usb.h
+++ b/libusb/os/windows_usb.h
@@ -80,8 +80,6 @@ inline void upperize(char* str) {
#define MAX_CTRL_BUFFER_LENGTH 4096
#define MAX_USB_DEVICES 256
#define MAX_USB_STRING_LENGTH 128
-#define MAX_HID_REPORT_SIZE 1024
-#define MAX_HID_DESCRIPTOR_SIZE 256
#define MAX_GUID_STRING_LENGTH 40
#define MAX_PATH_LENGTH 128
#define MAX_KEY_LENGTH 256
@@ -91,11 +89,6 @@ inline void upperize(char* str) {
#define LIST_SEPARATOR ';'
#define HTAB_SIZE 1021
-// Handle code for HID interface that have been claimed ("dibs")
-#define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5)
-// Additional return code for HID operations that completed synchronously
-#define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1)
-
// http://msdn.microsoft.com/en-us/library/ff545978.aspx
// http://msdn.microsoft.com/en-us/library/ff545972.aspx
// http://msdn.microsoft.com/en-us/library/ff545982.aspx
@@ -119,11 +112,9 @@ const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x
#define USB_API_COMPOSITE 2
#define USB_API_WINUSB 3
#define USB_API_LIBUSBK 4
-#define USB_API_HID 5
-#define USB_API_MAX 6
+#define USB_API_MAX 5
#define CLASS_GUID_UNSUPPORTED GUID_NULL
-const GUID CLASS_GUID_HID = { 0x745A17A0, 0x74D3, 0x11D0, {0xB6, 0xFE, 0x00, 0xA0, 0xC9, 0x0F, 0x57, 0xDA} };
const GUID CLASS_GUID_LIBUSB_WINUSB = { 0x78A1C341, 0x4539, 0x11D3, {0xB8, 0x8D, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71} };
const GUID CLASS_GUID_LIBUSBK = { 0xECFB0CFD, 0x74C4, 0x4F52, {0xBB, 0xF7, 0x34, 0x34, 0x61, 0xCD, 0x72, 0xAC} };
const GUID CLASS_GUID_COMPOSITE = { 0x36FC9E60, 0xC465, 0x11cF, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
@@ -163,71 +154,6 @@ extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
* private structures definition
* with inline pseudo constructors/destructors
*/
-
-// TODO (v2+): move hid desc to libusb.h?
-struct libusb_hid_descriptor {
- uint8_t bLength;
- uint8_t bDescriptorType;
- uint16_t bcdHID;
- uint8_t bCountryCode;
- uint8_t bNumDescriptors;
- uint8_t bClassDescriptorType;
- uint16_t wClassDescriptorLength;
-};
-#define LIBUSB_DT_HID_SIZE 9
-#define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \
- + LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE)
-#define HID_MAX_REPORT_SIZE 1024
-#define HID_IN_EP 0x81
-#define HID_OUT_EP 0x02
-#define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F)
-#define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5))
-#define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
-#define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
-
-// The following are used for HID reports IOCTLs
-#define HID_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS)
-#define HID_BUFFER_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define HID_IN_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
-#define HID_OUT_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
-
-#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
-#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
-#define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100)
-#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101)
-
-enum libusb_hid_request_type {
- HID_REQ_GET_REPORT = 0x01,
- HID_REQ_GET_IDLE = 0x02,
- HID_REQ_GET_PROTOCOL = 0x03,
- HID_REQ_SET_REPORT = 0x09,
- HID_REQ_SET_IDLE = 0x0A,
- HID_REQ_SET_PROTOCOL = 0x0B
-};
-
-enum libusb_hid_report_type {
- HID_REPORT_TYPE_INPUT = 0x01,
- HID_REPORT_TYPE_OUTPUT = 0x02,
- HID_REPORT_TYPE_FEATURE = 0x03
-};
-
-struct hid_device_priv {
- uint16_t vid;
- uint16_t pid;
- uint8_t config;
- uint8_t nb_interfaces;
- bool uses_report_ids[3]; // input, ouptput, feature
- uint16_t input_report_size;
- uint16_t output_report_size;
- uint16_t feature_report_size;
- WCHAR string[3][MAX_USB_STRING_LENGTH];
- uint8_t string_index[3]; // man, prod, ser
-};
-
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
struct windows_device_priv {
uint8_t depth; // distance to HCD
@@ -240,11 +166,8 @@ struct windows_device_priv {
struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support),
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
uint8_t *endpoint;
- bool restricted_functionality; // indicates if the interface functionality is restricted
- // by Windows (eg. HID keyboards or mice cannot do R/W)
} usb_interface[USB_MAXINTERFACES];
- uint8_t composite_api_flags; // HID and composite devices require additional data
- struct hid_device_priv *hid;
+ uint8_t composite_api_flags; // composite devices require additional data
uint8_t active_config;
USB_DEVICE_DESCRIPTOR dev_descriptor;
unsigned char **config_descriptor; // list of pointers to the cached config descriptors
@@ -263,7 +186,6 @@ static inline void windows_device_priv_init(libusb_device* dev) {
p->path = NULL;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->composite_api_flags = 0;
- p->hid = NULL;
p->active_config = 0;
p->config_descriptor = NULL;
memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR));
@@ -272,7 +194,6 @@ static inline void windows_device_priv_init(libusb_device* dev) {
p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->usb_interface[i].nb_endpoints = 0;
p->usb_interface[i].endpoint = NULL;
- p->usb_interface[i].restricted_functionality = false;
}
}
@@ -285,7 +206,6 @@ static inline void windows_device_priv_release(libusb_device* dev) {
safe_free(p->config_descriptor[i]);
}
safe_free(p->config_descriptor);
- safe_free(p->hid);
for (i=0; i<USB_MAXINTERFACES; i++) {
safe_free(p->usb_interface[i].path);
safe_free(p->usb_interface[i].endpoint);
@@ -315,9 +235,6 @@ static inline struct windows_device_handle_priv *__device_handle_priv(
struct windows_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
- uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
- uint8_t *hid_dest; // transfer buffer destination, required for HID
- size_t hid_expected_size;
};
// used to match a device driver (including filter drivers) against a supported API
@@ -576,7 +493,6 @@ typedef struct _USB_HUB_NAME_FIXED {
} u;
} USB_HUB_NAME_FIXED;
-
typedef struct _USB_HUB_INFORMATION {
USB_HUB_DESCRIPTOR HubDescriptor;
BOOLEAN HubIsBusPowered;
@@ -712,97 +628,3 @@ DLL_DECLARE(WINAPI, BOOL, LUsbK_ResetPipe, (WINUSB_INTERFACE_HANDLE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, LUsbK_AbortPipe, (WINUSB_INTERFACE_HANDLE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, LUsbK_FlushPipe, (WINUSB_INTERFACE_HANDLE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, LUsbK_ResetDevice, (WINUSB_INTERFACE_HANDLE));
-
-/* hid.dll interface */
-
-#define HIDP_STATUS_SUCCESS 0x110000
-typedef void* PHIDP_PREPARSED_DATA;
-
-#pragma pack(1)
-typedef struct {
- ULONG Size;
- USHORT VendorID;
- USHORT ProductID;
- USHORT VersionNumber;
-} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
-#pragma pack()
-
-typedef USHORT USAGE;
-typedef struct {
- USAGE Usage;
- USAGE UsagePage;
- USHORT InputReportByteLength;
- USHORT OutputReportByteLength;
- USHORT FeatureReportByteLength;
- USHORT Reserved[17];
- USHORT NumberLinkCollectionNodes;
- USHORT NumberInputButtonCaps;
- USHORT NumberInputValueCaps;
- USHORT NumberInputDataIndices;
- USHORT NumberOutputButtonCaps;
- USHORT NumberOutputValueCaps;
- USHORT NumberOutputDataIndices;
- USHORT NumberFeatureButtonCaps;
- USHORT NumberFeatureValueCaps;
- USHORT NumberFeatureDataIndices;
-} HIDP_CAPS, *PHIDP_CAPS;
-
-typedef enum _HIDP_REPORT_TYPE {
- HidP_Input,
- HidP_Output,
- HidP_Feature
-} HIDP_REPORT_TYPE;
-
-typedef struct _HIDP_VALUE_CAPS {
- USAGE UsagePage;
- UCHAR ReportID;
- BOOLEAN IsAlias;
- USHORT BitField;
- USHORT LinkCollection;
- USAGE LinkUsage;
- USAGE LinkUsagePage;
- BOOLEAN IsRange;
- BOOLEAN IsStringRange;
- BOOLEAN IsDesignatorRange;
- BOOLEAN IsAbsolute;
- BOOLEAN HasNull;
- UCHAR Reserved;
- USHORT BitSize;
- USHORT ReportCount;
- USHORT Reserved2[5];
- ULONG UnitsExp;
- ULONG Units;
- LONG LogicalMin, LogicalMax;
- LONG PhysicalMin, PhysicalMax;
- union {
- struct {
- USAGE UsageMin, UsageMax;
- USHORT StringMin, StringMax;
- USHORT DesignatorMin, DesignatorMax;
- USHORT DataIndexMin, DataIndexMax;
- } Range;
- struct {
- USAGE Usage, Reserved1;
- USHORT StringIndex, Reserved2;
- USHORT DesignatorIndex, Reserved3;
- USHORT DataIndex, Reserved4;
- } NotRange;
- } u;
-} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
-
-DLL_DECLARE(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
-DLL_DECLARE(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
-DLL_DECLARE(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
-DLL_DECLARE(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG));
-DLL_DECLARE(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
-DLL_DECLARE(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));
diff --git a/libusb/sync.c b/libusb/sync.c
index d040d98..f6dc2a7 100644
--- a/libusb/sync.c
+++ b/libusb/sync.c
@@ -102,13 +102,13 @@ int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
}
while (!completed) {
- r = libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed);
+ r = libusb_handle_events(HANDLE_CTX(dev_handle));
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(transfer);
while (!completed)
- if (libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed) < 0)
+ if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
break;
libusb_free_transfer(transfer);
return r;
@@ -172,13 +172,13 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
}
while (!completed) {
- r = libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed);
+ r = libusb_handle_events(HANDLE_CTX(dev_handle));
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
libusb_cancel_transfer(transfer);
while (!completed)
- if (libusb_handle_events_check(HANDLE_CTX(dev_handle), &completed) < 0)
+ if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
break;
libusb_free_transfer(transfer);
return r;
diff --git a/msvc/config.h b/msvc/config.h
index 29261fe..0430858 100644
--- a/msvc/config.h
+++ b/msvc/config.h
@@ -20,11 +20,5 @@
/* Windows backend */
#define OS_WINDOWS /**/
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Backend handles timeout */
-/* #undef USBI_OS_HANDLES_TIMEOUT */
-
-/* timerfd headers available */
-/* #undef USBI_TIMERFD_AVAILABLE */
+/* type of second poll() argument */
+#define POLL_NFDS_TYPE unsigned int