Upgrade libusb to 1.0.16

This commit is contained in:
Matthew Parlane
2013-09-30 18:36:54 +13:00
parent 3c53f2e5e0
commit d261dfaf46
86 changed files with 69015 additions and 87 deletions

68
Externals/libusbx/libusb/Makefile.am vendored Normal file
View File

@ -0,0 +1,68 @@
all: libusb-1.0.la libusb-1.0.dll
lib_LTLIBRARIES = libusb-1.0.la
POSIX_POLL_SRC = os/poll_posix.c
LINUX_USBFS_SRC = os/linux_usbfs.c
DARWIN_USB_SRC = os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
$(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
$(POSIX_POLL_SRC) \
os/threads_posix.c os/threads_windows.c \
os/linux_udev.c os/linux_netlink.c
if OS_LINUX
if USE_UDEV
OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
os/linux_udev.c
else
OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
os/linux_netlink.c
endif
endif
if OS_DARWIN
OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
AM_CFLAGS_EXT = -no-cpp-precomp
endif
if OS_OPENBSD
OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
endif
if OS_WINDOWS
OS_SRC = $(WINDOWS_USB_SRC)
.rc.lo:
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
libusb-1.0.rc: version.h version_nano.h
endif
libusb-1.0.dll: libusb-1.0.def
if CREATE_IMPORT_LIB
# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
$(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
endif
if THREADS_POSIX
THREADS_SRC = os/threads_posix.h os/threads_posix.c
else
THREADS_SRC = os/threads_windows.h os/threads_windows.c
endif
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
os/poll_posix.h os/poll_windows.h
hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h

860
Externals/libusbx/libusb/Makefile.in vendored Normal file
View File

@ -0,0 +1,860 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = libusb
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(hdr_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libusb_1_0_la_LIBADD =
am__libusb_1_0_la_SOURCES_DIST = libusbi.h core.c descriptor.c io.c \
strerror.c sync.c os/linux_usbfs.h os/darwin_usb.h \
os/windows_usb.h os/windows_common.h hotplug.h hotplug.c \
os/threads_windows.h os/threads_windows.c os/threads_posix.h \
os/threads_posix.c os/darwin_usb.c os/poll_posix.c \
os/linux_usbfs.c os/linux_netlink.c os/linux_udev.c \
os/openbsd_usb.c os/poll_windows.c os/windows_usb.c \
libusb-1.0.rc libusb-1.0.def os/poll_posix.h os/poll_windows.h
@THREADS_POSIX_FALSE@am__objects_1 = libusb_1_0_la-threads_windows.lo
@THREADS_POSIX_TRUE@am__objects_1 = libusb_1_0_la-threads_posix.lo
am__objects_2 = libusb_1_0_la-darwin_usb.lo
am__objects_3 = libusb_1_0_la-poll_posix.lo
am__objects_4 = libusb_1_0_la-linux_usbfs.lo
am__objects_5 = libusb_1_0_la-openbsd_usb.lo
am__objects_6 = libusb_1_0_la-poll_windows.lo \
libusb_1_0_la-windows_usb.lo libusb-1.0.lo
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_OPENBSD_FALSE@@OS_WINDOWS_TRUE@am__objects_7 = $(am__objects_6)
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_OPENBSD_TRUE@am__objects_7 = $(am__objects_5) \
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_OPENBSD_TRUE@ $(am__objects_3)
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_7 = $(am__objects_4) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ $(am__objects_3) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ libusb_1_0_la-linux_netlink.lo
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@am__objects_7 = $(am__objects_4) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ $(am__objects_3) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ libusb_1_0_la-linux_udev.lo
@OS_DARWIN_TRUE@am__objects_7 = $(am__objects_2) $(am__objects_3)
am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
libusb_1_0_la-descriptor.lo libusb_1_0_la-io.lo \
libusb_1_0_la-strerror.lo libusb_1_0_la-sync.lo \
libusb_1_0_la-hotplug.lo $(am__objects_1) $(am__objects_7)
libusb_1_0_la_OBJECTS = $(am_libusb_1_0_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libusb_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libusb_1_0_la_CFLAGS) \
$(CFLAGS) $(libusb_1_0_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libusb_1_0_la_SOURCES)
DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(hdr_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLDFLAGS = @LTLDFLAGS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OS_DARWIN = @OS_DARWIN@
OS_LINUX = @OS_LINUX@
OS_OPENBSD = @OS_OPENBSD@
OS_WINDOWS = @OS_WINDOWS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USE_UDEV = @USE_UDEV@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libusb-1.0.la
POSIX_POLL_SRC = os/poll_posix.c
LINUX_USBFS_SRC = os/linux_usbfs.c
DARWIN_USB_SRC = os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
$(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
$(POSIX_POLL_SRC) \
os/threads_posix.c os/threads_windows.c \
os/linux_udev.c os/linux_netlink.c
@OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
@OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/linux_netlink.c
@OS_LINUX_TRUE@@USE_UDEV_TRUE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/linux_udev.c
@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
@OS_WINDOWS_TRUE@OS_SRC = $(WINDOWS_USB_SRC)
@OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp
@THREADS_POSIX_FALSE@THREADS_SRC = os/threads_windows.h os/threads_windows.c
@THREADS_POSIX_TRUE@THREADS_SRC = os/threads_posix.h os/threads_posix.c
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
os/poll_posix.h os/poll_windows.h
hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj .rc
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu libusb/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libusb-1.0.la: $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_DEPENDENCIES) $(EXTRA_libusb_1_0_la_DEPENDENCIES)
$(AM_V_CCLD)$(libusb_1_0_la_LINK) -rpath $(libdir) $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-core.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-descriptor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-hotplug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-io.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-linux_udev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-poll_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-poll_windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-strerror.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-sync.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-threads_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-threads_windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-windows_usb.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
libusb_1_0_la-core.lo: core.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-core.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-core.Tpo -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-core.Tpo $(DEPDIR)/libusb_1_0_la-core.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='core.c' object='libusb_1_0_la-core.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
libusb_1_0_la-descriptor.lo: descriptor.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-descriptor.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-descriptor.Tpo -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-descriptor.Tpo $(DEPDIR)/libusb_1_0_la-descriptor.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='descriptor.c' object='libusb_1_0_la-descriptor.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
libusb_1_0_la-io.lo: io.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-io.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-io.Tpo -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-io.Tpo $(DEPDIR)/libusb_1_0_la-io.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='libusb_1_0_la-io.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
libusb_1_0_la-strerror.lo: strerror.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-strerror.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-strerror.Tpo -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-strerror.Tpo $(DEPDIR)/libusb_1_0_la-strerror.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libusb_1_0_la-strerror.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
libusb_1_0_la-sync.lo: sync.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-sync.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-sync.Tpo -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-sync.Tpo $(DEPDIR)/libusb_1_0_la-sync.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='libusb_1_0_la-sync.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
libusb_1_0_la-hotplug.lo: hotplug.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-hotplug.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-hotplug.Tpo -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-hotplug.Tpo $(DEPDIR)/libusb_1_0_la-hotplug.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hotplug.c' object='libusb_1_0_la-hotplug.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
libusb_1_0_la-threads_windows.lo: os/threads_windows.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-threads_windows.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-threads_windows.Tpo -c -o libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-threads_windows.Tpo $(DEPDIR)/libusb_1_0_la-threads_windows.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/threads_windows.c' object='libusb_1_0_la-threads_windows.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
libusb_1_0_la-threads_posix.lo: os/threads_posix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-threads_posix.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-threads_posix.Tpo -c -o libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-threads_posix.Tpo $(DEPDIR)/libusb_1_0_la-threads_posix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/threads_posix.c' object='libusb_1_0_la-threads_posix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
libusb_1_0_la-darwin_usb.lo: os/darwin_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-darwin_usb.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo -c -o libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo $(DEPDIR)/libusb_1_0_la-darwin_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/darwin_usb.c' object='libusb_1_0_la-darwin_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
libusb_1_0_la-poll_posix.lo: os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-poll_posix.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-poll_posix.Tpo -c -o libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-poll_posix.Tpo $(DEPDIR)/libusb_1_0_la-poll_posix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_posix.c' object='libusb_1_0_la-poll_posix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
libusb_1_0_la-linux_usbfs.lo: os/linux_usbfs.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-linux_usbfs.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo -c -o libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo $(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_usbfs.c' object='libusb_1_0_la-linux_usbfs.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
libusb_1_0_la-linux_netlink.lo: os/linux_netlink.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-linux_netlink.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo -c -o libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo $(DEPDIR)/libusb_1_0_la-linux_netlink.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_netlink.c' object='libusb_1_0_la-linux_netlink.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
libusb_1_0_la-linux_udev.lo: os/linux_udev.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-linux_udev.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-linux_udev.Tpo -c -o libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-linux_udev.Tpo $(DEPDIR)/libusb_1_0_la-linux_udev.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_udev.c' object='libusb_1_0_la-linux_udev.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
libusb_1_0_la-openbsd_usb.lo: os/openbsd_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-openbsd_usb.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo -c -o libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo $(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/openbsd_usb.c' object='libusb_1_0_la-openbsd_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
libusb_1_0_la-poll_windows.lo: os/poll_windows.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-poll_windows.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-poll_windows.Tpo -c -o libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-poll_windows.Tpo $(DEPDIR)/libusb_1_0_la-poll_windows.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_windows.c' object='libusb_1_0_la-poll_windows.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
libusb_1_0_la-windows_usb.lo: os/windows_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-windows_usb.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-windows_usb.Tpo -c -o libusb_1_0_la-windows_usb.lo `test -f 'os/windows_usb.c' || echo '$(srcdir)/'`os/windows_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-windows_usb.Tpo $(DEPDIR)/libusb_1_0_la-windows_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_usb.c' object='libusb_1_0_la-windows_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-windows_usb.lo `test -f 'os/windows_usb.c' || echo '$(srcdir)/'`os/windows_usb.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-hdrHEADERS: $(hdr_HEADERS)
@$(NORMAL_INSTALL)
@list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(hdrdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(hdrdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(hdrdir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(hdrdir)" || exit $$?; \
done
uninstall-hdrHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-hdrHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-hdrHEADERS install-html \
install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
uninstall-libLTLIBRARIES
all: libusb-1.0.la libusb-1.0.dll
@OS_WINDOWS_TRUE@.rc.lo:
@OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
@OS_WINDOWS_TRUE@libusb-1.0.rc: version.h version_nano.h
libusb-1.0.dll: libusb-1.0.def
# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
@CREATE_IMPORT_LIB_TRUE@ $(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

2228
Externals/libusbx/libusb/core.c vendored Normal file

File diff suppressed because it is too large Load Diff

1197
Externals/libusbx/libusb/descriptor.c vendored Normal file

File diff suppressed because it is too large Load Diff

320
Externals/libusbx/libusb/hotplug.c vendored Normal file
View File

@ -0,0 +1,320 @@
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
/*
* Hotplug functions for libusbx
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
* Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <assert.h>
#include "libusbi.h"
#include "hotplug.h"
/**
* @defgroup hotplug Device hotplug event notification
* This page details how to use the libusb hotplug interface, where available.
*
* Be mindful that not all platforms currently implement hotplug notification and
* that you should first call on \ref libusb_has_capability() with parameter
* \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available.
*
* \page hotplug Device hotplug event notification
*
* \section intro Introduction
*
* Version 1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, has added support
* for hotplug events on <b>some</b> platforms (you should test if your platform
* supports hotplug notification by calling \ref libusb_has_capability() with
* parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
*
* This interface allows you to request notification for the arrival and departure
* of matching USB devices.
*
* To receive hotplug notification you register a callback by calling
* \ref libusb_hotplug_register_callback(). This function will optionally return
* a handle that can be passed to \ref libusb_hotplug_deregister_callback().
*
* A callback function must return an int (0 or 1) indicating whether the callback is
* expecting additional events. Returning 0 will rearm the callback and 1 will cause
* the callback to be deregistered.
*
* Callbacks for a particular context are automatically deregistered by libusb_exit().
*
* As of 1.0.16 there are two supported hotplug events:
* - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use
* - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available
*
* A hotplug event can listen for either or both of these events.
*
* Note: If you receive notification that a device has left and you have any
* a libusb_device_handles for the device it is up to you to call libusb_close()
* on each handle to free up any remaining resources associated with the device.
* Once a device has left any libusb_device_handle associated with the device
* are invalid and will remain so even if the device comes back.
*
* When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered
* safe to call any libusbx function that takes a libusb_device. On the other hand,
* when handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function
* is libusb_get_device_descriptor().
*
* The following code provides an example of the usage of the hotplug interface:
\code
static int count = 0;
int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data) {
static libusb_device_handle *handle = NULL;
struct libusb_device_descriptor desc;
int rc;
(void)libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
rc = libusb_open(dev, &handle);
if (LIBUSB_SUCCESS != rc) {
printf("Could not open USB device\n");
}
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
if (handle) {
libusb_close(handle);
handle = NULL;
}
} else {
printf("Unhandled event %d\n", event);
}
count++;
return 0;
}
int main (void) {
libusb_hotplug_callback_handle handle;
int rc;
libusb_init(NULL);
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
&handle);
if (LIBUSB_SUCCESS != rc) {
printf("Error creating a hotplug callback\n");
libusb_exit(NULL);
return EXIT_FAILURE;
}
while (count < 2) {
usleep(10000);
}
libusb_hotplug_deregister_callback(handle);
libusb_exit(NULL);
return 0;
}
\endcode
*/
static int usbi_hotplug_match_cb (struct libusb_context *ctx,
struct libusb_device *dev, libusb_hotplug_event event,
struct libusb_hotplug_callback *hotplug_cb)
{
/* Handle lazy deregistration of callback */
if (hotplug_cb->needs_free) {
/* Free callback */
return 1;
}
if (!(hotplug_cb->events & event)) {
return 0;
}
if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->vendor_id &&
hotplug_cb->vendor_id != dev->device_descriptor.idVendor) {
return 0;
}
if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->product_id &&
hotplug_cb->product_id != dev->device_descriptor.idProduct) {
return 0;
}
if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->dev_class &&
hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) {
return 0;
}
return hotplug_cb->cb (ctx == usbi_default_context ? NULL : ctx,
dev, event, hotplug_cb->user_data);
}
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event)
{
struct libusb_hotplug_callback *hotplug_cb, *next;
int ret;
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
ret = usbi_hotplug_match_cb (ctx, dev, event, hotplug_cb);
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
if (ret) {
list_del(&hotplug_cb->list);
free(hotplug_cb);
}
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
/* loop through and disconnect all open handles for this device */
if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
struct libusb_device_handle *handle;
usbi_mutex_lock(&ctx->open_devs_lock);
list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) {
if (dev == handle->dev) {
usbi_handle_disconnect (handle);
}
}
usbi_mutex_unlock(&ctx->open_devs_lock);
}
}
int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
libusb_hotplug_event events, libusb_hotplug_flag flags,
int vendor_id, int product_id, int dev_class,
libusb_hotplug_callback_fn cb_fn, void *user_data,
libusb_hotplug_callback_handle *handle)
{
libusb_hotplug_callback *new_callback;
static int handle_id = 1;
/* check for hotplug support */
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
return LIBUSB_ERROR_NOT_SUPPORTED;
}
/* check for sane values */
if ((LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
(LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
(LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
!cb_fn) {
return LIBUSB_ERROR_INVALID_PARAM;
}
USBI_GET_CONTEXT(ctx);
new_callback = (libusb_hotplug_callback *)calloc(1, sizeof (*new_callback));
if (!new_callback) {
return LIBUSB_ERROR_NO_MEM;
}
new_callback->ctx = ctx;
new_callback->vendor_id = vendor_id;
new_callback->product_id = product_id;
new_callback->dev_class = dev_class;
new_callback->flags = flags;
new_callback->events = events;
new_callback->cb = cb_fn;
new_callback->user_data = user_data;
new_callback->needs_free = 0;
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
/* protect the handle by the context hotplug lock. it doesn't matter if the same handle
* is used for different contexts only that the handle is unique for this context */
new_callback->handle = handle_id++;
list_add(&new_callback->list, &ctx->hotplug_cbs);
if (flags & LIBUSB_HOTPLUG_ENUMERATE) {
struct libusb_device *dev;
usbi_mutex_lock(&ctx->usb_devs_lock);
list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) {
(void) usbi_hotplug_match_cb (ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, new_callback);
}
usbi_mutex_unlock(&ctx->usb_devs_lock);
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
if (handle) {
*handle = new_callback->handle;
}
return LIBUSB_SUCCESS;
}
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx,
libusb_hotplug_callback_handle handle)
{
struct libusb_hotplug_callback *hotplug_cb;
libusb_hotplug_message message;
ssize_t ret;
/* check for hotplug support */
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
return;
}
USBI_GET_CONTEXT(ctx);
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list,
struct libusb_hotplug_callback) {
if (handle == hotplug_cb->handle) {
/* Mark this callback for deregistration */
hotplug_cb->needs_free = 1;
}
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
/* wakeup handle_events to do the actual free */
memset(&message, 0, sizeof(message));
ret = usbi_write(ctx->hotplug_pipe[1], &message, sizeof(message));
if (sizeof(message) != ret) {
usbi_err(ctx, "error writing hotplug message");
}
}
void usbi_hotplug_deregister_all(struct libusb_context *ctx) {
struct libusb_hotplug_callback *hotplug_cb, *next;
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list,
struct libusb_hotplug_callback) {
list_del(&hotplug_cb->list);
free(hotplug_cb);
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
}

82
Externals/libusbx/libusb/hotplug.h vendored Normal file
View File

@ -0,0 +1,82 @@
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
/*
* Hotplug support for libusbx
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
* Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(USBI_HOTPLUG_H)
#define USBI_HOTPLUG_H
#ifndef LIBUSBI_H
#include "libusbi.h"
#endif
/** \ingroup hotplug
* The hotplug callback structure. The user populates this structure with
* libusb_hotplug_prepare_callback() and then calls libusb_hotplug_register_callback()
* to receive notification of hotplug events.
*/
struct libusb_hotplug_callback {
/** Context this callback is associated with */
struct libusb_context *ctx;
/** Vendor ID to match or LIBUSB_HOTPLUG_MATCH_ANY */
int vendor_id;
/** Product ID to match or LIBUSB_HOTPLUG_MATCH_ANY */
int product_id;
/** Device class to match or LIBUSB_HOTPLUG_MATCH_ANY */
int dev_class;
/** Hotplug callback flags */
libusb_hotplug_flag flags;
/** Event(s) that will trigger this callback */
libusb_hotplug_event events;
/** Callback function to invoke for matching event/device */
libusb_hotplug_callback_fn cb;
/** Handle for this callback (used to match on deregister) */
libusb_hotplug_callback_handle handle;
/** User data that will be passed to the callback function */
void *user_data;
/** Callback is marked for deletion */
int needs_free;
/** List this callback is registered in (ctx->hotplug_cbs) */
struct list_head list;
};
typedef struct libusb_hotplug_callback libusb_hotplug_callback;
struct libusb_hotplug_message {
libusb_hotplug_event event;
struct libusb_device *device;
};
typedef struct libusb_hotplug_message libusb_hotplug_message;
void usbi_hotplug_deregister_all(struct libusb_context *ctx);
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event);
#endif

2566
Externals/libusbx/libusb/io.c vendored Normal file

File diff suppressed because it is too large Load Diff

158
Externals/libusbx/libusb/libusb-1.0.def vendored Normal file
View File

@ -0,0 +1,158 @@
LIBRARY "libusb-1.0.dll"
EXPORTS
libusb_alloc_transfer
libusb_alloc_transfer@4 = libusb_alloc_transfer
libusb_attach_kernel_driver
libusb_attach_kernel_driver@8 = libusb_attach_kernel_driver
libusb_bulk_transfer
libusb_bulk_transfer@24 = libusb_bulk_transfer
libusb_cancel_transfer
libusb_cancel_transfer@4 = libusb_cancel_transfer
libusb_claim_interface
libusb_claim_interface@8 = libusb_claim_interface
libusb_clear_halt
libusb_clear_halt@8 = libusb_clear_halt
libusb_close
libusb_close@4 = libusb_close
libusb_control_transfer
libusb_control_transfer@32 = libusb_control_transfer
libusb_detach_kernel_driver
libusb_detach_kernel_driver@8 = libusb_detach_kernel_driver
libusb_error_name
libusb_error_name@4 = libusb_error_name
libusb_event_handler_active
libusb_event_handler_active@4 = libusb_event_handler_active
libusb_event_handling_ok
libusb_event_handling_ok@4 = libusb_event_handling_ok
libusb_exit
libusb_exit@4 = libusb_exit
libusb_free_bos_descriptor
libusb_free_bos_descriptor@4 = libusb_free_bos_descriptor
libusb_free_config_descriptor
libusb_free_config_descriptor@4 = libusb_free_config_descriptor
libusb_free_container_id_descriptor
libusb_free_container_id_descriptor@4 = libusb_free_container_id_descriptor
libusb_free_device_list
libusb_free_device_list@8 = libusb_free_device_list
libusb_free_ss_endpoint_companion_descriptor
libusb_free_ss_endpoint_companion_descriptor@4 = libusb_free_ss_endpoint_companion_descriptor
libusb_free_ss_usb_device_capability_descriptor
libusb_free_ss_usb_device_capability_descriptor@4 = libusb_free_ss_usb_device_capability_descriptor
libusb_free_transfer
libusb_free_transfer@4 = libusb_free_transfer
libusb_free_usb_2_0_extension_descriptor
libusb_free_usb_2_0_extension_descriptor@4 = libusb_free_usb_2_0_extension_descriptor
libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@8 = libusb_get_active_config_descriptor
libusb_get_bos_descriptor
libusb_get_bos_descriptor@8 = libusb_get_bos_descriptor
libusb_get_bus_number
libusb_get_bus_number@4 = libusb_get_bus_number
libusb_get_config_descriptor
libusb_get_config_descriptor@12 = libusb_get_config_descriptor
libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@12 = libusb_get_config_descriptor_by_value
libusb_get_configuration
libusb_get_configuration@8 = libusb_get_configuration
libusb_get_container_id_descriptor
libusb_get_container_id_descriptor@12 = libusb_get_container_id_descriptor
libusb_get_device
libusb_get_device@4 = libusb_get_device
libusb_get_device_address
libusb_get_device_address@4 = libusb_get_device_address
libusb_get_device_descriptor
libusb_get_device_descriptor@8 = libusb_get_device_descriptor
libusb_get_device_list
libusb_get_device_list@8 = libusb_get_device_list
libusb_get_device_speed
libusb_get_device_speed@4 = libusb_get_device_speed
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@8 = libusb_get_max_packet_size
libusb_get_next_timeout
libusb_get_next_timeout@8 = libusb_get_next_timeout
libusb_get_parent
libusb_get_parent@4 = libusb_get_parent
libusb_get_pollfds
libusb_get_pollfds@4 = libusb_get_pollfds
libusb_get_port_number
libusb_get_port_number@4 = libusb_get_port_number
libusb_get_port_numbers
libusb_get_port_numbers@12 = libusb_get_port_numbers
libusb_get_port_path
libusb_get_port_path@16 = libusb_get_port_path
libusb_get_ss_endpoint_companion_descriptor
libusb_get_ss_endpoint_companion_descriptor@12 = libusb_get_ss_endpoint_companion_descriptor
libusb_get_ss_usb_device_capability_descriptor
libusb_get_ss_usb_device_capability_descriptor@12 = libusb_get_ss_usb_device_capability_descriptor
libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@16 = libusb_get_string_descriptor_ascii
libusb_get_usb_2_0_extension_descriptor
libusb_get_usb_2_0_extension_descriptor@12 = libusb_get_usb_2_0_extension_descriptor
libusb_get_version
libusb_get_version@0 = libusb_get_version
libusb_handle_events
libusb_handle_events@4 = libusb_handle_events
libusb_handle_events_completed
libusb_handle_events_completed@8 = libusb_handle_events_completed
libusb_handle_events_locked
libusb_handle_events_locked@8 = libusb_handle_events_locked
libusb_handle_events_timeout
libusb_handle_events_timeout@8 = libusb_handle_events_timeout
libusb_handle_events_timeout_completed
libusb_handle_events_timeout_completed@12 = libusb_handle_events_timeout_completed
libusb_has_capability
libusb_has_capability@4 = libusb_has_capability
libusb_hotplug_deregister_callback
libusb_hotplug_deregister_callback@8 = libusb_hotplug_deregister_callback
libusb_hotplug_register_callback
libusb_hotplug_register_callback@36 = libusb_hotplug_register_callback
libusb_init
libusb_init@4 = libusb_init
libusb_interrupt_transfer
libusb_interrupt_transfer@24 = libusb_interrupt_transfer
libusb_kernel_driver_active
libusb_kernel_driver_active@8 = libusb_kernel_driver_active
libusb_lock_event_waiters
libusb_lock_event_waiters@4 = libusb_lock_event_waiters
libusb_lock_events
libusb_lock_events@4 = libusb_lock_events
libusb_open
libusb_open@8 = libusb_open
libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@12 = libusb_open_device_with_vid_pid
libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@4 = libusb_pollfds_handle_timeouts
libusb_ref_device
libusb_ref_device@4 = libusb_ref_device
libusb_release_interface
libusb_release_interface@8 = libusb_release_interface
libusb_reset_device
libusb_reset_device@4 = libusb_reset_device
libusb_set_auto_detach_kernel_driver
libusb_set_auto_detach_kernel_driver@8 = libusb_set_auto_detach_kernel_driver
libusb_set_configuration
libusb_set_configuration@8 = libusb_set_configuration
libusb_set_debug
libusb_set_debug@8 = libusb_set_debug
libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
libusb_setlocale
libusb_setlocale@4 = libusb_setlocale
libusb_strerror
libusb_strerror@4 = libusb_strerror
libusb_submit_transfer
libusb_submit_transfer@4 = libusb_submit_transfer
libusb_try_lock_events
libusb_try_lock_events@4 = libusb_try_lock_events
libusb_unlock_event_waiters
libusb_unlock_event_waiters@4 = libusb_unlock_event_waiters
libusb_unlock_events
libusb_unlock_events@4 = libusb_unlock_events
libusb_unref_device
libusb_unref_device@4 = libusb_unref_device
libusb_wait_for_event
libusb_wait_for_event@8 = libusb_wait_for_event

61
Externals/libusbx/libusb/libusb-1.0.rc vendored Normal file
View File

@ -0,0 +1,61 @@
/*
* For Windows: input this file to the Resoure Compiler to produce a binary
* .res file. This is then embedded in the resultant library (like any other
* compilation object).
* The information can then be queried using standard APIs and can also be
* viewed with utilities such as Windows Explorer.
*/
#ifndef _WIN32_WCE
#include "winresrc.h"
#endif
#include "version.h"
#ifndef LIBUSB_VERSIONSTRING
#define LU_STR(s) #s
#define LU_XSTR(s) LU_STR(s)
#if LIBUSB_NANO > 0
#define LIBUSB_VERSIONSTRING \
LU_XSTR(LIBUSB_MAJOR) "." LU_XSTR(LIBUSB_MINOR) "." \
LU_XSTR(LIBUSB_MICRO) "." LU_XSTR(LIBUSB_NANO) LIBUSB_RC "\0"
#else
#define LIBUSB_VERSIONSTRING \
LU_XSTR(LIBUSB_MAJOR) "." LU_XSTR(LIBUSB_MINOR) "." \
LU_XSTR(LIBUSB_MICRO) LIBUSB_RC "\0"
#endif
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION LIBUSB_MAJOR,LIBUSB_MINOR,LIBUSB_MICRO,LIBUSB_NANO
PRODUCTVERSION LIBUSB_MAJOR,LIBUSB_MINOR,LIBUSB_MICRO,LIBUSB_NANO
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "libusbx.org\0"
VALUE "FileDescription", "C library for writing portable USB drivers in userspace\0"
VALUE "FileVersion", LIBUSB_VERSIONSTRING
VALUE "InternalName", "libusb\0"
VALUE "LegalCopyright", "See individual source files, GNU LGPL v2.1 or later.\0"
VALUE "LegalTrademarks", "http://www.gnu.org/licenses/lgpl-2.1.html\0"
VALUE "OriginalFilename", "libusb-1.0.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libusb-1.0\0"
VALUE "ProductVersion", LIBUSB_VERSIONSTRING
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

1941
Externals/libusbx/libusb/libusb.h vendored Normal file

File diff suppressed because it is too large Load Diff

1004
Externals/libusbx/libusb/libusbi.h vendored Normal file

File diff suppressed because it is too large Load Diff

1903
Externals/libusbx/libusb/os/darwin_usb.c vendored Normal file

File diff suppressed because it is too large Load Diff

162
Externals/libusbx/libusb/os/darwin_usb.h vendored Normal file
View File

@ -0,0 +1,162 @@
/*
* darwin backend for libusbx 1.0
* Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(LIBUSB_DARWIN_H)
#define LIBUSB_DARWIN_H
#include "libusbi.h"
#include <IOKit/IOTypes.h>
#include <IOKit/IOCFBundle.h>
#include <IOKit/usb/IOUSBLib.h>
#include <IOKit/IOCFPlugIn.h>
/* IOUSBInterfaceInferface */
#if defined (kIOUSBInterfaceInterfaceID550)
#define usb_interface_t IOUSBInterfaceInterface550
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550
#define InterfaceVersion 550
#elif defined (kIOUSBInterfaceInterfaceID500)
#define usb_interface_t IOUSBInterfaceInterface500
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID500
#define InterfaceVersion 500
#elif defined (kIOUSBInterfaceInterfaceID300)
#define usb_interface_t IOUSBInterfaceInterface300
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300
#define InterfaceVersion 300
#elif defined (kIOUSBInterfaceInterfaceID245)
#define usb_interface_t IOUSBInterfaceInterface245
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245
#define InterfaceVersion 245
#elif defined (kIOUSBInterfaceInterfaceID220)
#define usb_interface_t IOUSBInterfaceInterface220
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
#define InterfaceVersion 220
#else
#error "IOUSBFamily is too old. Please upgrade your OS"
#endif
/* IOUSBDeviceInterface */
#if defined (kIOUSBDeviceInterfaceID500)
#define usb_device_t IOUSBDeviceInterface500
#define DeviceInterfaceID kIOUSBDeviceInterfaceID500
#define DeviceVersion 500
#elif defined (kIOUSBDeviceInterfaceID320)
#define usb_device_t IOUSBDeviceInterface320
#define DeviceInterfaceID kIOUSBDeviceInterfaceID320
#define DeviceVersion 320
#elif defined (kIOUSBDeviceInterfaceID300)
#define usb_device_t IOUSBDeviceInterface300
#define DeviceInterfaceID kIOUSBDeviceInterfaceID300
#define DeviceVersion 300
#elif defined (kIOUSBDeviceInterfaceID245)
#define usb_device_t IOUSBDeviceInterface245
#define DeviceInterfaceID kIOUSBDeviceInterfaceID245
#define DeviceVersion 245
#elif defined (kIOUSBDeviceInterfaceID220)
#define usb_device_t IOUSBDeviceInterface197
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
#define DeviceVersion 197
#else
#error "IOUSBFamily is too old. Please upgrade your OS"
#endif
#if !defined(IO_OBJECT_NULL)
#define IO_OBJECT_NULL ((io_object_t) 0)
#endif
typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
typedef IONotificationPortRef io_notification_port_t;
/* private structures */
struct darwin_cached_device {
struct list_head list;
IOUSBDeviceDescriptor dev_descriptor;
UInt32 location;
UInt64 parent_session;
UInt64 session;
UInt16 address;
char sys_path[21];
usb_device_t **device;
int open_count;
UInt8 first_config, active_config, port;
int can_enumerate;
int refcount;
};
struct darwin_device_priv {
struct darwin_cached_device *dev;
};
struct darwin_device_handle_priv {
int is_open;
CFRunLoopSourceRef cfSource;
int fds[2];
struct darwin_interface {
usb_interface_t **interface;
uint8_t num_endpoints;
CFRunLoopSourceRef cfSource;
uint64_t frames[256];
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
} interfaces[USB_MAXINTERFACES];
};
struct darwin_transfer_priv {
/* Isoc */
IOUSBIsocFrame *isoc_framelist;
int num_iso_packets;
/* Control */
IOUSBDevRequestTO req;
/* Bulk */
};
/* structure for signaling io completion */
struct darwin_msg_async_io_complete {
struct usbi_transfer *itransfer;
IOReturn result;
UInt32 size;
};
#endif

View File

@ -0,0 +1,254 @@
/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */
/*
* Linux usbfs backend for libusb
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.com>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "libusb.h"
#include "libusbi.h"
#include "linux_usbfs.h"
#include <linux/netlink.h>
#include <linux/filter.h>
#define KERNEL 1
static int linux_netlink_socket = -1;
static pthread_t libusb_linux_event_thread;
static void *linux_netlink_event_thread_main(void *arg);
struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL };
int linux_netlink_start_event_monitor(void)
{
int ret;
snl.nl_groups = KERNEL;
linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
if (-1 == linux_netlink_socket) {
return LIBUSB_ERROR_OTHER;
}
ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl));
if (0 != ret) {
return LIBUSB_ERROR_OTHER;
}
/* TODO -- add authentication */
/* setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); */
ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL);
if (0 != ret) {
return LIBUSB_ERROR_OTHER;
}
return LIBUSB_SUCCESS;
}
int linux_netlink_stop_event_monitor(void)
{
int r;
if (-1 == linux_netlink_socket) {
/* already closed. nothing to do */
return LIBUSB_SUCCESS;
}
r = close(linux_netlink_socket);
if (0 > r) {
usbi_err(NULL, "error closing netlink socket. %s", strerror(errno));
return LIBUSB_ERROR_OTHER;
}
pthread_cancel(libusb_linux_event_thread);
linux_netlink_socket = -1;
return LIBUSB_SUCCESS;
}
static const char *netlink_message_parse (const char *buffer, size_t len, const char *key)
{
size_t keylen = strlen(key);
size_t offset;
for (offset = 0 ; offset < len && '\0' != buffer[offset] ; offset += strlen(buffer + offset) + 1) {
if (0 == strncmp(buffer + offset, key, keylen) &&
'=' == buffer[offset + keylen]) {
return buffer + offset + keylen + 1;
}
}
return NULL;
}
/* parse parts of netlink message common to both libudev and the kernel */
static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name,
uint8_t *busnum, uint8_t *devaddr) {
const char *tmp;
int i;
errno = 0;
*sys_name = NULL;
*detached = 0;
*busnum = 0;
*devaddr = 0;
tmp = netlink_message_parse((const char *) buffer, len, "ACTION");
if (tmp == NULL)
return -1;
if (0 == strcmp(tmp, "remove")) {
*detached = 1;
} else if (0 != strcmp(tmp, "add")) {
usbi_dbg("unknown device action %s", tmp);
return -1;
}
/* check that this is a usb message */
tmp = netlink_message_parse(buffer, len, "SUBSYSTEM");
if (NULL == tmp || 0 != strcmp(tmp, "usb")) {
/* not usb. ignore */
return -1;
}
tmp = netlink_message_parse(buffer, len, "BUSNUM");
if (NULL == tmp) {
/* no bus number (likely a usb interface). ignore*/
return -1;
}
*busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
if (errno) {
errno = 0;
return -1;
}
tmp = netlink_message_parse(buffer, len, "DEVNUM");
if (NULL == tmp) {
return -1;
}
*devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
if (errno) {
errno = 0;
return -1;
}
tmp = netlink_message_parse(buffer, len, "DEVPATH");
if (NULL == tmp) {
return -1;
}
for (i = strlen(tmp) - 1 ; i ; --i) {
if ('/' ==tmp[i]) {
*sys_name = tmp + i + 1;
break;
}
}
/* found a usb device */
return 0;
}
static int linux_netlink_read_message(void)
{
unsigned char buffer[1024];
struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)};
struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
.msg_name=&snl, .msg_namelen=sizeof(snl) };
const char *sys_name = NULL;
uint8_t busnum, devaddr;
int detached, r;
size_t len;
/* read netlink message */
memset(buffer, 0, sizeof(buffer));
len = recvmsg(linux_netlink_socket, &meh, 0);
if (len < 32) {
if (errno != EAGAIN)
usbi_dbg("error recieving message from netlink");
return -1;
}
/* TODO -- authenticate this message is from the kernel or udevd */
r = linux_netlink_parse(buffer, len, &detached, &sys_name,
&busnum, &devaddr);
if (r)
return r;
usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
busnum, devaddr, sys_name, detached ? "yes" : "no");
/* signal device is available (or not) to all contexts */
if (detached)
linux_hotplug_disconnected(busnum, devaddr, sys_name);
else
linux_hotplug_enumerate(busnum, devaddr, sys_name);
return 0;
}
static void *linux_netlink_event_thread_main(void *arg)
{
struct pollfd fds = {.fd = linux_netlink_socket,
.events = POLLIN};
/* silence compiler warning */
(void) arg;
while (1 == poll(&fds, 1, -1)) {
if (POLLIN != fds.revents) {
break;
}
usbi_mutex_static_lock(&linux_hotplug_lock);
linux_netlink_read_message();
usbi_mutex_static_unlock(&linux_hotplug_lock);
}
return NULL;
}
void linux_netlink_hotplug_poll(void)
{
int r;
usbi_mutex_static_lock(&linux_hotplug_lock);
do {
r = linux_netlink_read_message();
} while (r == 0);
usbi_mutex_static_unlock(&linux_hotplug_lock);
}

273
Externals/libusbx/libusb/os/linux_udev.c vendored Normal file
View File

@ -0,0 +1,273 @@
/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */
/*
* Linux usbfs backend for libusb
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* Copyright (c) 2012-2013 Nathan Hjelm <hjelmn@mac.com>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <unistd.h>
#include <libudev.h>
#include "libusb.h"
#include "libusbi.h"
#include "linux_usbfs.h"
/* udev context */
static struct udev *udev_ctx = NULL;
static int udev_monitor_fd = -1;
static struct udev_monitor *udev_monitor = NULL;
static pthread_t linux_event_thread;
static void udev_hotplug_event(struct udev_device* udev_dev);
static void *linux_udev_event_thread_main(void *arg);
int linux_udev_start_event_monitor(void)
{
int r;
assert(udev_ctx == NULL);
udev_ctx = udev_new();
if (!udev_ctx) {
usbi_err(NULL, "could not create udev context");
return LIBUSB_ERROR_OTHER;
}
udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev");
if (!udev_monitor) {
usbi_err(NULL, "could not initialize udev monitor");
goto err_free_ctx;
}
r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", 0);
if (r) {
usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem");
goto err_free_monitor;
}
if (udev_monitor_enable_receiving(udev_monitor)) {
usbi_err(NULL, "failed to enable the udev monitor");
goto err_free_monitor;
}
udev_monitor_fd = udev_monitor_get_fd(udev_monitor);
/* Some older versions of udev are not non-blocking by default,
* so make sure this is set */
r = fcntl(udev_monitor_fd, F_GETFL);
if (r == -1) {
usbi_err(NULL, "getting udev monitor fd flags (%d)", errno);
goto err_free_monitor;
}
r = fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK);
if (r) {
usbi_err(NULL, "setting udev monitor fd flags (%d)", errno);
goto err_free_monitor;
}
r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL);
if (r) {
usbi_err(NULL, "creating hotplug event thread (%d)", r);
goto err_free_monitor;
}
return LIBUSB_SUCCESS;
err_free_monitor:
udev_monitor_unref(udev_monitor);
udev_monitor = NULL;
udev_monitor_fd = -1;
err_free_ctx:
udev_unref(udev_ctx);
udev_ctx = NULL;
return LIBUSB_ERROR_OTHER;
}
int linux_udev_stop_event_monitor(void)
{
assert(udev_ctx != NULL);
assert(udev_monitor != NULL);
assert(udev_monitor_fd != -1);
/* Cancel the event thread. This is the only way to guarantee the
thread exits since closing the monitor fd won't necessarily cause
poll to return. */
pthread_cancel(linux_event_thread);
pthread_join(linux_event_thread, NULL);
/* Release the udev monitor */
udev_monitor_unref(udev_monitor);
udev_monitor = NULL;
udev_monitor_fd = -1;
/* Clean up the udev context */
udev_unref(udev_ctx);
udev_ctx = NULL;
return LIBUSB_SUCCESS;
}
static void *linux_udev_event_thread_main(void *arg)
{
struct udev_device* udev_dev;
struct pollfd fds = {.fd = udev_monitor_fd,
.events = POLLIN};
usbi_dbg("udev event thread entering.");
while (1 == poll(&fds, 1, -1)) {
if (NULL == udev_monitor || POLLIN != fds.revents) {
break;
}
usbi_mutex_static_lock(&linux_hotplug_lock);
udev_dev = udev_monitor_receive_device(udev_monitor);
if (udev_dev)
udev_hotplug_event(udev_dev);
usbi_mutex_static_unlock(&linux_hotplug_lock);
}
usbi_dbg("udev event thread exiting");
return NULL;
}
static int udev_device_info(struct libusb_context *ctx, int detached,
struct udev_device *udev_dev, uint8_t *busnum,
uint8_t *devaddr, const char **sys_name) {
const char *dev_node;
dev_node = udev_device_get_devnode(udev_dev);
if (!dev_node) {
return LIBUSB_ERROR_OTHER;
}
*sys_name = udev_device_get_sysname(udev_dev);
if (!*sys_name) {
return LIBUSB_ERROR_OTHER;
}
return linux_get_device_address(ctx, detached, busnum, devaddr,
dev_node, *sys_name);
}
static void udev_hotplug_event(struct udev_device* udev_dev)
{
const char* udev_action;
const char* sys_name = NULL;
uint8_t busnum = 0, devaddr = 0;
int detached;
int r;
do {
udev_action = udev_device_get_action(udev_dev);
if (!udev_action) {
break;
}
detached = !strncmp(udev_action, "remove", 6);
r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name);
if (LIBUSB_SUCCESS != r) {
break;
}
usbi_dbg("udev hotplug event. action: %s.", udev_action);
if (strncmp(udev_action, "add", 3) == 0) {
linux_hotplug_enumerate(busnum, devaddr, sys_name);
} else if (detached) {
linux_hotplug_disconnected(busnum, devaddr, sys_name);
} else {
usbi_err(NULL, "ignoring udev action %s", udev_action);
}
} while (0);
udev_device_unref(udev_dev);
}
int linux_udev_scan_devices(struct libusb_context *ctx)
{
struct udev_enumerate *enumerator;
struct udev_list_entry *devices, *entry;
struct udev_device *udev_dev;
const char *sys_name;
int r;
assert(udev_ctx != NULL);
enumerator = udev_enumerate_new(udev_ctx);
if (NULL == enumerator) {
usbi_err(ctx, "error creating udev enumerator");
return LIBUSB_ERROR_OTHER;
}
udev_enumerate_add_match_subsystem(enumerator, "usb");
udev_enumerate_scan_devices(enumerator);
devices = udev_enumerate_get_list_entry(enumerator);
udev_list_entry_foreach(entry, devices) {
const char *path = udev_list_entry_get_name(entry);
uint8_t busnum = 0, devaddr = 0;
udev_dev = udev_device_new_from_syspath(udev_ctx, path);
r = udev_device_info(ctx, 0, udev_dev, &busnum, &devaddr, &sys_name);
if (r) {
udev_device_unref(udev_dev);
continue;
}
linux_enumerate_device(ctx, busnum, devaddr, sys_name);
udev_device_unref(udev_dev);
}
udev_enumerate_unref(enumerator);
return LIBUSB_SUCCESS;
}
void linux_udev_hotplug_poll(void)
{
struct udev_device* udev_dev;
usbi_mutex_static_lock(&linux_hotplug_lock);
do {
udev_dev = udev_monitor_receive_device(udev_monitor);
if (udev_dev) {
usbi_dbg("Handling hotplug event from hotplug_poll");
udev_hotplug_event(udev_dev);
}
} while (udev_dev);
usbi_mutex_static_unlock(&linux_hotplug_lock);
}

2568
Externals/libusbx/libusb/os/linux_usbfs.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,181 @@
/*
* usbfs header structures
* Copyright © 2007 Daniel Drake <dsd@gentoo.org>
* Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_USBFS_H
#define LIBUSB_USBFS_H
#include <linux/types.h>
#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices"
struct usbfs_ctrltransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint32_t timeout; /* in milliseconds */
/* pointer to data */
void *data;
};
struct usbfs_bulktransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_bulktransfer */
unsigned int ep;
unsigned int len;
unsigned int timeout; /* in milliseconds */
/* pointer to data */
void *data;
};
struct usbfs_setinterface {
/* keep in sync with usbdevice_fs.h:usbdevfs_setinterface */
unsigned int interface;
unsigned int altsetting;
};
#define USBFS_MAXDRIVERNAME 255
struct usbfs_getdriver {
unsigned int interface;
char driver[USBFS_MAXDRIVERNAME + 1];
};
#define USBFS_URB_SHORT_NOT_OK 0x01
#define USBFS_URB_ISO_ASAP 0x02
#define USBFS_URB_BULK_CONTINUATION 0x04
#define USBFS_URB_QUEUE_BULK 0x10
#define USBFS_URB_ZERO_PACKET 0x40
enum usbfs_urb_type {
USBFS_URB_TYPE_ISO = 0,
USBFS_URB_TYPE_INTERRUPT = 1,
USBFS_URB_TYPE_CONTROL = 2,
USBFS_URB_TYPE_BULK = 3,
};
struct usbfs_iso_packet_desc {
unsigned int length;
unsigned int actual_length;
unsigned int status;
};
#define MAX_ISO_BUFFER_LENGTH 32768
#define MAX_BULK_BUFFER_LENGTH 16384
#define MAX_CTRL_BUFFER_LENGTH 4096
struct usbfs_urb {
unsigned char type;
unsigned char endpoint;
int status;
unsigned int flags;
void *buffer;
int buffer_length;
int actual_length;
int start_frame;
int number_of_packets;
int error_count;
unsigned int signr;
void *usercontext;
struct usbfs_iso_packet_desc iso_frame_desc[0];
};
struct usbfs_connectinfo {
unsigned int devnum;
unsigned char slow;
};
struct usbfs_ioctl {
int ifno; /* interface 0..N ; negative numbers reserved */
int ioctl_code; /* MUST encode size + direction of data so the
* macros in <asm/ioctl.h> give correct values */
void *data; /* param buffer (in, or out) */
};
struct usbfs_hub_portinfo {
unsigned char numports;
unsigned char port[127]; /* port to device num mapping */
};
#define USBFS_CAP_ZERO_PACKET 0x01
#define USBFS_CAP_BULK_CONTINUATION 0x02
#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04
#define USBFS_CAP_BULK_SCATTER_GATHER 0x08
#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
struct usbfs_disconnect_claim {
unsigned int interface;
unsigned int flags;
char driver[USBFS_MAXDRIVERNAME + 1];
};
#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
#define IOCTL_USBFS_SETINTF _IOR('U', 4, struct usbfs_setinterface)
#define IOCTL_USBFS_SETCONFIG _IOR('U', 5, unsigned int)
#define IOCTL_USBFS_GETDRIVER _IOW('U', 8, struct usbfs_getdriver)
#define IOCTL_USBFS_SUBMITURB _IOR('U', 10, struct usbfs_urb)
#define IOCTL_USBFS_DISCARDURB _IO('U', 11)
#define IOCTL_USBFS_REAPURB _IOW('U', 12, void *)
#define IOCTL_USBFS_REAPURBNDELAY _IOW('U', 13, void *)
#define IOCTL_USBFS_CLAIMINTF _IOR('U', 15, unsigned int)
#define IOCTL_USBFS_RELEASEINTF _IOR('U', 16, unsigned int)
#define IOCTL_USBFS_CONNECTINFO _IOW('U', 17, struct usbfs_connectinfo)
#define IOCTL_USBFS_IOCTL _IOWR('U', 18, struct usbfs_ioctl)
#define IOCTL_USBFS_HUB_PORTINFO _IOR('U', 19, struct usbfs_hub_portinfo)
#define IOCTL_USBFS_RESET _IO('U', 20)
#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int)
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
#define IOCTL_USBFS_CONNECT _IO('U', 23)
#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int)
#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int)
#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32)
#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim)
extern usbi_mutex_static_t linux_hotplug_lock;
#if defined(HAVE_LIBUDEV)
int linux_udev_start_event_monitor(void);
int linux_udev_stop_event_monitor(void);
int linux_udev_scan_devices(struct libusb_context *ctx);
void linux_udev_hotplug_poll(void);
#else
int linux_netlink_start_event_monitor(void);
int linux_netlink_stop_event_monitor(void);
void linux_netlink_hotplug_poll(void);
#endif
void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name);
void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name);
int linux_get_device_address (struct libusb_context *ctx, int detached,
uint8_t *busnum, uint8_t *devaddr, const char *dev_node,
const char *sys_name);
int linux_enumerate_device(struct libusb_context *ctx,
uint8_t busnum, uint8_t devaddr, const char *sysfs_dir);
#endif

View File

@ -0,0 +1,734 @@
/*
* Copyright © 2011 Martin Pieuchot <mpi@openbsd.org>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dev/usb/usb.h>
#include "libusb.h"
#include "libusbi.h"
struct device_priv {
char devnode[16];
int fd;
unsigned char *cdesc; /* active config descriptor */
usb_device_descriptor_t ddesc; /* usb device descriptor */
};
struct handle_priv {
int pipe[2]; /* for event notification */
int endpoints[USB_MAX_ENDPOINTS];
};
/*
* Backend functions
*/
static int obsd_get_device_list(struct libusb_context *,
struct discovered_devs **);
static int obsd_open(struct libusb_device_handle *);
static void obsd_close(struct libusb_device_handle *);
static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *,
int *);
static int obsd_get_active_config_descriptor(struct libusb_device *,
unsigned char *, size_t, int *);
static int obsd_get_config_descriptor(struct libusb_device *, uint8_t,
unsigned char *, size_t, int *);
static int obsd_get_configuration(struct libusb_device_handle *, int *);
static int obsd_set_configuration(struct libusb_device_handle *, int);
static int obsd_claim_interface(struct libusb_device_handle *, int);
static int obsd_release_interface(struct libusb_device_handle *, int);
static int obsd_set_interface_altsetting(struct libusb_device_handle *, int,
int);
static int obsd_clear_halt(struct libusb_device_handle *, unsigned char);
static int obsd_reset_device(struct libusb_device_handle *);
static void obsd_destroy_device(struct libusb_device *);
static int obsd_submit_transfer(struct usbi_transfer *);
static int obsd_cancel_transfer(struct usbi_transfer *);
static void obsd_clear_transfer_priv(struct usbi_transfer *);
static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *,
nfds_t, int);
static int obsd_clock_gettime(int, struct timespec *);
/*
* Private functions
*/
static int _errno_to_libusb(int);
static int _cache_active_config_descriptor(struct libusb_device *, int);
static int _sync_control_transfer(struct usbi_transfer *);
static int _sync_gen_transfer(struct usbi_transfer *);
static int _access_endpoint(struct libusb_transfer *);
const struct usbi_os_backend openbsd_backend = {
"Synchronous OpenBSD backend",
0,
NULL, /* init() */
NULL, /* exit() */
obsd_get_device_list,
NULL, /* hotplug_poll */
obsd_open,
obsd_close,
obsd_get_device_descriptor,
obsd_get_active_config_descriptor,
obsd_get_config_descriptor,
NULL, /* get_config_descriptor_by_value() */
obsd_get_configuration,
obsd_set_configuration,
obsd_claim_interface,
obsd_release_interface,
obsd_set_interface_altsetting,
obsd_clear_halt,
obsd_reset_device,
NULL, /* kernel_driver_active() */
NULL, /* detach_kernel_driver() */
NULL, /* attach_kernel_driver() */
obsd_destroy_device,
obsd_submit_transfer,
obsd_cancel_transfer,
obsd_clear_transfer_priv,
obsd_handle_events,
obsd_clock_gettime,
sizeof(struct device_priv),
sizeof(struct handle_priv),
0, /* transfer_priv_size */
0, /* add_iso_packet_size */
};
int
obsd_get_device_list(struct libusb_context * ctx,
struct discovered_devs **discdevs)
{
struct libusb_device *dev;
struct device_priv *dpriv;
struct usb_device_info di;
unsigned long session_id;
char devnode[16];
int fd, err, i;
usbi_dbg("");
/* Only ugen(4) is supported */
for (i = 0; i < USB_MAX_DEVICES; i++) {
/* Control endpoint is always .00 */
snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i);
if ((fd = open(devnode, O_RDONLY)) < 0) {
if (errno != ENOENT && errno != ENXIO)
usbi_err(ctx, "could not open %s", devnode);
continue;
}
if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0)
continue;
session_id = (di.udi_bus << 8 | di.udi_addr);
dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev) {
dev = libusb_ref_device(dev);
} else {
dev = usbi_alloc_device(ctx, session_id);
if (dev == NULL)
return (LIBUSB_ERROR_NO_MEM);
dev->bus_number = di.udi_bus;
dev->device_address = di.udi_addr;
dev->speed = di.udi_speed;
dpriv = (struct device_priv *)dev->os_priv;
strlcpy(dpriv->devnode, devnode, sizeof(devnode));
dpriv->fd = -1;
if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) {
err = errno;
goto error;
}
dpriv->cdesc = NULL;
if (_cache_active_config_descriptor(dev, fd)) {
err = errno;
goto error;
}
if ((err = usbi_sanitize_device(dev)))
goto error;
}
close(fd);
if (discovered_devs_append(*discdevs, dev) == NULL)
return (LIBUSB_ERROR_NO_MEM);
libusb_unref_device(dev);
}
return (LIBUSB_SUCCESS);
error:
close(fd);
libusb_unref_device(dev);
return _errno_to_libusb(err);
}
int
obsd_open(struct libusb_device_handle *handle)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
dpriv->fd = open(dpriv->devnode, O_RDWR);
if (dpriv->fd < 0) {
dpriv->fd = open(dpriv->devnode, O_RDONLY);
if (dpriv->fd < 0)
return _errno_to_libusb(errno);
}
usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
if (pipe(hpriv->pipe) < 0)
return _errno_to_libusb(errno);
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
}
void
obsd_close(struct libusb_device_handle *handle)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usbi_dbg("close: fd %d", dpriv->fd);
close(dpriv->fd);
dpriv->fd = -1;
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
close(hpriv->pipe[0]);
close(hpriv->pipe[1]);
}
int
obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usbi_dbg("");
memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH);
*host_endian = 0;
return (LIBUSB_SUCCESS);
}
int
obsd_get_active_config_descriptor(struct libusb_device *dev,
unsigned char *buf, size_t len, int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usb_config_descriptor_t *ucd;
ucd = (usb_config_descriptor_t *) dpriv->cdesc;
len = MIN(len, UGETW(ucd->wTotalLength));
usbi_dbg("len %d", len);
memcpy(buf, dpriv->cdesc, len);
*host_endian = 0;
return len;
}
int
obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
unsigned char *buf, size_t len, int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
struct usb_full_desc ufd;
int fd, err;
usbi_dbg("index %d, len %d", idx, len);
/* A config descriptor may be requested before opening the device */
if (dpriv->fd >= 0) {
fd = dpriv->fd;
} else {
fd = open(dpriv->devnode, O_RDONLY);
if (fd < 0)
return _errno_to_libusb(errno);
}
ufd.ufd_config_index = idx;
ufd.ufd_size = len;
ufd.ufd_data = buf;
if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
err = errno;
if (dpriv->fd < 0)
close(fd);
return _errno_to_libusb(err);
}
if (dpriv->fd < 0)
close(fd);
*host_endian = 0;
return len;
}
int
obsd_get_configuration(struct libusb_device_handle *handle, int *config)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usbi_dbg("");
if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0)
return _errno_to_libusb(errno);
usbi_dbg("configuration %d", *config);
return (LIBUSB_SUCCESS);
}
int
obsd_set_configuration(struct libusb_device_handle *handle, int config)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usbi_dbg("configuration %d", config);
if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
return _errno_to_libusb(errno);
return _cache_active_config_descriptor(handle->dev, dpriv->fd);
}
int
obsd_claim_interface(struct libusb_device_handle *handle, int iface)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
int i;
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
hpriv->endpoints[i] = -1;
return (LIBUSB_SUCCESS);
}
int
obsd_release_interface(struct libusb_device_handle *handle, int iface)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
int i;
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
if (hpriv->endpoints[i] >= 0)
close(hpriv->endpoints[i]);
return (LIBUSB_SUCCESS);
}
int
obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
int altsetting)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
struct usb_alt_interface intf;
usbi_dbg("iface %d, setting %d", iface, altsetting);
memset(&intf, 0, sizeof(intf));
intf.uai_interface_index = iface;
intf.uai_alt_no = altsetting;
if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
struct usb_ctl_request req;
usbi_dbg("");
req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
req.ucr_request.bRequest = UR_CLEAR_FEATURE;
USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
USETW(req.ucr_request.wIndex, endpoint);
USETW(req.ucr_request.wLength, 0);
if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
obsd_reset_device(struct libusb_device_handle *handle)
{
usbi_dbg("");
return (LIBUSB_ERROR_NOT_SUPPORTED);
}
void
obsd_destroy_device(struct libusb_device *dev)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usbi_dbg("");
free(dpriv->cdesc);
}
int
obsd_submit_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct handle_priv *hpriv;
int err = 0;
usbi_dbg("");
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
err = _sync_control_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
if (IS_XFEROUT(transfer)) {
/* Isochronous write is not supported */
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
err = _sync_gen_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
if (IS_XFEROUT(transfer) &&
transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
err = _sync_gen_transfer(itransfer);
break;
}
if (err)
return (err);
if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
obsd_cancel_transfer(struct usbi_transfer *itransfer)
{
usbi_dbg("");
return (LIBUSB_ERROR_NOT_SUPPORTED);
}
void
obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
{
usbi_dbg("");
/* Nothing to do */
}
int
obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
int num_ready)
{
struct libusb_device_handle *handle;
struct handle_priv *hpriv = NULL;
struct usbi_transfer *itransfer;
struct pollfd *pollfd;
int i, err = 0;
usbi_dbg("");
pthread_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
pollfd = &fds[i];
if (!pollfd->revents)
continue;
hpriv = NULL;
num_ready--;
list_for_each_entry(handle, &ctx->open_devs, list,
struct libusb_device_handle) {
hpriv = (struct handle_priv *)handle->os_priv;
if (hpriv->pipe[0] == pollfd->fd)
break;
hpriv = NULL;
}
if (NULL == hpriv) {
usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
err = ENOENT;
break;
}
if (pollfd->revents & POLLERR) {
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
usbi_handle_disconnect(handle);
continue;
}
if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
err = errno;
break;
}
if ((err = usbi_handle_transfer_completion(itransfer,
LIBUSB_TRANSFER_COMPLETED)))
break;
}
pthread_mutex_unlock(&ctx->open_devs_lock);
if (err)
return _errno_to_libusb(err);
return (LIBUSB_SUCCESS);
}
int
obsd_clock_gettime(int clkid, struct timespec *tp)
{
usbi_dbg("clock %d", clkid);
if (clkid == USBI_CLOCK_REALTIME)
return clock_gettime(CLOCK_REALTIME, tp);
if (clkid == USBI_CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, tp);
return (LIBUSB_ERROR_INVALID_PARAM);
}
int
_errno_to_libusb(int err)
{
switch (err) {
case EIO:
return (LIBUSB_ERROR_IO);
case EACCES:
return (LIBUSB_ERROR_ACCESS);
case ENOENT:
return (LIBUSB_ERROR_NO_DEVICE);
case ENOMEM:
return (LIBUSB_ERROR_NO_MEM);
}
usbi_dbg("error: %s", strerror(err));
return (LIBUSB_ERROR_OTHER);
}
int
_cache_active_config_descriptor(struct libusb_device *dev, int fd)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
struct usb_config_desc ucd;
struct usb_full_desc ufd;
unsigned char* buf;
int len;
usbi_dbg("fd %d", fd);
ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX;
if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0)
return _errno_to_libusb(errno);
usbi_dbg("active bLength %d", ucd.ucd_desc.bLength);
len = UGETW(ucd.ucd_desc.wTotalLength);
buf = malloc(len);
if (buf == NULL)
return (LIBUSB_ERROR_NO_MEM);
ufd.ufd_config_index = ucd.ucd_config_index;
ufd.ufd_size = len;
ufd.ufd_data = buf;
usbi_dbg("index %d, len %d", ufd.ufd_config_index, len);
if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
free(buf);
return _errno_to_libusb(errno);
}
if (dpriv->cdesc)
free(dpriv->cdesc);
dpriv->cdesc = buf;
return (0);
}
int
_sync_control_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct libusb_control_setup *setup;
struct device_priv *dpriv;
struct usb_ctl_request req;
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
setup = (struct libusb_control_setup *)transfer->buffer;
usbi_dbg("type %d request %d value %d index %d length %d timeout %d",
setup->bmRequestType, setup->bRequest,
libusb_le16_to_cpu(setup->wValue),
libusb_le16_to_cpu(setup->wIndex),
libusb_le16_to_cpu(setup->wLength), transfer->timeout);
req.ucr_request.bmRequestType = setup->bmRequestType;
req.ucr_request.bRequest = setup->bRequest;
/* Don't use USETW, libusbx already deals with the endianness */
(*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
(*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
(*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
req.ucr_flags = USBD_SHORT_XFER_OK;
if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
return _errno_to_libusb(errno);
itransfer->transferred = req.ucr_actlen;
usbi_dbg("transferred %d", itransfer->transferred);
return (0);
}
int
_access_endpoint(struct libusb_transfer *transfer)
{
struct handle_priv *hpriv;
struct device_priv *dpriv;
char *s, devnode[16];
int fd, endpt;
mode_t mode;
hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
endpt = UE_GET_ADDR(transfer->endpoint);
mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
usbi_dbg("endpoint %d mode %d", endpt, mode);
if (hpriv->endpoints[endpt] < 0) {
/* Pick the right node given the control one */
strlcpy(devnode, dpriv->devnode, sizeof(devnode));
s = strchr(devnode, '.');
snprintf(s, 4, ".%02d", endpt);
/* We may need to read/write to the same endpoint later. */
if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO))
if ((fd = open(devnode, mode)) < 0)
return (-1);
hpriv->endpoints[endpt] = fd;
}
return (hpriv->endpoints[endpt]);
}
int
_sync_gen_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
int fd, nr = 1;
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
/*
* Bulk, Interrupt or Isochronous transfer depends on the
* endpoint and thus the node to open.
*/
if ((fd = _access_endpoint(transfer)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
return _errno_to_libusb(errno);
if (IS_XFERIN(transfer)) {
if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
return _errno_to_libusb(errno);
nr = read(fd, transfer->buffer, transfer->length);
} else {
nr = write(fd, transfer->buffer, transfer->length);
}
if (nr < 0)
return _errno_to_libusb(errno);
itransfer->transferred = nr;
return (0);
}

View File

@ -0,0 +1,51 @@
/*
* poll_posix: poll compatibility wrapper for POSIX systems
* Copyright © 2013 RealVNC Ltd.
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "libusbi.h"
int usbi_pipe(int pipefd[2])
{
int ret = pipe(pipefd);
if (ret != 0) {
return ret;
}
ret = fcntl(pipefd[1], F_GETFL);
if (ret == -1) {
usbi_dbg("Failed to get pipe fd flags: %d", errno);
goto err_close_pipe;
}
ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK);
if (ret != 0) {
usbi_dbg("Failed to set non-blocking on new pipe: %d", errno);
goto err_close_pipe;
}
return 0;
err_close_pipe:
usbi_close(pipefd[0]);
usbi_close(pipefd[1]);
return ret;
}

View File

@ -0,0 +1,11 @@
#ifndef LIBUSB_POLL_POSIX_H
#define LIBUSB_POLL_POSIX_H
#define usbi_write write
#define usbi_read read
#define usbi_close close
#define usbi_poll poll
int usbi_pipe(int pipefd[2]);
#endif /* LIBUSB_POLL_POSIX_H */

View File

@ -0,0 +1,726 @@
/*
* poll_windows: poll compatibility wrapper for Windows
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* poll() and pipe() Windows compatibility layer for libusbx 1.0
*
* The way this layer works is by using OVERLAPPED with async I/O transfers, as
* OVERLAPPED have an associated event which is flagged for I/O completion.
*
* For USB pollable async I/O, you would typically:
* - obtain a Windows HANDLE to a file or device that has been opened in
* OVERLAPPED mode
* - call usbi_create_fd with this handle to obtain a custom fd.
* Note that if you need simultaneous R/W access, you need to call create_fd
* twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate
* pollable fds
* - leave the core functions call the poll routine and flag POLLIN/POLLOUT
*
* The pipe pollable synchronous I/O works using the overlapped event associated
* with a fake pipe. The read/write functions are only meant to be used in that
* context.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "libusbi.h"
// Uncomment to debug the polling layer
//#define DEBUG_POLL_WINDOWS
#if defined(DEBUG_POLL_WINDOWS)
#define poll_dbg usbi_dbg
#else
// MSVC++ < 2005 cannot use a variadic argument and non MSVC
// compilers produce warnings if parenthesis are ommitted.
#if defined(_MSC_VER) && (_MSC_VER < 1400)
#define poll_dbg
#else
#define poll_dbg(...)
#endif
#endif
#if defined(_PREFAST_)
#pragma warning(disable:28719)
#endif
#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
// public fd data
const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE};
struct winfd poll_fd[MAX_FDS];
// internal fd data
struct {
CRITICAL_SECTION mutex; // lock for fds
// Additional variables for XP CancelIoEx partial emulation
HANDLE original_handle;
DWORD thread_id;
} _poll_fd[MAX_FDS];
// globals
BOOLEAN is_polling_set = FALSE;
LONG pipe_number = 0;
static volatile LONG compat_spinlock = 0;
#if !defined(_WIN32_WCE)
// CancelIoEx, available on Vista and later only, provides the ability to cancel
// a single transfer (OVERLAPPED) when used. As it may not be part of any of the
// platform headers, we hook into the Kernel32 system DLL directly to seek it.
static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
#define Use_Duplicate_Handles (pCancelIoEx == NULL)
static inline void setup_cancel_io(void)
{
HMODULE hKernel32 = GetModuleHandleA("KERNEL32");
if (hKernel32 != NULL) {
pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
GetProcAddress(hKernel32, "CancelIoEx");
}
usbi_dbg("Will use CancelIo%s for I/O cancellation",
Use_Duplicate_Handles?"":"Ex");
}
static inline BOOL cancel_io(int _index)
{
if ((_index < 0) || (_index >= MAX_FDS)) {
return FALSE;
}
if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
return TRUE;
}
if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
// Cancel outstanding transfer via the specific callback
(*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
return TRUE;
}
if (pCancelIoEx != NULL) {
return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
}
if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
return CancelIo(poll_fd[_index].handle);
}
usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
return FALSE;
}
#else
#define Use_Duplicate_Handles FALSE
static __inline void setup_cancel_io()
{
// No setup needed on WinCE
}
static __inline BOOL cancel_io(int _index)
{
if ((_index < 0) || (_index >= MAX_FDS)) {
return FALSE;
}
if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
return TRUE;
}
if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
// Cancel outstanding transfer via the specific callback
(*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
}
return TRUE;
}
#endif
// Init
void init_polling(void)
{
int i;
while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
SleepEx(0, TRUE);
}
if (!is_polling_set) {
setup_cancel_io();
for (i=0; i<MAX_FDS; i++) {
poll_fd[i] = INVALID_WINFD;
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
_poll_fd[i].thread_id = 0;
InitializeCriticalSection(&_poll_fd[i].mutex);
}
is_polling_set = TRUE;
}
InterlockedExchange((LONG *)&compat_spinlock, 0);
}
// Internal function to retrieve the table index (and lock the fd mutex)
static int _fd_to_index_and_lock(int fd)
{
int i;
if (fd < 0)
return -1;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd == fd) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have changed before we got to critical
if (poll_fd[i].fd != fd) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
return i;
}
}
return -1;
}
static OVERLAPPED *create_overlapped(void)
{
OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
if (overlapped == NULL) {
return NULL;
}
overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(overlapped->hEvent == NULL) {
free (overlapped);
return NULL;
}
return overlapped;
}
static void free_overlapped(OVERLAPPED *overlapped)
{
if (overlapped == NULL)
return;
if ( (overlapped->hEvent != 0)
&& (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
CloseHandle(overlapped->hEvent);
}
free(overlapped);
}
void exit_polling(void)
{
int i;
while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
SleepEx(0, TRUE);
}
if (is_polling_set) {
is_polling_set = FALSE;
for (i=0; i<MAX_FDS; i++) {
// Cancel any async I/O (handle can be invalid)
cancel_io(i);
// If anything was pending on that I/O, it should be
// terminating, and we should be able to access the fd
// mutex lock before too long
EnterCriticalSection(&_poll_fd[i].mutex);
free_overlapped(poll_fd[i].overlapped);
if (Use_Duplicate_Handles) {
// Close duplicate handle
if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
CloseHandle(poll_fd[i].handle);
}
}
poll_fd[i] = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[i].mutex);
DeleteCriticalSection(&_poll_fd[i].mutex);
}
}
InterlockedExchange((LONG *)&compat_spinlock, 0);
}
/*
* Create a fake pipe.
* As libusbx only uses pipes for signaling, all we need from a pipe is an
* event. To that extent, we create a single wfd and overlapped as a means
* to access that event.
*/
int usbi_pipe(int filedes[2])
{
int i;
OVERLAPPED* overlapped;
CHECK_INIT_POLLING;
overlapped = create_overlapped();
if (overlapped == NULL) {
return -1;
}
// The overlapped must have status pending for signaling to work in poll
overlapped->Internal = STATUS_PENDING;
overlapped->InternalHigh = 0;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd < 0) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been allocated before we got to critical
if (poll_fd[i].fd >= 0) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
// Use index as the unique fd number
poll_fd[i].fd = i;
// Read end of the "pipe"
filedes[0] = poll_fd[i].fd;
// We can use the same handle for both ends
filedes[1] = filedes[0];
poll_fd[i].handle = DUMMY_HANDLE;
poll_fd[i].overlapped = overlapped;
// There's no polling on the write end, so we just use READ for our needs
poll_fd[i].rw = RW_READ;
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
LeaveCriticalSection(&_poll_fd[i].mutex);
return 0;
}
}
free_overlapped(overlapped);
return -1;
}
/*
* Create both an fd and an OVERLAPPED from an open Windows handle, so that
* it can be used with our polling function
* The handle MUST support overlapped transfers (usually requires CreateFile
* with FILE_FLAG_OVERLAPPED)
* Return a pollable file descriptor struct, or INVALID_WINFD on error
*
* Note that the fd returned by this function is a per-transfer fd, rather
* than a per-session fd and cannot be used for anything else but our
* custom functions (the fd itself points to the NUL: device)
* if you plan to do R/W on the same handle, you MUST create 2 fds: one for
* read and one for write. Using a single R/W fd is unsupported and will
* produce unexpected results
*/
struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
{
int i;
struct winfd wfd = INVALID_WINFD;
OVERLAPPED* overlapped = NULL;
CHECK_INIT_POLLING;
if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
return INVALID_WINFD;
}
wfd.itransfer = itransfer;
wfd.cancel_fn = cancel_fn;
if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
"If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
return INVALID_WINFD;
}
if (access_mode == RW_READ) {
wfd.rw = RW_READ;
} else {
wfd.rw = RW_WRITE;
}
overlapped = create_overlapped();
if(overlapped == NULL) {
return INVALID_WINFD;
}
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd < 0) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been removed before we got to critical
if (poll_fd[i].fd >= 0) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
// Use index as the unique fd number
wfd.fd = i;
// Attempt to emulate some of the CancelIoEx behaviour on platforms
// that don't have it
if (Use_Duplicate_Handles) {
_poll_fd[i].thread_id = GetCurrentThreadId();
if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
&wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
usbi_dbg("could not duplicate handle for CancelIo - using original one");
wfd.handle = handle;
// Make sure we won't close the original handle on fd deletion then
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
} else {
_poll_fd[i].original_handle = handle;
}
} else {
wfd.handle = handle;
}
wfd.overlapped = overlapped;
memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
free_overlapped(overlapped);
return INVALID_WINFD;
}
static void _free_index(int _index)
{
// Cancel any async IO (Don't care about the validity of our handles for this)
cancel_io(_index);
// close the duplicate handle (if we have an actual duplicate)
if (Use_Duplicate_Handles) {
if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
CloseHandle(poll_fd[_index].handle);
}
_poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
_poll_fd[_index].thread_id = 0;
}
free_overlapped(poll_fd[_index].overlapped);
poll_fd[_index] = INVALID_WINFD;
}
/*
* Release a pollable file descriptor.
*
* Note that the associated Windows handle is not closed by this call
*/
void usbi_free_fd(struct winfd *wfd)
{
int _index;
CHECK_INIT_POLLING;
_index = _fd_to_index_and_lock(wfd->fd);
if (_index < 0) {
return;
}
_free_index(_index);
*wfd = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
/*
* The functions below perform various conversions between fd, handle and OVERLAPPED
*/
struct winfd fd_to_winfd(int fd)
{
int i;
struct winfd wfd;
CHECK_INIT_POLLING;
if (fd <= 0)
return INVALID_WINFD;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd == fd) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been deleted before we got to critical
if (poll_fd[i].fd != fd) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
return INVALID_WINFD;
}
struct winfd handle_to_winfd(HANDLE handle)
{
int i;
struct winfd wfd;
CHECK_INIT_POLLING;
if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
return INVALID_WINFD;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].handle == handle) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been deleted before we got to critical
if (poll_fd[i].handle != handle) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
return INVALID_WINFD;
}
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
{
int i;
struct winfd wfd;
CHECK_INIT_POLLING;
if (overlapped == NULL)
return INVALID_WINFD;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].overlapped == overlapped) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been deleted before we got to critical
if (poll_fd[i].overlapped != overlapped) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
return INVALID_WINFD;
}
/*
* POSIX poll equivalent, using Windows OVERLAPPED
* Currently, this function only accepts one of POLLIN or POLLOUT per fd
* (but you can create multiple fds from the same handle for read and write)
*/
int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
unsigned i;
int _index, object_index, triggered;
HANDLE *handles_to_wait_on;
int *handle_to_index;
DWORD nb_handles_to_wait_on = 0;
DWORD ret;
CHECK_INIT_POLLING;
triggered = 0;
handles_to_wait_on = (HANDLE*) calloc(nfds+1, sizeof(HANDLE)); // +1 for fd_update
handle_to_index = (int*) calloc(nfds, sizeof(int));
if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
errno = ENOMEM;
triggered = -1;
goto poll_exit;
}
for (i = 0; i < nfds; ++i) {
fds[i].revents = 0;
// Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
fds[i].revents |= POLLERR;
errno = EACCES;
usbi_warn(NULL, "unsupported set of events");
triggered = -1;
goto poll_exit;
}
_index = _fd_to_index_and_lock(fds[i].fd);
poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
if (_index >= 0) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
usbi_warn(NULL, "invalid fd");
triggered = -1;
goto poll_exit;
}
// IN or OUT must match our fd direction
if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
usbi_warn(NULL, "attempted POLLIN on fd without READ access");
LeaveCriticalSection(&_poll_fd[_index].mutex);
triggered = -1;
goto poll_exit;
}
if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
LeaveCriticalSection(&_poll_fd[_index].mutex);
triggered = -1;
goto poll_exit;
}
// The following macro only works if overlapped I/O was reported pending
if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
|| (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
poll_dbg(" completed");
// checks above should ensure this works:
fds[i].revents = fds[i].events;
triggered++;
} else {
handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
handle_to_index[nb_handles_to_wait_on] = i;
nb_handles_to_wait_on++;
}
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
// If nothing was triggered, wait on all fds that require it
if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
if (timeout < 0) {
poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
} else {
poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
}
ret = WaitForMultipleObjects(nb_handles_to_wait_on, handles_to_wait_on,
FALSE, (timeout<0)?INFINITE:(DWORD)timeout);
object_index = ret-WAIT_OBJECT_0;
if ((object_index >= 0) && ((DWORD)object_index < nb_handles_to_wait_on)) {
poll_dbg(" completed after wait");
i = handle_to_index[object_index];
_index = _fd_to_index_and_lock(fds[i].fd);
fds[i].revents = fds[i].events;
triggered++;
if (_index >= 0) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
} else if (ret == WAIT_TIMEOUT) {
poll_dbg(" timed out");
triggered = 0; // 0 = timeout
} else {
errno = EIO;
triggered = -1; // error
}
}
poll_exit:
if (handles_to_wait_on != NULL) {
free(handles_to_wait_on);
}
if (handle_to_index != NULL) {
free(handle_to_index);
}
return triggered;
}
/*
* close a fake pipe fd
*/
int usbi_close(int fd)
{
int _index;
int r = -1;
CHECK_INIT_POLLING;
_index = _fd_to_index_and_lock(fd);
if (_index < 0) {
errno = EBADF;
} else {
free_overlapped(poll_fd[_index].overlapped);
poll_fd[_index] = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
return r;
}
/*
* synchronous write for fake "pipe" signaling
*/
ssize_t usbi_write(int fd, const void *buf, size_t count)
{
int _index;
UNUSED(buf);
CHECK_INIT_POLLING;
if (count != sizeof(unsigned char)) {
usbi_err(NULL, "this function should only used for signaling");
return -1;
}
_index = _fd_to_index_and_lock(fd);
if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
errno = EBADF;
if (_index >= 0) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
return -1;
}
poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
SetEvent(poll_fd[_index].overlapped->hEvent);
poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
// If two threads write on the pipe at the same time, we need to
// process two separate reads => use the overlapped as a counter
poll_fd[_index].overlapped->InternalHigh++;
LeaveCriticalSection(&_poll_fd[_index].mutex);
return sizeof(unsigned char);
}
/*
* synchronous read for fake "pipe" signaling
*/
ssize_t usbi_read(int fd, void *buf, size_t count)
{
int _index;
ssize_t r = -1;
UNUSED(buf);
CHECK_INIT_POLLING;
if (count != sizeof(unsigned char)) {
usbi_err(NULL, "this function should only used for signaling");
return -1;
}
_index = _fd_to_index_and_lock(fd);
if (_index < 0) {
errno = EBADF;
return -1;
}
if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
errno = EIO;
goto out;
}
poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
poll_fd[_index].overlapped->InternalHigh--;
// Don't reset unless we don't have any more events to process
if (poll_fd[_index].overlapped->InternalHigh <= 0) {
ResetEvent(poll_fd[_index].overlapped->hEvent);
poll_fd[_index].overlapped->Internal = STATUS_PENDING;
}
r = sizeof(unsigned char);
out:
LeaveCriticalSection(&_poll_fd[_index].mutex);
return r;
}

View File

@ -0,0 +1,125 @@
/*
* Windows compat: POSIX compatibility wrapper
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#pragma once
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4127) // conditional expression is constant
#endif
// Handle synchronous completion through the overlapped structure
#if !defined(STATUS_REPARSE) // reuse the REPARSE status code
#define STATUS_REPARSE ((LONG)0x00000104L)
#endif
#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE
#if defined(_WIN32_WCE)
// WinCE doesn't have a HasOverlappedIoCompleted() macro, so attempt to emulate it
#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) != STATUS_PENDING)
#endif
#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY)
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
enum windows_version {
WINDOWS_UNSUPPORTED,
WINDOWS_CE,
WINDOWS_XP,
WINDOWS_2003, // also includes XP 64
WINDOWS_VISTA_AND_LATER,
};
extern enum windows_version windows_version;
#define MAX_FDS 256
#define POLLIN 0x0001 /* There is data to read */
#define POLLPRI 0x0002 /* There is urgent data to read */
#define POLLOUT 0x0004 /* Writing now will not block */
#define POLLERR 0x0008 /* Error condition */
#define POLLHUP 0x0010 /* Hung up */
#define POLLNVAL 0x0020 /* Invalid request: fd not open */
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
// access modes
enum rw_type {
RW_NONE,
RW_READ,
RW_WRITE,
};
// fd struct that can be used for polling on Windows
typedef int cancel_transfer(struct usbi_transfer *itransfer);
struct winfd {
int fd; // what's exposed to libusb core
HANDLE handle; // what we need to attach overlapped to the I/O op, so we can poll it
OVERLAPPED* overlapped; // what will report our I/O status
struct usbi_transfer *itransfer; // Associated transfer, or NULL if completed
cancel_transfer *cancel_fn; // Function pointer to cancel transfer API
enum rw_type rw; // I/O transfer direction: read *XOR* write (NOT BOTH)
};
extern const struct winfd INVALID_WINFD;
int usbi_pipe(int pipefd[2]);
int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout);
ssize_t usbi_write(int fd, const void *buf, size_t count);
ssize_t usbi_read(int fd, void *buf, size_t count);
int usbi_close(int fd);
void init_polling(void);
void exit_polling(void);
struct winfd usbi_create_fd(HANDLE handle, int access_mode,
struct usbi_transfer *transfer, cancel_transfer *cancel_fn);
void usbi_free_fd(struct winfd* winfd);
struct winfd fd_to_winfd(int fd);
struct winfd handle_to_winfd(HANDLE handle);
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped);
/*
* Timeval operations
*/
#if defined(DDKBUILD)
#include <winsock.h> // defines timeval functions on DDK
#endif
#if !defined(TIMESPEC_TO_TIMEVAL)
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (long)(ts)->tv_sec; \
(tv)->tv_usec = (long)(ts)->tv_nsec / 1000; \
}
#endif
#if !defined(timersub)
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif

View File

@ -0,0 +1,80 @@
/*
* libusbx synchronization using POSIX Threads
*
* Copyright © 2011 Vitali Lovich <vlovich@aliph.com>
* Copyright © 2011 Peter Stuge <peter@stuge.se>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(__linux__) || defined(__OpenBSD__)
# if defined(__linux__)
# define _GNU_SOURCE
# else
# define _BSD_SOURCE
# endif
# include <unistd.h>
# include <sys/syscall.h>
#elif defined(__APPLE__)
# include <mach/mach.h>
#elif defined(__CYGWIN__)
# include <windows.h>
#endif
#include "threads_posix.h"
int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
{
int err;
pthread_mutexattr_t stack_attr;
if (!attr) {
attr = &stack_attr;
err = pthread_mutexattr_init(&stack_attr);
if (err != 0)
return err;
}
/* mutexattr_settype requires _GNU_SOURCE or _XOPEN_SOURCE >= 500 on Linux */
err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
if (err != 0)
goto finish;
err = pthread_mutex_init(mutex, attr);
finish:
if (attr == &stack_attr)
pthread_mutexattr_destroy(&stack_attr);
return err;
}
int usbi_get_tid(void)
{
int ret = -1;
#if defined(__linux__)
ret = syscall(SYS_gettid);
#elif defined(__OpenBSD__)
/* The following only works with OpenBSD > 5.1 as it requires
real thread support. For 5.1 and earlier, -1 is returned. */
ret = syscall(SYS_getthrid);
#elif defined(__APPLE__)
ret = mach_thread_self();
mach_port_deallocate(mach_task_self(), ret);
#elif defined(__CYGWIN__)
ret = GetCurrentThreadId();
#endif
/* TODO: NetBSD thread ID support */
return ret;
}

View File

@ -0,0 +1,50 @@
/*
* libusbx synchronization using POSIX Threads
*
* Copyright © 2010 Peter Stuge <peter@stuge.se>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_THREADS_POSIX_H
#define LIBUSB_THREADS_POSIX_H
#include <pthread.h>
#define usbi_mutex_static_t pthread_mutex_t
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define usbi_mutex_static_lock pthread_mutex_lock
#define usbi_mutex_static_unlock pthread_mutex_unlock
#define usbi_mutex_t pthread_mutex_t
#define usbi_mutex_init pthread_mutex_init
#define usbi_mutex_lock pthread_mutex_lock
#define usbi_mutex_unlock pthread_mutex_unlock
#define usbi_mutex_trylock pthread_mutex_trylock
#define usbi_mutex_destroy pthread_mutex_destroy
#define usbi_cond_t pthread_cond_t
#define usbi_cond_init pthread_cond_init
#define usbi_cond_wait pthread_cond_wait
#define usbi_cond_timedwait pthread_cond_timedwait
#define usbi_cond_broadcast pthread_cond_broadcast
#define usbi_cond_destroy pthread_cond_destroy
#define usbi_cond_signal pthread_cond_signal
extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
int usbi_get_tid(void);
#endif /* LIBUSB_THREADS_POSIX_H */

View File

@ -0,0 +1,212 @@
/*
* libusbx synchronization on Microsoft Windows
*
* Copyright © 2010 Michael Plante <michael.plante@gmail.com>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
#include <objbase.h>
#include <errno.h>
#include <stdarg.h>
#include "libusbi.h"
extern const uint64_t epoch_time;
int usbi_mutex_init(usbi_mutex_t *mutex,
const usbi_mutexattr_t *attr) {
UNUSED(attr);
if(! mutex) return ((errno=EINVAL));
*mutex = CreateMutex(NULL, FALSE, NULL);
if(!*mutex) return ((errno=ENOMEM));
return 0;
}
int usbi_mutex_destroy(usbi_mutex_t *mutex) {
// It is not clear if CloseHandle failure is due to failure to unlock.
// If so, this should be errno=EBUSY.
if(!mutex || !CloseHandle(*mutex)) return ((errno=EINVAL));
*mutex = NULL;
return 0;
}
int usbi_mutex_trylock(usbi_mutex_t *mutex) {
DWORD result;
if(!mutex) return ((errno=EINVAL));
result = WaitForSingleObject(*mutex, 0);
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
return 0; // acquired (ToDo: check that abandoned is ok)
if(result == WAIT_TIMEOUT)
return ((errno=EBUSY));
return ((errno=EINVAL)); // don't know how this would happen
// so don't know proper errno
}
int usbi_mutex_lock(usbi_mutex_t *mutex) {
DWORD result;
if(!mutex) return ((errno=EINVAL));
result = WaitForSingleObject(*mutex, INFINITE);
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
return 0; // acquired (ToDo: check that abandoned is ok)
return ((errno=EINVAL)); // don't know how this would happen
// so don't know proper errno
}
int usbi_mutex_unlock(usbi_mutex_t *mutex) {
if(!mutex) return ((errno=EINVAL));
if(!ReleaseMutex(*mutex)) return ((errno=EPERM ));
return 0;
}
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex) {
if(!mutex) return ((errno=EINVAL));
while (InterlockedExchange((LONG *)mutex, 1) == 1) {
SleepEx(0, TRUE);
}
return 0;
}
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) {
if(!mutex) return ((errno=EINVAL));
*mutex = 0;
return 0;
}
int usbi_cond_init(usbi_cond_t *cond,
const usbi_condattr_t *attr) {
UNUSED(attr);
if(!cond) return ((errno=EINVAL));
list_init(&cond->waiters );
list_init(&cond->not_waiting);
return 0;
}
int usbi_cond_destroy(usbi_cond_t *cond) {
// This assumes no one is using this anymore. The check MAY NOT BE safe.
struct usbi_cond_perthread *pos, *next_pos = NULL;
if(!cond) return ((errno=EINVAL));
if(!list_empty(&cond->waiters)) return ((errno=EBUSY )); // (!see above!)
list_for_each_entry_safe(pos, next_pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
CloseHandle(pos->event);
list_del(&pos->list);
free(pos);
}
return 0;
}
int usbi_cond_broadcast(usbi_cond_t *cond) {
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
// libusb does this anyway, so we simplify by not adding more sync
// primitives to the CV definition!
int fail = 0;
struct usbi_cond_perthread *pos;
if(!cond) return ((errno=EINVAL));
list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) {
if(!SetEvent(pos->event))
fail = 1;
}
// The wait function will remove its respective item from the list.
return fail ? ((errno=EINVAL)) : 0;
}
int usbi_cond_signal(usbi_cond_t *cond) {
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
// libusb does this anyway, so we simplify by not adding more sync
// primitives to the CV definition!
struct usbi_cond_perthread *pos;
if(!cond) return ((errno=EINVAL));
if(list_empty(&cond->waiters)) return 0; // no one to wakeup.
pos = list_entry(&cond->waiters.next, struct usbi_cond_perthread, list);
// The wait function will remove its respective item from the list.
return SetEvent(pos->event) ? 0 : ((errno=EINVAL));
}
__inline static int usbi_cond_intwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
DWORD timeout_ms) {
struct usbi_cond_perthread *pos;
int found = 0, r;
DWORD r2,tid = GetCurrentThreadId();
if(!cond || !mutex) return ((errno=EINVAL));
list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
if(tid == pos->tid) {
found = 1;
break;
}
}
if(!found) {
pos = (struct usbi_cond_perthread*) calloc(1, sizeof(struct usbi_cond_perthread));
if(!pos) return ((errno=ENOMEM)); // This errno is not POSIX-allowed.
pos->tid = tid;
pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
if(!pos->event) {
free(pos);
return ((errno=ENOMEM));
}
list_add(&pos->list, &cond->not_waiting);
}
list_del(&pos->list); // remove from not_waiting list.
list_add(&pos->list, &cond->waiters);
r = usbi_mutex_unlock(mutex);
if(r) return r;
r2 = WaitForSingleObject(pos->event, timeout_ms);
r = usbi_mutex_lock(mutex);
if(r) return r;
list_del(&pos->list);
list_add(&pos->list, &cond->not_waiting);
if(r2 == WAIT_TIMEOUT) return ((errno=ETIMEDOUT));
return 0;
}
// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot!
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) {
return usbi_cond_intwait(cond, mutex, INFINITE);
}
int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
const struct timespec *abstime) {
FILETIME filetime;
ULARGE_INTEGER rtime;
struct timeval targ_time, cur_time, delta_time;
struct timespec cur_time_ns;
DWORD millis;
// GetSystemTimeAsFileTime() is not available on CE
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &filetime);
rtime.LowPart = filetime.dwLowDateTime;
rtime.HighPart = filetime.dwHighDateTime;
rtime.QuadPart -= epoch_time;
cur_time_ns.tv_sec = (long)(rtime.QuadPart / 10000000);
cur_time_ns.tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
TIMESPEC_TO_TIMEVAL(&cur_time, &cur_time_ns);
TIMESPEC_TO_TIMEVAL(&targ_time, abstime);
timersub(&targ_time, &cur_time, &delta_time);
if(delta_time.tv_sec < 0) // abstime already passed?
millis = 0;
else {
millis = delta_time.tv_usec/1000;
millis += delta_time.tv_sec *1000;
if (delta_time.tv_usec % 1000) // round up to next millisecond
millis++;
}
return usbi_cond_intwait(cond, mutex, millis);
}
int usbi_get_tid(void) {
return GetCurrentThreadId();
}

View File

@ -0,0 +1,87 @@
/*
* libusbx synchronization on Microsoft Windows
*
* Copyright © 2010 Michael Plante <michael.plante@gmail.com>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_THREADS_WINDOWS_H
#define LIBUSB_THREADS_WINDOWS_H
#define usbi_mutex_static_t volatile LONG
#define USBI_MUTEX_INITIALIZER 0
#define usbi_mutex_t HANDLE
struct usbi_cond_perthread {
struct list_head list;
DWORD tid;
HANDLE event;
};
struct usbi_cond_t_ {
// Every time a thread touches the CV, it winds up in one of these lists.
// It stays there until the CV is destroyed, even if the thread
// terminates.
struct list_head waiters;
struct list_head not_waiting;
};
typedef struct usbi_cond_t_ usbi_cond_t;
// We *were* getting timespec from pthread.h:
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
#define HAVE_STRUCT_TIMESPEC 1
#define _TIMESPEC_DEFINED 1
struct timespec {
long tv_sec;
long tv_nsec;
};
#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
// We *were* getting ETIMEDOUT from pthread.h:
#ifndef ETIMEDOUT
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
#define usbi_mutexattr_t void
#define usbi_condattr_t void
// all Windows mutexes are recursive
#define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr))
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
int usbi_mutex_init(usbi_mutex_t *mutex,
const usbi_mutexattr_t *attr);
int usbi_mutex_lock(usbi_mutex_t *mutex);
int usbi_mutex_unlock(usbi_mutex_t *mutex);
int usbi_mutex_trylock(usbi_mutex_t *mutex);
int usbi_mutex_destroy(usbi_mutex_t *mutex);
int usbi_cond_init(usbi_cond_t *cond,
const usbi_condattr_t *attr);
int usbi_cond_destroy(usbi_cond_t *cond);
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
const struct timespec *abstime);
int usbi_cond_broadcast(usbi_cond_t *cond);
int usbi_cond_signal(usbi_cond_t *cond);
int usbi_get_tid(void);
#endif /* LIBUSB_THREADS_WINDOWS_H */

1015
Externals/libusbx/libusb/os/wince_usb.c vendored Normal file

File diff suppressed because it is too large Load Diff

131
Externals/libusbx/libusb/os/wince_usb.h vendored Normal file
View File

@ -0,0 +1,131 @@
/*
* Windows CE backend for libusbx 1.0
* Copyright © 2011-2013 RealVNC Ltd.
* Portions taken from Windows backend, which is
* Copyright © 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
* Major code testing contribution by Xiaofan Chen
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "windows_common.h"
#include <windows.h>
#include "poll_windows.h"
#define MAX_DEVICE_COUNT 256
// This is a modified dump of the types in the ceusbkwrapper.h library header
// with functions transformed into extern pointers.
//
// This backend dynamically loads ceusbkwrapper.dll and doesn't include
// ceusbkwrapper.h directly to simplify the build process. The kernel
// side wrapper driver is built using the platform image build tools,
// which makes it difficult to reference directly from the libusbx build
// system.
struct UKW_DEVICE_PRIV;
typedef struct UKW_DEVICE_PRIV *UKW_DEVICE;
typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE;
typedef struct {
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 bcdUSB;
UINT8 bDeviceClass;
UINT8 bDeviceSubClass;
UINT8 bDeviceProtocol;
UINT8 bMaxPacketSize0;
UINT16 idVendor;
UINT16 idProduct;
UINT16 bcdDevice;
UINT8 iManufacturer;
UINT8 iProduct;
UINT8 iSerialNumber;
UINT8 bNumConfigurations;
} UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR;
typedef struct {
UINT8 bmRequestType;
UINT8 bRequest;
UINT16 wValue;
UINT16 wIndex;
UINT16 wLength;
} UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER;
// Collection of flags which can be used when issuing transfer requests
/* Indicates that the transfer direction is 'in' */
#define UKW_TF_IN_TRANSFER 0x00000001
/* Indicates that the transfer direction is 'out' */
#define UKW_TF_OUT_TRANSFER 0x00000000
/* Specifies that the transfer should complete as soon as possible,
* even if no OVERLAPPED structure has been provided. */
#define UKW_TF_NO_WAIT 0x00000100
/* Indicates that transfers shorter than the buffer are ok */
#define UKW_TF_SHORT_TRANSFER_OK 0x00000200
#define UKW_TF_SEND_TO_DEVICE 0x00010000
#define UKW_TF_SEND_TO_INTERFACE 0x00020000
#define UKW_TF_SEND_TO_ENDPOINT 0x00040000
/* Don't block when waiting for memory allocations */
#define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000
/* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor,
* to specify the currently active configuration for the device. */
#define UKW_ACTIVE_CONFIGURATION -1
DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ());
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
// Used to determine if an endpoint status really is halted on a failed transfer.
#define STATUS_HALT_FLAG 0x1
struct wince_device_priv {
UKW_DEVICE dev;
UKW_DEVICE_DESCRIPTOR desc;
};
struct wince_device_handle_priv {
// This member isn't used, but only exists to avoid an empty structure
// for private data for the device handle.
int reserved;
};
struct wince_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
};

View File

@ -0,0 +1,108 @@
/*
* Windows backend common header for libusbx 1.0
*
* This file brings together header code common between
* the desktop Windows and Windows CE backends.
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
// Windows API default is uppercase - ugh!
#if !defined(bool)
#define bool BOOL
#endif
#if !defined(true)
#define true TRUE
#endif
#if !defined(false)
#define false FALSE
#endif
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
#define safe_strlen(str) ((str==NULL)?0:strlen(str))
#define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
#define safe_stprintf _sntprintf
#define safe_tcslen(str) ((str==NULL)?0:_tcslen(str))
#define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
#define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
#define ERR_BUFFER_SIZE 256
#define TIMER_REQUEST_RETRY_MS 100
#define MAX_TIMER_SEMAPHORES 128
/*
* API macros - from libusb-win32 1.x
*/
#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_t)args; \
static __dll_##name##_t prefixname = NULL
#ifndef _WIN32_WCE
#define DLL_STRINGIFY(dll) #dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
#else
#define DLL_STRINGIFY(dll) L#dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
#endif
#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
if (!h) \
h = DLL_LOAD_LIBRARY(dll); \
if (!h) { \
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
else { break; } \
} \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) break; \
if(ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
} while(0)
#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)

4393
Externals/libusbx/libusb/os/windows_usb.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,918 @@
/*
* Windows backend for libusbx 1.0
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "windows_common.h"
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4214) // bit field types other than int
#pragma warning(disable:4201) // nameless struct/union
#endif
// Missing from MSVC6 setupapi.h
#if !defined(SPDRP_ADDRESS)
#define SPDRP_ADDRESS 28
#endif
#if !defined(SPDRP_INSTALL_STATE)
#define SPDRP_INSTALL_STATE 34
#endif
#if defined(__CYGWIN__ )
#define _stricmp stricmp
// cygwin produces a warning unless these prototypes are defined
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
extern char *_strdup(const char *strSource);
// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f)
#endif
#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
#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
#if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER)
const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_DEVICE)
const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_HUB)
const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
#endif
#if !defined(GUID_DEVINTERFACE_LIBUSB0_FILTER)
const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} };
#endif
/*
* Multiple USB API backend support
*/
#define USB_API_UNSUPPORTED 0
#define USB_API_HUB 1
#define USB_API_COMPOSITE 2
#define USB_API_WINUSBX 3
#define USB_API_HID 4
#define USB_API_MAX 5
// The following is used to indicate if the HID or composite extra props have already been set.
#define USB_API_SET (1<<USB_API_MAX)
// Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL)
// Must have the same values as the KUSB_DRVID enum from libusbk.h
#define SUB_API_NOTSET -1
#define SUB_API_LIBUSBK 0
#define SUB_API_LIBUSB0 1
#define SUB_API_WINUSB 2
#define SUB_API_MAX 3
#define WINUSBX_DRV_NAMES { "libusbK", "libusb0", "WinUSB"}
struct windows_usb_api_backend {
const uint8_t id;
const char* designation;
const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp"
const uint8_t nb_driver_names;
int (*init)(int sub_api, struct libusb_context *ctx);
int (*exit)(int sub_api);
int (*open)(int sub_api, struct libusb_device_handle *dev_handle);
void (*close)(int sub_api, struct libusb_device_handle *dev_handle);
int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle);
int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*abort_control)(int sub_api, struct usbi_transfer *itransfer);
int (*abort_transfers)(int sub_api, struct usbi_transfer *itransfer);
int (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
};
extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
#define PRINT_UNSUPPORTED_API(fname) \
usbi_dbg("unsupported API call for '" \
#fname "' (unrecognized device driver)"); \
return LIBUSB_ERROR_NOT_SUPPORTED;
/*
* 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
uint8_t port; // port number on the hub
uint8_t active_config;
struct libusb_device *parent_dev; // access to parent is required for usermode ops
struct windows_usb_api_backend const *apib;
char *path; // device interface path
int sub_api; // for WinUSB-like APIs
struct {
char *path; // each interface needs a device interface path,
struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support),
int sub_api;
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];
struct hid_device_priv *hid;
USB_DEVICE_DESCRIPTOR dev_descriptor;
unsigned char **config_descriptor; // list of pointers to the cached config descriptors
};
static inline struct windows_device_priv *_device_priv(struct libusb_device *dev) {
return (struct windows_device_priv *)dev->os_priv;
}
static inline void windows_device_priv_init(libusb_device* dev) {
struct windows_device_priv* p = _device_priv(dev);
int i;
p->depth = 0;
p->port = 0;
p->parent_dev = NULL;
p->path = NULL;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->sub_api = SUB_API_NOTSET;
p->hid = NULL;
p->active_config = 0;
p->config_descriptor = NULL;
memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR));
for (i=0; i<USB_MAXINTERFACES; i++) {
p->usb_interface[i].path = NULL;
p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->usb_interface[i].sub_api = SUB_API_NOTSET;
p->usb_interface[i].nb_endpoints = 0;
p->usb_interface[i].endpoint = NULL;
p->usb_interface[i].restricted_functionality = false;
}
}
static inline void windows_device_priv_release(libusb_device* dev) {
struct windows_device_priv* p = _device_priv(dev);
int i;
safe_free(p->path);
if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) {
for (i=0; i < dev->num_configurations; i++)
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);
}
}
struct interface_handle_t {
HANDLE dev_handle; // WinUSB needs an extra handle for the file
HANDLE api_handle; // used by the API to communicate with the device
};
struct windows_device_handle_priv {
int active_interface;
struct interface_handle_t interface_handle[USB_MAXINTERFACES];
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
};
static inline struct windows_device_handle_priv *_device_handle_priv(
struct libusb_device_handle *handle)
{
return (struct windows_device_handle_priv *) handle->os_priv;
}
// used for async polling functions
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
struct driver_lookup {
char list[MAX_KEY_LENGTH+1];// REG_MULTI_SZ list of services (driver) names
const DWORD reg_prop; // SPDRP registry key to use to retreive list
const char* designation; // internal designation (for debug output)
};
/* OLE32 dependency */
DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
/* SetupAPI dependencies */
DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
/*
* Windows DDK API definitions. Most of it copied from MinGW's includes
*/
typedef DWORD DEVNODE, DEVINST;
typedef DEVNODE *PDEVNODE, *PDEVINST;
typedef DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
#define CR_SUCCESS 0x00000000
#define CR_NO_SUCH_DEVNODE 0x0000000D
#define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE
#define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG
#define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING
#define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE
#define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT
#define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS
#define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE
#define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE
#define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS
#define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR
#define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR
#define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION
#define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION
#define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE
#define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE
#define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME
#define USB_GET_NODE_INFORMATION 258
#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
#define USB_GET_NODE_CONNECTION_NAME 261
#define USB_GET_HUB_CAPABILITIES 271
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
#endif
#if !defined(USB_GET_HUB_CAPABILITIES_EX)
#define USB_GET_HUB_CAPABILITIES_EX 276
#endif
#ifndef METHOD_BUFFERED
#define METHOD_BUFFERED 0
#endif
#ifndef FILE_ANY_ACCESS
#define FILE_ANY_ACCESS 0x00000000
#endif
#ifndef FILE_DEVICE_UNKNOWN
#define FILE_DEVICE_UNKNOWN 0x00000022
#endif
#ifndef FILE_DEVICE_USB
#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
#endif
#ifndef CTL_CODE
#define CTL_CODE(DeviceType, Function, Method, Access)( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#endif
typedef enum USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
typedef enum USB_HUB_NODE {
UsbHub,
UsbMIParent
} USB_HUB_NODE;
/* Cfgmgr32.dll interface */
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \
CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_HUB_CAPABILITIES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_ROOT_HUB_NAME \
CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_INFORMATION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_NAME \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Most of the structures below need to be packed
#pragma pack(push, 1)
typedef struct USB_INTERFACE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bInterfaceNumber;
UCHAR bAlternateSetting;
UCHAR bNumEndpoints;
UCHAR bInterfaceClass;
UCHAR bInterfaceSubClass;
UCHAR bInterfaceProtocol;
UCHAR iInterface;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT {
struct {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
} req;
USB_CONFIGURATION_DESCRIPTOR data;
} USB_CONFIGURATION_DESCRIPTOR_SHORT;
typedef struct USB_ENDPOINT_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bEndpointAddress;
UCHAR bmAttributes;
USHORT wMaxPacketSize;
UCHAR bInterval;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
typedef struct USB_DESCRIPTOR_REQUEST {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
// UCHAR Data[0];
} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
typedef struct USB_HUB_DESCRIPTOR {
UCHAR bDescriptorLength;
UCHAR bDescriptorType;
UCHAR bNumberOfPorts;
USHORT wHubCharacteristics;
UCHAR bPowerOnToPowerGood;
UCHAR bHubControlCurrent;
UCHAR bRemoveAndPowerMask[64];
} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
typedef struct USB_ROOT_HUB_NAME {
ULONG ActualLength;
WCHAR RootHubName[1];
} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;
typedef struct USB_ROOT_HUB_NAME_FIXED {
ULONG ActualLength;
WCHAR RootHubName[MAX_PATH_LENGTH];
} USB_ROOT_HUB_NAME_FIXED;
typedef struct USB_NODE_CONNECTION_NAME {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[1];
} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME;
typedef struct USB_NODE_CONNECTION_NAME_FIXED {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[MAX_PATH_LENGTH];
} USB_NODE_CONNECTION_NAME_FIXED;
typedef struct USB_HUB_NAME_FIXED {
union {
USB_ROOT_HUB_NAME_FIXED root;
USB_NODE_CONNECTION_NAME_FIXED node;
} u;
} USB_HUB_NAME_FIXED;
typedef struct USB_HUB_INFORMATION {
USB_HUB_DESCRIPTOR HubDescriptor;
BOOLEAN HubIsBusPowered;
} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
typedef struct USB_MI_PARENT_INFORMATION {
ULONG NumberOfInterfaces;
} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION;
typedef struct USB_NODE_INFORMATION {
USB_HUB_NODE NodeType;
union {
USB_HUB_INFORMATION HubInformation;
USB_MI_PARENT_INFORMATION MiParentInformation;
} u;
} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
typedef struct USB_PIPE_INFO {
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
ULONG ScheduleOffset;
} USB_PIPE_INFO, *PUSB_PIPE_INFO;
typedef struct USB_NODE_CONNECTION_INFORMATION_EX {
ULONG ConnectionIndex;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
UCHAR CurrentConfigurationValue;
UCHAR Speed;
BOOLEAN DeviceIsHub;
USHORT DeviceAddress;
ULONG NumberOfOpenPipes;
USB_CONNECTION_STATUS ConnectionStatus;
// USB_PIPE_INFO PipeList[0];
} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
typedef struct USB_HUB_CAP_FLAGS {
ULONG HubIsHighSpeedCapable:1;
ULONG HubIsHighSpeed:1;
ULONG HubIsMultiTtCapable:1;
ULONG HubIsMultiTt:1;
ULONG HubIsRoot:1;
ULONG HubIsArmedWakeOnConnect:1;
ULONG ReservedMBZ:26;
} USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS;
typedef struct USB_HUB_CAPABILITIES {
ULONG HubIs2xCapable : 1;
} USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES;
typedef struct USB_HUB_CAPABILITIES_EX {
USB_HUB_CAP_FLAGS CapabilityFlags;
} USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX;
#pragma pack(pop)
/* winusb.dll interface */
#define SHORT_PACKET_TERMINATE 0x01
#define AUTO_CLEAR_STALL 0x02
#define PIPE_TRANSFER_TIMEOUT 0x03
#define IGNORE_SHORT_PACKETS 0x04
#define ALLOW_PARTIAL_READS 0x05
#define AUTO_FLUSH 0x06
#define RAW_IO 0x07
#define MAXIMUM_TRANSFER_SIZE 0x08
#define AUTO_SUSPEND 0x81
#define SUSPEND_DELAY 0x83
#define DEVICE_SPEED 0x01
#define LowSpeed 0x01
#define FullSpeed 0x02
#define HighSpeed 0x03
typedef enum USBD_PIPE_TYPE {
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
UsbdPipeTypeBulk,
UsbdPipeTypeInterrupt
} USBD_PIPE_TYPE;
typedef struct {
USBD_PIPE_TYPE PipeType;
UCHAR PipeId;
USHORT MaximumPacketSize;
UCHAR Interval;
} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION;
#pragma pack(1)
typedef struct {
UCHAR request_type;
UCHAR request;
USHORT value;
USHORT index;
USHORT length;
} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET;
#pragma pack()
typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE;
typedef BOOL (WINAPI *WinUsb_AbortPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
WINUSB_SETUP_PACKET SetupPacket,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_FlushPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_Free_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AssociatedInterfaceIndex,
PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_GetCurrentAlternateSetting_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
PUCHAR AlternateSetting
);
typedef BOOL (WINAPI *WinUsb_GetDescriptor_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR DescriptorType,
UCHAR Index,
USHORT LanguageID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred
);
typedef BOOL (WINAPI *WinUsb_GetOverlappedResult_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
LPOVERLAPPED lpOverlapped,
LPDWORD lpNumberOfBytesTransferred,
BOOL bWait
);
typedef BOOL (WINAPI *WinUsb_GetPipePolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
ULONG PolicyType,
PULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_GetPowerPolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG PolicyType,
PULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_Initialize_t)(
HANDLE DeviceHandle,
PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_QueryDeviceInformation_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG InformationType,
PULONG BufferLength,
PVOID Buffer
);
typedef BOOL (WINAPI *WinUsb_QueryInterfaceSettings_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateSettingNumber,
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
);
typedef BOOL (WINAPI *WinUsb_QueryPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
UCHAR PipeIndex,
PWINUSB_PIPE_INFORMATION PipeInformation
);
typedef BOOL (WINAPI *WinUsb_ReadPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_ResetPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateSetting
);
typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
ULONG PolicyType,
ULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_SetPowerPolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG PolicyType,
ULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_WritePipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_ResetDevice_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
/* /!\ These must match the ones from the official libusbk.h */
typedef enum _KUSB_FNID
{
KUSB_FNID_Init,
KUSB_FNID_Free,
KUSB_FNID_ClaimInterface,
KUSB_FNID_ReleaseInterface,
KUSB_FNID_SetAltInterface,
KUSB_FNID_GetAltInterface,
KUSB_FNID_GetDescriptor,
KUSB_FNID_ControlTransfer,
KUSB_FNID_SetPowerPolicy,
KUSB_FNID_GetPowerPolicy,
KUSB_FNID_SetConfiguration,
KUSB_FNID_GetConfiguration,
KUSB_FNID_ResetDevice,
KUSB_FNID_Initialize,
KUSB_FNID_SelectInterface,
KUSB_FNID_GetAssociatedInterface,
KUSB_FNID_Clone,
KUSB_FNID_QueryInterfaceSettings,
KUSB_FNID_QueryDeviceInformation,
KUSB_FNID_SetCurrentAlternateSetting,
KUSB_FNID_GetCurrentAlternateSetting,
KUSB_FNID_QueryPipe,
KUSB_FNID_SetPipePolicy,
KUSB_FNID_GetPipePolicy,
KUSB_FNID_ReadPipe,
KUSB_FNID_WritePipe,
KUSB_FNID_ResetPipe,
KUSB_FNID_AbortPipe,
KUSB_FNID_FlushPipe,
KUSB_FNID_IsoReadPipe,
KUSB_FNID_IsoWritePipe,
KUSB_FNID_GetCurrentFrameNumber,
KUSB_FNID_GetOverlappedResult,
KUSB_FNID_GetProperty,
KUSB_FNID_COUNT,
} KUSB_FNID;
typedef struct _KLIB_VERSION {
INT Major;
INT Minor;
INT Micro;
INT Nano;
} KLIB_VERSION;
typedef KLIB_VERSION* PKLIB_VERSION;
typedef BOOL (WINAPI *LibK_GetProcAddress_t)(
PVOID* ProcAddress,
ULONG DriverID,
ULONG FunctionID
);
typedef VOID (WINAPI *LibK_GetVersion_t)(
PKLIB_VERSION Version
);
struct winusb_interface {
bool initialized;
WinUsb_AbortPipe_t AbortPipe;
WinUsb_ControlTransfer_t ControlTransfer;
WinUsb_FlushPipe_t FlushPipe;
WinUsb_Free_t Free;
WinUsb_GetAssociatedInterface_t GetAssociatedInterface;
WinUsb_GetCurrentAlternateSetting_t GetCurrentAlternateSetting;
WinUsb_GetDescriptor_t GetDescriptor;
WinUsb_GetOverlappedResult_t GetOverlappedResult;
WinUsb_GetPipePolicy_t GetPipePolicy;
WinUsb_GetPowerPolicy_t GetPowerPolicy;
WinUsb_Initialize_t Initialize;
WinUsb_QueryDeviceInformation_t QueryDeviceInformation;
WinUsb_QueryInterfaceSettings_t QueryInterfaceSettings;
WinUsb_QueryPipe_t QueryPipe;
WinUsb_ReadPipe_t ReadPipe;
WinUsb_ResetPipe_t ResetPipe;
WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting;
WinUsb_SetPipePolicy_t SetPipePolicy;
WinUsb_SetPowerPolicy_t SetPowerPolicy;
WinUsb_WritePipe_t WritePipe;
WinUsb_ResetDevice_t ResetDevice;
};
/* 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));

184
Externals/libusbx/libusb/strerror.c vendored Normal file
View File

@ -0,0 +1,184 @@
/*
* libusb strerror code
* Copyright © 2013 Hans de Goede <hdegoede@redhat.com>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include "libusb.h"
#include "libusbi.h"
#if defined(_MSC_VER)
#define strncasecmp _strnicmp
#endif
static size_t usbi_locale = 0;
/** \ingroup misc
* How to add a new \ref libusb_strerror() translation:
* <ol>
* <li> Download the latest \c strerror.c from:<br>
* https://raw.github.com/libusbx/libusbx/master/libusb/sterror.c </li>
* <li> Open the file in an UTF-8 capable editor </li>
* <li> Add the 2 letter <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">ISO 639-1</a>
* code for your locale at the end of \c usbi_locale_supported[]<br>
* Eg. for Chinese, you would add "zh" so that:
* \code... usbi_locale_supported[] = { "en", "nl", "fr" };\endcode
* becomes:
* \code... usbi_locale_supported[] = { "en", "nl", "fr", "zh" };\endcode </li>
* <li> Copy the <tt>{ / * English (en) * / ... }</tt> section and add it at the end of \c usbi_localized_errors<br>
* Eg. for Chinese, the last section of \c usbi_localized_errors could look like:
* \code
* }, { / * Chinese (zh) * /
* "Success",
* ...
* "Other error",
* }
* };\endcode </li>
* <li> Translate each of the English messages from the section you copied into your language </li>
* <li> Save the file (in UTF-8 format) and send it to \c libusbx-devel@lists.sourceforge.net </li>
* </ol>
*/
static const char* usbi_locale_supported[] = { "en", "nl", "fr" };
static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = {
{ /* English (en) */
"Success",
"Input/Output Error",
"Invalid parameter",
"Access denied (insufficient permissions)",
"No such device (it may have been disconnected)",
"Entity not found",
"Resource busy",
"Operation timed out",
"Overflow",
"Pipe error",
"System call interrupted (perhaps due to signal)",
"Insufficient memory",
"Operation not supported or unimplemented on this platform",
"Other error",
}, { /* Dutch (nl) */
"Gelukt",
"Invoer-/uitvoerfout",
"Ongeldig argument",
"Toegang geweigerd (onvoldoende toegangsrechten)",
"Apparaat bestaat niet (verbinding met apparaat verbroken?)",
"Niet gevonden",
"Apparaat of hulpbron is bezig",
"Bewerking verlopen",
"Waarde is te groot",
"Gebroken pijp",
"Onderbroken systeemaanroep",
"Onvoldoende geheugen beschikbaar",
"Bewerking wordt niet ondersteund",
"Andere fout",
}, { /* French (fr) */
"Succès",
"Erreur d'entrée/sortie",
"Paramètre invalide",
"Accès refusé (permissions insuffisantes)",
"Périphérique introuvable (peut-être déconnecté)",
"Elément introuvable",
"Resource déjà occupée",
"Operation expirée",
"Débordement",
"Erreur de pipe",
"Appel système abandonné (peut-être à cause dun signal)",
"Mémoire insuffisante",
"Opération non supportée or non implémentée sur cette plateforme",
"Autre erreur"
}
};
/** \ingroup misc
* Set the language, and only the language, not the encoding! used for
* translatable libusb messages.
*
* This takes a locale string in the default setlocale format: lang[-region]
* or lang[_country_region][.codeset]. Only the lang part of the string is
* used, and only 2 letter ISO 639-1 codes are accepted for it, such as "de".
* The optional region, country_region or codeset parts are ignored. This
* means that functions which return translatable strings will NOT honor the
* specified encoding.
* All strings returned are encoded as UTF-8 strings.
*
* If libusb_setlocale() is not called, all messages will be in English.
*
* The following functions return translatable strings: libusb_strerror().
* Note that the libusb log messages controlled through libusb_set_debug()
* are not translated, they are always in English.
*
* For POSIX UTF-8 environments if you want libusb to follow the standard
* locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)),
* after your app has done its locale setup.
*
* \param locale locale-string in the form of lang[_country_region][.codeset]
* or lang[-region], where lang is a 2 letter ISO 639-1 code
* \returns LIBUSB_SUCCESS on success
* \returns LIBUSB_ERROR_INVALID_PARAM if the locale doesn't meet the requirements
* \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported
* \returns a LIBUSB_ERROR code on other errors
*/
int API_EXPORTED libusb_setlocale(const char *locale)
{
size_t i;
if ( (locale == NULL) || (strlen(locale) < 2)
|| ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') && (locale[2] != '.')) )
return LIBUSB_ERROR_INVALID_PARAM;
for (i=0; i<ARRAYSIZE(usbi_locale_supported); i++) {
if (strncasecmp(usbi_locale_supported[i], locale, 2) == 0)
break;
}
if (i >= ARRAYSIZE(usbi_locale_supported)) {
return LIBUSB_ERROR_NOT_FOUND;
}
usbi_locale = i;
return LIBUSB_SUCCESS;
}
/** \ingroup misc
* Returns a constant string with a short description of the given error code,
* this description is intended for displaying to the end user and will be in
* the language set by libusb_setlocale().
*
* The returned string is encoded in UTF-8.
*
* The messages always start with a capital letter and end without any dot.
* The caller must not free() the returned string.
*
* \param errcode the error code whose description is desired
* \returns a short description of the error code in UTF-8 encoding
*/
DEFAULT_VISIBILITY const char* LIBUSB_CALL libusb_strerror(enum libusb_error errcode)
{
int errcode_index = -errcode;
if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) {
/* "Other Error", which should always be our last message, is returned */
errcode_index = LIBUSB_ERROR_COUNT - 1;
}
return usbi_localized_errors[usbi_locale][errcode_index];
}

307
Externals/libusbx/libusb/sync.c vendored Normal file
View File

@ -0,0 +1,307 @@
/*
* Synchronous I/O functions for libusbx
* Copyright © 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "libusbi.h"
/**
* @defgroup syncio Synchronous device I/O
*
* This page documents libusbx's synchronous (blocking) API for USB device I/O.
* This interface is easy to use but has some limitations. More advanced users
* may wish to consider using the \ref asyncio "asynchronous I/O API" instead.
*/
static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer)
{
int *completed = transfer->user_data;
*completed = 1;
usbi_dbg("actual_length=%d", transfer->actual_length);
/* caller interprets result and frees transfer */
}
static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer)
{
int r, *completed = transfer->user_data;
struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle);
while (!*completed) {
r = libusb_handle_events_completed(ctx, completed);
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying",
libusb_error_name(r));
libusb_cancel_transfer(transfer);
continue;
}
}
}
/** \ingroup syncio
* Perform a USB control transfer.
*
* The direction of the transfer is inferred from the bmRequestType field of
* the setup packet.
*
* The wValue, wIndex and wLength fields values should be given in host-endian
* byte order.
*
* \param dev_handle a handle for the device to communicate with
* \param bmRequestType the request type field for the setup packet
* \param bRequest the request field for the setup packet
* \param wValue the value field for the setup packet
* \param wIndex the index field for the setup packet
* \param data a suitably-sized data buffer for either input or output
* (depending on direction bits within bmRequestType)
* \param wLength the length field for the setup packet. The data buffer should
* be at least this size.
* \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
* \returns on success, the number of bytes actually transferred
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
* device
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other failures
*/
int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
unsigned char *data, uint16_t wLength, unsigned int timeout)
{
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
unsigned char *buffer;
int completed = 0;
int r;
if (!transfer)
return LIBUSB_ERROR_NO_MEM;
buffer = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength);
if (!buffer) {
libusb_free_transfer(transfer);
return LIBUSB_ERROR_NO_MEM;
}
libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex,
wLength);
if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);
libusb_fill_control_transfer(transfer, dev_handle, buffer,
sync_transfer_cb, &completed, timeout);
transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
r = libusb_submit_transfer(transfer);
if (r < 0) {
libusb_free_transfer(transfer);
return r;
}
sync_transfer_wait_for_completion(transfer);
if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
memcpy(data, libusb_control_transfer_get_data(transfer),
transfer->actual_length);
switch (transfer->status) {
case LIBUSB_TRANSFER_COMPLETED:
r = transfer->actual_length;
break;
case LIBUSB_TRANSFER_TIMED_OUT:
r = LIBUSB_ERROR_TIMEOUT;
break;
case LIBUSB_TRANSFER_STALL:
r = LIBUSB_ERROR_PIPE;
break;
case LIBUSB_TRANSFER_NO_DEVICE:
r = LIBUSB_ERROR_NO_DEVICE;
break;
case LIBUSB_TRANSFER_OVERFLOW:
r = LIBUSB_ERROR_OVERFLOW;
break;
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_CANCELLED:
r = LIBUSB_ERROR_IO;
break;
default:
usbi_warn(HANDLE_CTX(dev_handle),
"unrecognised status code %d", transfer->status);
r = LIBUSB_ERROR_OTHER;
}
libusb_free_transfer(transfer);
return r;
}
static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *buffer, int length,
int *transferred, unsigned int timeout, unsigned char type)
{
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
int completed = 0;
int r;
if (!transfer)
return LIBUSB_ERROR_NO_MEM;
libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
sync_transfer_cb, &completed, timeout);
transfer->type = type;
r = libusb_submit_transfer(transfer);
if (r < 0) {
libusb_free_transfer(transfer);
return r;
}
sync_transfer_wait_for_completion(transfer);
*transferred = transfer->actual_length;
switch (transfer->status) {
case LIBUSB_TRANSFER_COMPLETED:
r = 0;
break;
case LIBUSB_TRANSFER_TIMED_OUT:
r = LIBUSB_ERROR_TIMEOUT;
break;
case LIBUSB_TRANSFER_STALL:
r = LIBUSB_ERROR_PIPE;
break;
case LIBUSB_TRANSFER_OVERFLOW:
r = LIBUSB_ERROR_OVERFLOW;
break;
case LIBUSB_TRANSFER_NO_DEVICE:
r = LIBUSB_ERROR_NO_DEVICE;
break;
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_CANCELLED:
r = LIBUSB_ERROR_IO;
break;
default:
usbi_warn(HANDLE_CTX(dev_handle),
"unrecognised status code %d", transfer->status);
r = LIBUSB_ERROR_OTHER;
}
libusb_free_transfer(transfer);
return r;
}
/** \ingroup syncio
* Perform a USB bulk transfer. The direction of the transfer is inferred from
* the direction bits of the endpoint address.
*
* For bulk reads, the <tt>length</tt> field indicates the maximum length of
* data you are expecting to receive. If less data arrives than expected,
* this function will return that data, so be sure to check the
* <tt>transferred</tt> output parameter.
*
* You should also check the <tt>transferred</tt> parameter for bulk writes.
* Not all of the data may have been written.
*
* Also check <tt>transferred</tt> when dealing with a timeout error code.
* libusbx may have to split your transfer into a number of chunks to satisfy
* underlying O/S requirements, meaning that the timeout may expire after
* the first few chunks have completed. libusbx is careful not to lose any data
* that may have been transferred; do not assume that timeout conditions
* indicate a complete lack of I/O.
*
* \param dev_handle a handle for the device to communicate with
* \param endpoint the address of a valid endpoint to communicate with
* \param data a suitably-sized data buffer for either input or output
* (depending on endpoint)
* \param length for bulk writes, the number of bytes from data to be sent. for
* bulk reads, the maximum number of bytes to receive into the data buffer.
* \param transferred output location for the number of bytes actually
* transferred.
* \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
*
* \returns 0 on success (and populates <tt>transferred</tt>)
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates
* <tt>transferred</tt>)
* \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other failures
*/
int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *data, int length, int *transferred,
unsigned int timeout)
{
return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK);
}
/** \ingroup syncio
* Perform a USB interrupt transfer. The direction of the transfer is inferred
* from the direction bits of the endpoint address.
*
* For interrupt reads, the <tt>length</tt> field indicates the maximum length
* of data you are expecting to receive. If less data arrives than expected,
* this function will return that data, so be sure to check the
* <tt>transferred</tt> output parameter.
*
* You should also check the <tt>transferred</tt> parameter for interrupt
* writes. Not all of the data may have been written.
*
* Also check <tt>transferred</tt> when dealing with a timeout error code.
* libusbx may have to split your transfer into a number of chunks to satisfy
* underlying O/S requirements, meaning that the timeout may expire after
* the first few chunks have completed. libusbx is careful not to lose any data
* that may have been transferred; do not assume that timeout conditions
* indicate a complete lack of I/O.
*
* The default endpoint bInterval value is used as the polling interval.
*
* \param dev_handle a handle for the device to communicate with
* \param endpoint the address of a valid endpoint to communicate with
* \param data a suitably-sized data buffer for either input or output
* (depending on endpoint)
* \param length for bulk writes, the number of bytes from data to be sent. for
* bulk reads, the maximum number of bytes to receive into the data buffer.
* \param transferred output location for the number of bytes actually
* transferred.
* \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
*
* \returns 0 on success (and populates <tt>transferred</tt>)
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other error
*/
int API_EXPORTED libusb_interrupt_transfer(
struct libusb_device_handle *dev_handle, unsigned char endpoint,
unsigned char *data, int length, int *transferred, unsigned int timeout)
{
return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT);
}

18
Externals/libusbx/libusb/version.h vendored Normal file
View File

@ -0,0 +1,18 @@
/* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */
#include "version_nano.h"
#ifndef LIBUSB_MAJOR
#define LIBUSB_MAJOR 1
#endif
#ifndef LIBUSB_MINOR
#define LIBUSB_MINOR 0
#endif
#ifndef LIBUSB_MICRO
#define LIBUSB_MICRO 16
#endif
#ifndef LIBUSB_NANO
#define LIBUSB_NANO 0
#endif
/* LIBUSB_RC is the release candidate suffix. Should normally be empty. */
#ifndef LIBUSB_RC
#define LIBUSB_RC ""
#endif

View File

@ -0,0 +1 @@
#define LIBUSB_NANO 10774