early-access version 1255
This commit is contained in:
150
externals/libusb/CMakeLists.txt
vendored
Executable file
150
externals/libusb/CMakeLists.txt
vendored
Executable file
@@ -0,0 +1,150 @@
|
||||
add_library(usb STATIC EXCLUDE_FROM_ALL
|
||||
libusb/libusb/core.c
|
||||
libusb/libusb/core.c
|
||||
libusb/libusb/descriptor.c
|
||||
libusb/libusb/hotplug.c
|
||||
libusb/libusb/io.c
|
||||
libusb/libusb/strerror.c
|
||||
libusb/libusb/sync.c
|
||||
)
|
||||
set_target_properties(usb PROPERTIES VERSION 1.0.23)
|
||||
if(WIN32)
|
||||
target_include_directories(usb
|
||||
BEFORE
|
||||
PUBLIC
|
||||
libusb/libusb
|
||||
|
||||
PRIVATE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
if (NOT MINGW)
|
||||
target_include_directories(usb BEFORE PRIVATE libusb/msvc)
|
||||
endif()
|
||||
|
||||
# Works around other libraries providing their own definition of USB GUIDs (e.g. SDL2)
|
||||
target_compile_definitions(usb PRIVATE "-DGUID_DEVINTERFACE_USB_DEVICE=(GUID){ 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}}")
|
||||
else()
|
||||
target_include_directories(usb
|
||||
# turns out other projects also have "config.h", so make sure the
|
||||
# LibUSB one comes first
|
||||
BEFORE
|
||||
|
||||
PUBLIC
|
||||
libusb/libusb
|
||||
|
||||
PRIVATE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR CYGWIN)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/threads_windows.c
|
||||
libusb/libusb/os/windows_winusb.c
|
||||
libusb/libusb/os/windows_usbdk.c
|
||||
libusb/libusb/os/windows_nt_common.c
|
||||
)
|
||||
set(OS_WINDOWS TRUE)
|
||||
elseif(APPLE)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/darwin_usb.c
|
||||
)
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(OBJC_LIBRARY objc)
|
||||
target_link_libraries(usb PRIVATE
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
${OBJC_LIBRARY}
|
||||
)
|
||||
set(OS_DARWIN TRUE)
|
||||
elseif(ANDROID)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/linux_usbfs.c
|
||||
libusb/libusb/os/linux_netlink.c
|
||||
)
|
||||
find_library(LOG_LIBRARY log)
|
||||
target_link_libraries(usb PRIVATE ${LOG_LIBRARY})
|
||||
set(OS_LINUX TRUE)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/linux_usbfs.c
|
||||
)
|
||||
find_package(Libudev)
|
||||
if(LIBUDEV_FOUND)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/linux_udev.c
|
||||
)
|
||||
target_link_libraries(usb PRIVATE "${LIBUDEV_LIBRARIES}")
|
||||
target_include_directories(usb PRIVATE "${LIBUDEV_INCLUDE_DIR}")
|
||||
set(HAVE_LIBUDEV TRUE)
|
||||
set(USE_UDEV TRUE)
|
||||
else()
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/linux_netlink.c
|
||||
)
|
||||
endif()
|
||||
set(OS_LINUX TRUE)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/netbsd_usb.c
|
||||
)
|
||||
set(OS_NETBSD TRUE)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/openbsd_usb.c
|
||||
)
|
||||
set(OS_OPENBSD TRUE)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/poll_posix.c
|
||||
libusb/libusb/os/threads_posix.c
|
||||
)
|
||||
find_package(Threads REQUIRED)
|
||||
if(THREADS_HAVE_PTHREAD_ARG)
|
||||
target_compile_options(usb PUBLIC "-pthread")
|
||||
endif()
|
||||
if(CMAKE_THREAD_LIBS_INIT)
|
||||
target_link_libraries(usb PRIVATE "${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif()
|
||||
set(THREADS_POSIX TRUE)
|
||||
elseif(WIN32)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/poll_windows.c
|
||||
libusb/libusb/os/threads_windows.c
|
||||
)
|
||||
endif()
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckTypeSize)
|
||||
check_include_files(asm/types.h HAVE_ASM_TYPES_H)
|
||||
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
check_include_files(linux/filter.h HAVE_LINUX_FILTER_H)
|
||||
check_include_files(linux/netlink.h HAVE_LINUX_NETLINK_H)
|
||||
check_include_files(poll.h HAVE_POLL_H)
|
||||
check_include_files(signal.h HAVE_SIGNAL_H)
|
||||
check_include_files(strings.h HAVE_STRINGS_H)
|
||||
check_type_size("struct timespec" STRUCT_TIMESPEC)
|
||||
check_function_exists(syslog HAVE_SYSLOG_FUNC)
|
||||
check_include_files(syslog.h HAVE_SYSLOG_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
|
||||
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES poll.h)
|
||||
check_type_size("nfds_t" nfds_t)
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(HAVE_NFDS_T)
|
||||
set(POLL_NFDS_TYPE "nfds_t")
|
||||
else()
|
||||
set(POLL_NFDS_TYPE "unsigned int")
|
||||
endif()
|
||||
|
||||
check_include_files(sys/timerfd.h USBI_TIMERFD_AVAILABLE)
|
||||
|
||||
|
||||
configure_file(config.h.in config.h)
|
||||
90
externals/libusb/config.h.in
vendored
Executable file
90
externals/libusb/config.h.in
vendored
Executable file
@@ -0,0 +1,90 @@
|
||||
/* Default visibility */
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
|
||||
#elif defined(_MSC_VER)
|
||||
#define DEFAULT_VISIBILITY __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
/* Start with debug message logging enabled */
|
||||
#undef ENABLE_DEBUG_LOGGING
|
||||
|
||||
/* Message logging */
|
||||
#undef ENABLE_LOGGING
|
||||
|
||||
/* Define to 1 if you have the <asm/types.h> header file. */
|
||||
#cmakedefine HAVE_ASM_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#cmakedefine HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `udev' library (-ludev). */
|
||||
#cmakedefine HAVE_LIBUDEV 1
|
||||
|
||||
/* Define to 1 if you have the <linux/filter.h> header file. */
|
||||
#cmakedefine HAVE_LINUX_FILTER_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
||||
#cmakedefine HAVE_LINUX_NETLINK_H 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#cmakedefine HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#cmakedefine HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#cmakedefine HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct timespec'. */
|
||||
#cmakedefine HAVE_STRUCT_TIMESPEC 1
|
||||
|
||||
/* syslog() function available */
|
||||
#cmakedefine HAVE_SYSLOG_FUNC 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#cmakedefine HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Darwin backend */
|
||||
#cmakedefine OS_DARWIN 1
|
||||
|
||||
/* Linux backend */
|
||||
#cmakedefine OS_LINUX 1
|
||||
|
||||
/* NetBSD backend */
|
||||
#cmakedefine OS_NETBSD 1
|
||||
|
||||
/* OpenBSD backend */
|
||||
#cmakedefine OS_OPENBSD 1
|
||||
|
||||
/* Windows backend */
|
||||
#cmakedefine OS_WINDOWS 1
|
||||
|
||||
/* type of second poll() argument */
|
||||
#define POLL_NFDS_TYPE @POLL_NFDS_TYPE@
|
||||
|
||||
/* Use POSIX Threads */
|
||||
#cmakedefine THREADS_POSIX
|
||||
|
||||
/* timerfd headers available */
|
||||
#cmakedefine USBI_TIMERFD_AVAILABLE 1
|
||||
|
||||
/* Enable output to system log */
|
||||
#define USE_SYSTEM_LOGGING_FACILITY 1
|
||||
|
||||
/* Use udev for device enumeration/hotplug */
|
||||
#cmakedefine USE_UDEV 1
|
||||
|
||||
/* Use GNU extensions */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/* Oldest Windows version supported */
|
||||
#define WINVER 0x0501
|
||||
11
externals/libusb/libusb/.gitattributes
vendored
Executable file
11
externals/libusb/libusb/.gitattributes
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
*.sh eol=lf
|
||||
*.ac eol=lf
|
||||
*.am eol=lf
|
||||
*.dsw eol=crlf
|
||||
*.dsp eol=crlf whitespace=space-before-tab
|
||||
*.sln eol=crlf
|
||||
*.vcproj eol=crlf
|
||||
*.vcxproj* eol=crlf
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
INSTALL_WIN.txt eol=crlf
|
||||
60
externals/libusb/libusb/.gitignore
vendored
Executable file
60
externals/libusb/libusb/.gitignore
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h1
|
||||
m4/
|
||||
autom4te.cache
|
||||
INSTALL
|
||||
install-sh
|
||||
depcomp
|
||||
configure
|
||||
aclocal.m4
|
||||
compile
|
||||
config.guess
|
||||
config.h*
|
||||
!msvc/config.h
|
||||
!android/config.h
|
||||
!Xcode/config.h
|
||||
.vs
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
*.swp
|
||||
doxygen.cfg
|
||||
examples/listdevs
|
||||
examples/xusb
|
||||
examples/dpfp
|
||||
examples/dpfp_threaded
|
||||
examples/fxload
|
||||
examples/hotplugtest
|
||||
examples/sam3u_benchmark
|
||||
examples/testlibusb
|
||||
tests/stress
|
||||
*.exe
|
||||
*.pc
|
||||
doc/html
|
||||
*.plg
|
||||
*.ncb
|
||||
*.opt
|
||||
Debug
|
||||
Release
|
||||
*.user
|
||||
*.suo
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.patch
|
||||
*~
|
||||
*.orig
|
||||
.dirstamp
|
||||
.amend
|
||||
xcuserdata
|
||||
*.xcuserdatad
|
||||
*.xccheckout
|
||||
*.xcscmblueprint
|
||||
5
externals/libusb/libusb/.private/README.txt
vendored
Executable file
5
externals/libusb/libusb/.private/README.txt
vendored
Executable file
@@ -0,0 +1,5 @@
|
||||
This directory contains private internal scripts used by the libusb
|
||||
project maintainers.
|
||||
|
||||
These scripts are not intended for general usage and will not be
|
||||
exported when producing release archives.
|
||||
89
externals/libusb/libusb/.private/bd.cmd
vendored
Executable file
89
externals/libusb/libusb/.private/bd.cmd
vendored
Executable file
@@ -0,0 +1,89 @@
|
||||
@echo off
|
||||
rem produce the DDK binary files for snapshots
|
||||
rem !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!!
|
||||
|
||||
if NOT x%DDK_TARGET_OS%==xWinXP goto usage
|
||||
|
||||
set IWD=%~dp0
|
||||
cd ..
|
||||
mkdir E:\dailies\%DATE%
|
||||
for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A
|
||||
for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A\static
|
||||
for %%A in (MS32 MS64) do mkdir E:\dailies\%DATE%\%%A\dll
|
||||
for %%A in (source bin32 bin64) do mkdir E:\dailies\%DATE%\examples\%%A
|
||||
copy examples\listdevs.c E:\dailies\%DATE%\examples\source
|
||||
copy examples\xusb.c E:\dailies\%DATE%\examples\source
|
||||
copy examples\ezusb.? E:\dailies\%DATE%\examples\source
|
||||
copy examples\fxload.c E:\dailies\%DATE%\examples\source
|
||||
copy msvc\stdint.h E:\dailies\%DATE%\examples\source
|
||||
copy .private\wbs.txt E:\dailies\%DATE%\README.txt
|
||||
|
||||
set ORG_BUILD_ALT_DIR=%BUILD_ALT_DIR%
|
||||
set ORG_BUILDARCH=%_BUILDARCH%
|
||||
set ORG_PATH=%PATH%
|
||||
set ORG_BUILD_DEFAULT_TARGETS=%BUILD_DEFAULT_TARGETS%
|
||||
|
||||
set 386=1
|
||||
set AMD64=
|
||||
set BUILD_DEFAULT_TARGETS=-386
|
||||
set _AMD64bit=
|
||||
set _BUILDARCH=x86
|
||||
set PATH=%BASEDIR%\bin\x86;%BASEDIR%\bin\x86\x86
|
||||
|
||||
cd msvc
|
||||
call ddk_build
|
||||
cd ..
|
||||
|
||||
@echo off
|
||||
copy Win32\Release\lib\libusb-1.0.lib E:\dailies\%DATE%\MS32\static
|
||||
copy Win32\Release\examples\listdevs.exe E:\dailies\%DATE%\examples\bin32
|
||||
copy Win32\Release\examples\xusb.exe E:\dailies\%DATE%\examples\bin32
|
||||
copy Win32\Release\examples\fxload.exe E:\dailies\%DATE%\examples\bin32
|
||||
|
||||
cd msvc
|
||||
call ddk_build DLL
|
||||
cd ..
|
||||
|
||||
@echo off
|
||||
copy Win32\Release\lib\libusb-1.0.lib E:\dailies\%DATE%\MS32\dll
|
||||
copy Win32\Release\dll\libusb-1.0.dll E:\dailies\%DATE%\MS32\dll
|
||||
copy Win32\Release\dll\libusb-1.0.pdb E:\dailies\%DATE%\MS32\dll
|
||||
|
||||
set 386=
|
||||
set AMD64=1
|
||||
set BUILD_DEFAULT_TARGETS=-amd64
|
||||
set _AMD64bit=true
|
||||
set _BUILDARCH=AMD64
|
||||
set PATH=%BASEDIR%\bin\x86\amd64;%BASEDIR%\bin\x86
|
||||
|
||||
cd msvc
|
||||
call ddk_build
|
||||
cd ..
|
||||
|
||||
@echo off
|
||||
copy x64\Release\lib\libusb-1.0.lib E:\dailies\%DATE%\MS64\static
|
||||
copy x64\Release\examples\listdevs.exe E:\dailies\%DATE%\examples\bin64
|
||||
copy x64\Release\examples\xusb.exe E:\dailies\%DATE%\examples\bin64
|
||||
copy x64\Release\examples\fxload.exe E:\dailies\%DATE%\examples\bin64
|
||||
|
||||
cd msvc
|
||||
call ddk_build DLL
|
||||
cd ..
|
||||
|
||||
@echo off
|
||||
copy x64\Release\lib\libusb-1.0.lib E:\dailies\%DATE%\MS64\dll
|
||||
copy x64\Release\dll\libusb-1.0.dll E:\dailies\%DATE%\MS64\dll
|
||||
copy x64\Release\dll\libusb-1.0.pdb E:\dailies\%DATE%\MS64\dll
|
||||
|
||||
set BUILD_ALT_DIR=%ORG_BUILD_ALT_DIR%
|
||||
set _BUILDARCH=%ORG_BUILDARCH%
|
||||
set PATH=%ORG_PATH%
|
||||
set BUILD_DEFAULT_TARGETS=%ORG_BUILD_DEFAULT_TARGETS%
|
||||
|
||||
goto done
|
||||
|
||||
:usage
|
||||
echo must be run in a WXP build environment!
|
||||
|
||||
:done
|
||||
cd %IWD%
|
||||
54
externals/libusb/libusb/.private/bm.sh
vendored
Executable file
54
externals/libusb/libusb/.private/bm.sh
vendored
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
# produce the MinGW binary files for snapshots
|
||||
# !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!!
|
||||
|
||||
PWD=`pwd`
|
||||
cd ..
|
||||
date=`date +%Y.%m.%d`
|
||||
target=e:/dailies/$date
|
||||
mkdir -p $target/include/libusb-1.0
|
||||
cp -v libusb/libusb-1.0.def $target
|
||||
cp -v libusb/libusb.h $target/include/libusb-1.0
|
||||
|
||||
#
|
||||
# 32 bit binaries
|
||||
#
|
||||
target=e:/dailies/$date/MinGW32
|
||||
git clean -fdx
|
||||
# Not using debug (-g) in CFLAGS DRAMATICALLY reduces the size of the binaries
|
||||
export CFLAGS="-O2 -m32"
|
||||
export LDFLAGS="-m32"
|
||||
export RCFLAGS="--target=pe-i386"
|
||||
export DLLTOOLFLAGS="-m i386 -f --32"
|
||||
echo `pwd`
|
||||
(glibtoolize --version) < /dev/null > /dev/null 2>&1 && LIBTOOLIZE=glibtoolize || LIBTOOLIZE=libtoolize
|
||||
$LIBTOOLIZE --copy --force || exit 1
|
||||
aclocal || exit 1
|
||||
autoheader || exit 1
|
||||
autoconf || exit 1
|
||||
automake -a -c || exit 1
|
||||
./configure
|
||||
make -j2
|
||||
mkdir -p $target/static
|
||||
mkdir -p $target/dll
|
||||
cp -v libusb/.libs/libusb-1.0.a $target/static
|
||||
cp -v libusb/.libs/libusb-1.0.dll $target/dll
|
||||
cp -v libusb/.libs/libusb-1.0.dll.a $target/dll
|
||||
make clean -j2
|
||||
|
||||
#
|
||||
# 64 bit binaries
|
||||
#
|
||||
target=e:/dailies/$date/MinGW64
|
||||
export CFLAGS="-O2"
|
||||
export LDFLAGS=""
|
||||
export RCFLAGS=""
|
||||
export DLLTOOLFLAGS=""
|
||||
./configure
|
||||
make -j2
|
||||
mkdir -p $target/static
|
||||
mkdir -p $target/dll
|
||||
cp -v libusb/.libs/libusb-1.0.a $target/static
|
||||
cp -v libusb/.libs/libusb-1.0.dll $target/dll
|
||||
cp -v libusb/.libs/libusb-1.0.dll.a $target/dll
|
||||
cd $PWD
|
||||
57
externals/libusb/libusb/.private/bwince.cmd
vendored
Executable file
57
externals/libusb/libusb/.private/bwince.cmd
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
@echo off
|
||||
rem produce the Win CE binary files for snapshots
|
||||
rem !!!THIS SCRIPT IS FOR INTERNAL DEVELOPER USE ONLY!!!
|
||||
|
||||
if "x%VSINSTALLDIR%"=="x" goto usage
|
||||
|
||||
if "x%WINCE_TARGET_DIR_BASE%"=="x" set WINCE_TARGET_DIR_BASE=E:\dailies
|
||||
if "x%WINCE_TARGET_ARCHES%"=="x" set WINCE_TARGET_ARCHES=ARMV4I MIPSII MIPSII_FP MIPSIV MIPSIV_FP SH4 x86
|
||||
|
||||
|
||||
set WINCE_TARGET_DIR=%WINCE_TARGET_DIR_BASE%\%DATE:/=-%
|
||||
set MSBUILD_CMD=msbuild.exe
|
||||
set MSBUILD_TARGET=Rebuild
|
||||
set MSBUILD_CONFIGURATION=Release
|
||||
set WINCE_SLN=msvc\libusb_wince.sln
|
||||
set PLATFORM_PREFIX=STANDARDSDK_500 (
|
||||
set PLATFORM_POSTFIX=)
|
||||
|
||||
|
||||
set PWD=%~dp0
|
||||
cd ..
|
||||
|
||||
mkdir %WINCE_TARGET_DIR%
|
||||
mkdir %WINCE_TARGET_DIR%\include\libusb-1.0
|
||||
copy libusb\libusb-1.0.def %WINCE_TARGET_DIR%
|
||||
copy libusb\libusb.h %WINCE_TARGET_DIR%\include\libusb-1.0
|
||||
for %%A in (%WINCE_TARGET_ARCHES%) do mkdir %WINCE_TARGET_DIR%\%%A
|
||||
for %%A in (%WINCE_TARGET_ARCHES%) do mkdir %WINCE_TARGET_DIR%\%%A\static
|
||||
for %%A in (%WINCE_TARGET_ARCHES%) do mkdir %WINCE_TARGET_DIR%\%%A\dll
|
||||
for %%A in (%WINCE_TARGET_ARCHES%) do mkdir %WINCE_TARGET_DIR%\examples\%%A
|
||||
mkdir %WINCE_TARGET_DIR%\examples\source
|
||||
copy examples\listdevs.c %WINCE_TARGET_DIR%\examples\source
|
||||
copy examples\xusb.c %WINCE_TARGET_DIR%\examples\source
|
||||
copy msvc\stdint.h %WINCE_TARGET_DIR%\examples\source
|
||||
copy .private\wbs_wince.txt %WINCE_TARGET_DIR%\README.txt
|
||||
copy COPYING %WINCE_TARGET_DIR%\COPYING
|
||||
|
||||
rem Perform the rebuild
|
||||
for %%A in (%WINCE_TARGET_ARCHES%) do %MSBUILD_CMD% %WINCE_SLN% /property:Platform="%PLATFORM_PREFIX%%%A%PLATFORM_POSTFIX%" /property:Configuration=%MSBUILD_CONFIGURATION% /target:%MSBUILD_TARGET%"
|
||||
|
||||
|
||||
rem Copy across the binaries
|
||||
for %%A in (%WINCE_TARGET_ARCHES%) do (
|
||||
copy %%A\%MSBUILD_CONFIGURATION%\lib\libusb-1.0.lib %WINCE_TARGET_DIR%\%%A\static
|
||||
copy %%A\%MSBUILD_CONFIGURATION%\examples\listdevs.exe %WINCE_TARGET_DIR%\examples\%%A
|
||||
copy %%A\%MSBUILD_CONFIGURATION%\examples\xusb.exe %WINCE_TARGET_DIR%\examples\%%A
|
||||
copy %%A\%MSBUILD_CONFIGURATION%\dll\libusb-1.0.lib %WINCE_TARGET_DIR%\%%A\dll
|
||||
copy %%A\%MSBUILD_CONFIGURATION%\dll\libusb-1.0.dll %WINCE_TARGET_DIR%\%%A\dll
|
||||
copy %%A\%MSBUILD_CONFIGURATION%\dll\libusb-1.0.pdb %WINCE_TARGET_DIR%\%%A\dll )
|
||||
|
||||
goto done
|
||||
|
||||
:usage
|
||||
echo must be run in a Visual Studio 2005 build environment!
|
||||
|
||||
:done
|
||||
cd %PWD%
|
||||
28
externals/libusb/libusb/.private/post-rewrite.sh
vendored
Executable file
28
externals/libusb/libusb/.private/post-rewrite.sh
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Detect amended commits and warn user if .amend is missing
|
||||
#
|
||||
# To have git run this script on commit, create a "post-rewrite" text file in
|
||||
# .git/hooks/ with the following content:
|
||||
# #!/bin/sh
|
||||
# if [ -x .private/post-rewrite.sh ]; then
|
||||
# source .private/post-rewrite.sh
|
||||
# fi
|
||||
#
|
||||
# NOTE: These versioning hooks are intended to be used *INTERNALLY* by the
|
||||
# libusb development team and are NOT intended to solve versioning for any
|
||||
# derivative branch, such as one you would create for private development.
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
amend)
|
||||
# Check if a .amend exists. If none, create one and warn user to re-commit.
|
||||
if [ -f .amend ]; then
|
||||
rm .amend
|
||||
else
|
||||
echo "Amend commit detected, but no .amend file - One has now been created."
|
||||
echo "Please re-commit as is (amend), so that the version number is correct."
|
||||
touch .amend
|
||||
fi ;;
|
||||
*) ;;
|
||||
esac
|
||||
48
externals/libusb/libusb/.private/pre-commit.sh
vendored
Executable file
48
externals/libusb/libusb/.private/pre-commit.sh
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Sets the nano version according to the number of commits on this branch, as
|
||||
# well as the branch offset.
|
||||
#
|
||||
# To have git run this script on commit, first make sure you change
|
||||
# BRANCH_OFFSET to 60000 or higher, then create a "pre-commit" text file in
|
||||
# .git/hooks/ with the following content:
|
||||
# #!/bin/sh
|
||||
# if [ -x .private/pre-commit.sh ]; then
|
||||
# source .private/pre-commit.sh
|
||||
# fi
|
||||
#
|
||||
# NOTE: These versioning hooks are intended to be used *INTERNALLY* by the
|
||||
# libusb development team and are NOT intended to solve versioning for any
|
||||
# derivative branch, such as one you would create for private development.
|
||||
#
|
||||
# Should you wish to reuse these scripts for your own versioning, in your own
|
||||
# private branch, we kindly ask you to first set BRANCH_OFFSET to 60000, or
|
||||
# higher, as any offset below below 60000 is *RESERVED* for libusb official
|
||||
# usage.
|
||||
|
||||
################################################################################
|
||||
## YOU *MUST* SET THE FOLLOWING TO 60000 OR HIGHER IF YOU REUSE THIS SCRIPT ##
|
||||
################################################################################
|
||||
BRANCH_OFFSET=10000
|
||||
################################################################################
|
||||
|
||||
if [ "$BASH_VERSION" = '' ]; then
|
||||
TYPE_CMD="type git >/dev/null 2>&1"
|
||||
else
|
||||
TYPE_CMD="type -P git &>/dev/null"
|
||||
fi
|
||||
|
||||
eval $TYPE_CMD || { echo "git command not found. Aborting." >&2; exit 1; }
|
||||
|
||||
NANO=`git log --oneline | wc -l`
|
||||
NANO=`expr $NANO + $BRANCH_OFFSET`
|
||||
# Amended commits need to have the nano corrected. Current versions of git hooks
|
||||
# only allow detection of amending post commit, so we require a .amend file,
|
||||
# which will be created post commit with a user warning if none exists when an
|
||||
# amend is detected.
|
||||
if [ -f .amend ]; then
|
||||
NANO=`expr $NANO - 1`
|
||||
fi
|
||||
echo "setting nano to $NANO"
|
||||
echo "#define LIBUSB_NANO $NANO" > libusb/version_nano.h
|
||||
git add libusb/version_nano.h
|
||||
61
externals/libusb/libusb/.private/wbs.txt
vendored
Executable file
61
externals/libusb/libusb/.private/wbs.txt
vendored
Executable file
@@ -0,0 +1,61 @@
|
||||
libusb 1.0 Windows binary snapshot - README
|
||||
|
||||
*********************************************************************
|
||||
* The latest version of this snapshot can always be downloaded at: *
|
||||
* https://sourceforge.net/projects/libusb/files/ *
|
||||
*********************************************************************
|
||||
|
||||
o Visual Studio:
|
||||
- Open existing or create a new project for your application
|
||||
- Copy libusb.h, from the include\libusb-1.0\ directory, into your project and
|
||||
make sure that the location where the file reside appears in the 'Additional
|
||||
Include Directories' section (Configuration Properties -> C/C++ -> General).
|
||||
- Copy the relevant .lib file from MS32\ or MS64\ and add 'libusb-1.0.lib' to
|
||||
your 'Additional Dependencies' (Configuration Properties -> Linker -> Input)
|
||||
Also make sure that the directory where libusb-1.0.lib resides is added to
|
||||
'Additional Library Directories' (Configuration Properties -> Linker
|
||||
-> General)
|
||||
- If you use the static version of the libusb library, make sure that
|
||||
'Runtime Library' is set to 'Multi-threaded DLL (/MD)' (Configuration
|
||||
Properties -> C/C++ -> Code Generation).
|
||||
NB: If your application requires /MT (Multi-threaded/libCMT), you need to
|
||||
recompile a static libusb 1.0 library from source.
|
||||
- Compile and run your application. If you use the DLL version of libusb-1.0,
|
||||
remember that you need to have a copy of the DLL either in the runtime
|
||||
directory or in system32
|
||||
|
||||
o WDK/DDK:
|
||||
- The following is an example of a sources files that you can use to compile
|
||||
a libusb 1.0 based console application. In this sample ..\libusb\ is the
|
||||
directory where you would have copied libusb.h as well as the relevant
|
||||
libusb-1.0.lib
|
||||
|
||||
TARGETNAME=your_app
|
||||
TARGETTYPE=PROGRAM
|
||||
USE_MSVCRT=1
|
||||
UMTYPE=console
|
||||
INCLUDES=..\libusb;$(DDK_INC_PATH)
|
||||
TARGETLIBS=..\libusb\libusb-1.0.lib
|
||||
SOURCES=your_app.c
|
||||
|
||||
- Note that if you plan to use libCMT instead of MSVCRT (USE_LIBCMT=1 instead
|
||||
of USE_MSVCRT=1), you will need to recompile libusb to use libCMT. This can
|
||||
easily be achieved, in the DDK environment, by running 'ddk_build /MT'
|
||||
|
||||
o MinGW/cygwin
|
||||
- Copy libusb.h, from include/libusb-1.0/ to your default include directory,
|
||||
and copy the MinGW32/ or MinGW64/ .a files to your default library directory.
|
||||
Or, if you don't want to use the default locations, make sure that you feed
|
||||
the relevant -I and -L options to the compiler.
|
||||
- Add the '-lusb-1.0' linker option when compiling.
|
||||
|
||||
o Additional information:
|
||||
- The libusb 1.0 API documentation can be accessed at:
|
||||
http://api.libusb.info
|
||||
- For some libusb samples (including source), please have a look in examples/
|
||||
- For additional information on the libusb 1.0 Windows backend please visit:
|
||||
http://windows.libusb.info
|
||||
- The MinGW and MS generated DLLs are fully interchangeable, provided that you
|
||||
use the import libs provided or generate one from the .def also provided.
|
||||
- If you find any issue, please visit http://libusb.info/ and check the
|
||||
Support section
|
||||
42
externals/libusb/libusb/.private/wbs_wince.txt
vendored
Executable file
42
externals/libusb/libusb/.private/wbs_wince.txt
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
libusb 1.0 Windows CE binary snapshot - README
|
||||
|
||||
*********************************************************************
|
||||
* The latest version of this snapshot can always be downloaded at: *
|
||||
* https://sourceforge.net/projects/libusb/files/ *
|
||||
*********************************************************************
|
||||
|
||||
The binaries contained in this snapshot are licensed under the
|
||||
GNU Lesser General Public License version 2.1 or, at your option, any later
|
||||
version (see COPYING for further details). The source code for these binaries
|
||||
is available for download at the same location as this binary snapshot.
|
||||
|
||||
o Visual Studio:
|
||||
- Open existing or create a new project for your application
|
||||
- Copy libusb.h, from the include\libusb-1.0\ directory, into your project and
|
||||
make sure that the location where the file reside appears in the 'Additional
|
||||
Include Directories' section (Configuration Properties -> C/C++ -> General).
|
||||
- Copy the relevant .lib file from ARMV4I, MIPSII, MIPSII_FP, MIPSIV, MIPSIV_FP,
|
||||
SH4 or x86 and add 'libusb-1.0.lib' to your 'Additional Dependencies'
|
||||
(Configuration Properties -> Linker -> Input). Also make sure that the
|
||||
directory where libusb-1.0.lib resides is added to 'Additional Library
|
||||
Directories' (Configuration Properties -> Linker -> General)
|
||||
- If you use the static version of the libusb library, make sure that
|
||||
'Runtime Library' is set to 'Multi-threaded DLL (/MD)' (Configuration
|
||||
Properties -> C/C++ -> Code Generation).
|
||||
NB: If your application requires /MT (Multi-threaded/libCMT), you need to
|
||||
recompile a static libusb 1.0 library from source.
|
||||
- Compile and run your application. If you use the DLL version of libusb-1.0,
|
||||
remember that you need to have a copy of the DLL either in the runtime
|
||||
directory or in system32
|
||||
|
||||
o Additional information:
|
||||
- The libusb 1.0 API documentation can be accessed at:
|
||||
http://api.libusb.info
|
||||
- For some libusb samples (including source), please have a look in examples/
|
||||
- For additional information on the libusb 1.0 Windows backend please visit:
|
||||
http://windows.libusb.info
|
||||
- It is necessary to install the CE USB Kernel Wrapper driver for libusb to
|
||||
function on a device. This is obtainable from:
|
||||
https://github.com/RealVNC/CEUSBKWrapper
|
||||
- If you find any issue, please visit http://libusb.info/ and check the
|
||||
Support section
|
||||
49
externals/libusb/libusb/.travis.yml
vendored
Executable file
49
externals/libusb/libusb/.travis.yml
vendored
Executable file
@@ -0,0 +1,49 @@
|
||||
language: c
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler: clang
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: gcc
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
compiler: clang
|
||||
- os: osx
|
||||
osx_image: xcode7.1
|
||||
compiler: gcc
|
||||
- os: osx
|
||||
osx_image: xcode7.1
|
||||
compiler: clang
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.2
|
||||
compiler: gcc
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.2
|
||||
compiler: clang
|
||||
|
||||
addons:
|
||||
homebrew:
|
||||
update: true
|
||||
brewfile: true
|
||||
apt:
|
||||
packages:
|
||||
- autoconf
|
||||
- automake
|
||||
- libtool
|
||||
- m4
|
||||
- libudev-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
script:
|
||||
- ./autogen.sh && make clean && make
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./travis-autogen.sh --disable-udev && make clean && make ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cd Xcode && xcodebuild -project libusb.xcodeproj ; fi
|
||||
119
externals/libusb/libusb/AUTHORS
vendored
Executable file
119
externals/libusb/libusb/AUTHORS
vendored
Executable file
@@ -0,0 +1,119 @@
|
||||
Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
||||
Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
|
||||
Copyright © 2010-2012 Peter Stuge <peter@stuge.se>
|
||||
Copyright © 2008-2016 Nathan Hjelm <hjelmn@users.sourceforge.net>
|
||||
Copyright © 2009-2013 Pete Batard <pete@akeo.ie>
|
||||
Copyright © 2009-2013 Ludovic Rousseau <ludovic.rousseau@gmail.com>
|
||||
Copyright © 2010-2012 Michael Plante <michael.plante@gmail.com>
|
||||
Copyright © 2011-2013 Hans de Goede <hdegoede@redhat.com>
|
||||
Copyright © 2012-2013 Martin Pieuchot <mpi@openbsd.org>
|
||||
Copyright © 2012-2013 Toby Gray <toby.gray@realvnc.com>
|
||||
Copyright © 2013-2018 Chris Dickens <christopher.a.dickens@gmail.com>
|
||||
|
||||
Other contributors:
|
||||
Adrian Bunk
|
||||
Akshay Jaggi
|
||||
Alan Ott
|
||||
Alan Stern
|
||||
Alex Vatchenko
|
||||
Andrew Fernandes
|
||||
Andy Chunyu
|
||||
Andy McFadden
|
||||
Angus Gratton
|
||||
Anil Nair
|
||||
Anthony Clay
|
||||
Antonio Ospite
|
||||
Artem Egorkine
|
||||
Aurelien Jarno
|
||||
Bastien Nocera
|
||||
Bei Zhang
|
||||
Benjamin Dobell
|
||||
Brent Rector
|
||||
Carl Karsten
|
||||
Christophe Zeitouny
|
||||
Colin Walters
|
||||
Dave Camarillo
|
||||
David Engraf
|
||||
David Moore
|
||||
Davidlohr Bueso
|
||||
Dmitry Fleytman
|
||||
Doug Johnston
|
||||
Evan Hunter
|
||||
Federico Manzan
|
||||
Felipe Balbi
|
||||
Florian Albrechtskirchinger
|
||||
Francesco Montorsi
|
||||
Francisco Facioni
|
||||
Gaurav Gupta
|
||||
Graeme Gill
|
||||
Gustavo Zacarias
|
||||
Hans Ulrich Niedermann
|
||||
Hector Martin
|
||||
Hoi-Ho Chan
|
||||
Ilya Konstantinov
|
||||
Jakub Klama
|
||||
James Hanko
|
||||
Jeffrey Nichols
|
||||
Johann Richard
|
||||
John Sheu
|
||||
Jonathon Jongsma
|
||||
Joost Muller
|
||||
Josh Gao
|
||||
Joshua Blake
|
||||
Justin Bischoff
|
||||
KIMURA Masaru
|
||||
Karsten Koenig
|
||||
Konrad Rzepecki
|
||||
Kuangye Guo
|
||||
Lars Kanis
|
||||
Lars Wirzenius
|
||||
Lei Chen
|
||||
Luca Longinotti
|
||||
Marcus Meissner
|
||||
Markus Heidelberg
|
||||
Martin Ettl
|
||||
Martin Koegler
|
||||
Matthew Stapleton
|
||||
Matthias Bolte
|
||||
Michel Zou
|
||||
Mike Frysinger
|
||||
Mikhail Gusarov
|
||||
Morgan Leborgne
|
||||
Moritz Fischer
|
||||
Ларионов Даниил
|
||||
Nicholas Corgan
|
||||
Omri Iluz
|
||||
Orin Eman
|
||||
Paul Fertser
|
||||
Pekka Nikander
|
||||
Rob Walker
|
||||
Romain Vimont
|
||||
Roman Kalashnikov
|
||||
Sameeh Jubran
|
||||
Sean McBride
|
||||
Sebastian Pipping
|
||||
Sergey Serb
|
||||
Simon Haggett
|
||||
Simon Newton
|
||||
Stefan Agner
|
||||
Stefan Tauner
|
||||
Steinar H. Gunderson
|
||||
Thomas Röfer
|
||||
Tim Hutt
|
||||
Tim Roberts
|
||||
Tobias Klauser
|
||||
Toby Peterson
|
||||
Tormod Volden
|
||||
Trygve Laugstøl
|
||||
Uri Lublin
|
||||
Vasily Khoruzhick
|
||||
Vegard Storheil Eriksen
|
||||
Venkatesh Shukla
|
||||
Vianney le Clément de Saint-Marcq
|
||||
Victor Toso
|
||||
Vitali Lovich
|
||||
William Skellenger
|
||||
Xiaofan Chen
|
||||
Zoltán Kovács
|
||||
Роман Донченко
|
||||
parafin
|
||||
4
externals/libusb/libusb/Brewfile
vendored
Executable file
4
externals/libusb/libusb/Brewfile
vendored
Executable file
@@ -0,0 +1,4 @@
|
||||
brew 'automake'
|
||||
brew 'libtool'
|
||||
brew 'autoconf'
|
||||
brew 'm4'
|
||||
504
externals/libusb/libusb/COPYING
vendored
Executable file
504
externals/libusb/libusb/COPYING
vendored
Executable file
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
283
externals/libusb/libusb/ChangeLog
vendored
Executable file
283
externals/libusb/libusb/ChangeLog
vendored
Executable file
@@ -0,0 +1,283 @@
|
||||
For detailed information about the changes below, please see the git log or
|
||||
visit: http://log.libusb.info
|
||||
|
||||
2019-08-28: v1.0.23
|
||||
* Add German translation (#446)
|
||||
* Add Hungarian translation (#493)
|
||||
* Android: Improved support for Android
|
||||
* BSD: Remove infinite recursion in OpenBSD backend
|
||||
* configure.ac: Fix detection of clock_gettime library (#439)
|
||||
* Core: abandon synchronous transfers when device closure is detected.
|
||||
* Core: fix error in handling the removal of file descriptors while handling
|
||||
events.
|
||||
* Darwin(macOS): Switch from using ResetDevice to USBDeviceReEnumerate (#455)
|
||||
* Darwin(macOS): Remove code that changed the device class used (#428)
|
||||
* Darwin(macOS): Reduce hotplug timeout to 1ms (from 5s)
|
||||
* New API libusb_set_log_cb() to redirect global and per context log
|
||||
messages to the provided log handling function
|
||||
* New API libusb_wrap_sys_device to allow the user to specify the
|
||||
usb device to use.
|
||||
* Solaris: Break infinite recursion in backend clock_gettime
|
||||
* Solaris: Enable timerfd on sunos when available
|
||||
* Windows: Add support for isochronous transfers with WinUSB
|
||||
* Various other bug fixes and improvements
|
||||
|
||||
2018-03-24: v1.0.22:
|
||||
* New libusb_set_option() API
|
||||
* Fix transfer timeout not being cleared upon resubmission
|
||||
* Report super speed plus devices on modern Linux and macOS
|
||||
* Darwin: Improve support for macOS Sierra and High Sierra
|
||||
* Darwin: SDK fixes and improvements
|
||||
* Linux: Let initialization succeed when no devices are present
|
||||
* Linux: Mark internal file descriptors with CLOEXEC flag
|
||||
* Solaris: Add support for attach/detach kernel driver
|
||||
* Windows: Add dynamic UsbDk backend selection
|
||||
* Windows: Add isochronous transfer support via libusbK
|
||||
* Windows: Add Visual Studio 2017 support
|
||||
* Windows: Fix enumeration problems on Windows 8 and later
|
||||
* Windows: Major rework of poll() emulation
|
||||
* Windows: Numerous HID API fixes
|
||||
* Windows: Support cancelation of individual transfers (Vista and later)
|
||||
* Various other bug fixes and improvements
|
||||
|
||||
2016-10-01: v1.0.21:
|
||||
* Core: Refactor code related to transfer flags and timeout handling
|
||||
* Darwin: Ignore root hub simulation devices
|
||||
* Darwin: Improved support for OS X El Capitan
|
||||
* Darwin: Work around devices with buggy endpoint descriptors
|
||||
* Darwin: Do not use objc_registerThreadWithCollector after its deprecation
|
||||
* Darwin: Use C11 atomics on 10.12+ as the OS atomics are now deprecated
|
||||
* Linux: Support preallocating kernel memory for zerocopy USB
|
||||
* Linux: Deal with receiving POLLERR before all transfers have completed
|
||||
* Solaris: Add solaris backend
|
||||
* Windows: Add Visual Studio 2015 support
|
||||
* Windows: Add usbdk backend
|
||||
* Prevent attempts to recursively handle events
|
||||
* Fix race condition in handle_timeout()
|
||||
* Allow transferred argument to be optional in bulk APIs
|
||||
* Various other bug fixes and improvements
|
||||
|
||||
2015-09-13: v1.0.20
|
||||
* Add Haiku support
|
||||
* Fix multiple memory and resource leaks (#16, #52, #76, #81)
|
||||
* Fix possible deadlock when executing transfer callback
|
||||
* New libusb_free_pollfds() API
|
||||
* Darwin: Fix devices not being detected on OS X 10.8 (#48)
|
||||
* Linux: Allow larger isochronous transfer submission (#23)
|
||||
* Windows: Fix broken builds Cygwin/MinGW builds and compiler warnings
|
||||
* Windows: Fix broken bus number lookup
|
||||
* Windows: Improve submission of control requests for composite devices
|
||||
* Examples: Add two-stage load support to fxload (#12)
|
||||
* Correctly report cancellations due to timeouts
|
||||
* Improve efficiency of event handling
|
||||
* Improve speed of transfer submission in multi-threaded environments
|
||||
* Various other bug fixes and improvements
|
||||
The (#xx) numbers are libusb issue numbers, see ie:
|
||||
https://github.com/libusb/libusb/issues/16
|
||||
|
||||
2014-05-30: v1.0.19
|
||||
* Add support for USB bulk streams on Linux and Mac OS X (#11)
|
||||
* Windows: Add AMD and Intel USB-3.0 root hub support
|
||||
* Windows: Fix USB 3.0 speed detection on Windows 8 or later (#10)
|
||||
* Added Russian translation for libusb_strerror strings
|
||||
* All: Various small fixes and cleanups
|
||||
|
||||
2014-01-25: v1.0.18
|
||||
* Fix multiple memory leaks
|
||||
* Fix a crash when HID transfers return no data on Windows
|
||||
* Ensure all pending events are consumed
|
||||
* Improve Android and ucLinux support
|
||||
* Multiple Windows improvements (error logging, VS2013, VIA xHCI support)
|
||||
* Multiple OS X improvements (broken compilation, SIGFPE, 64bit support)
|
||||
|
||||
2013-09-06: v1.0.17
|
||||
* Hotplug callbacks now always get passed a libusb_context, even if it is
|
||||
the default context. Previously NULL would be passed for the default context,
|
||||
but since the first context created is the default context, and most apps
|
||||
use only 1 context, this meant that apps explicitly creating a context would
|
||||
still get passed NULL
|
||||
* Android: Add .mk files to build with the Android NDK
|
||||
* Darwin: Add Xcode project
|
||||
* Darwin: Fix crash on unplug (#121)
|
||||
* Linux: Fix hang (deadlock) on libusb_exit
|
||||
* Linux: Fix libusb build failure with --disable-udev (#124)
|
||||
* Linux: Fix libusb_get_device_list() hang with --disable-udev (#130)
|
||||
* OpenBSD: Update OpenBSD backend with support for control transfers to
|
||||
non-ugen(4) devices and make get_configuration() no longer generate I/O.
|
||||
Note that using this libusb version on OpenBSD requires using
|
||||
OpenBSD 5.3-current or later. Users of older OpenBSD versions are advised
|
||||
to stay with the libusb shipped with OpenBSD (mpi)
|
||||
* Windows: fix libusb_dll_2010.vcxproj link errors (#129)
|
||||
* Various other bug fixes and improvements
|
||||
|
||||
2013-07-11: v1.0.16
|
||||
* Add hotplug support for Darwin and Linux (#9)
|
||||
* Add superspeed endpoint companion descriptor support (#15)
|
||||
* Add BOS descriptor support (#15)
|
||||
* Make descriptor parsing code more robust
|
||||
* New libusb_get_port_numbers API, this is libusb_get_port_path without
|
||||
the unnecessary context parameter, libusb_get_port_path is now deprecated
|
||||
* New libusb_strerror API (#14)
|
||||
* New libusb_set_auto_detach_kernel_driver API (#17)
|
||||
* Improve topology API docs (#95)
|
||||
* Logging now use a single write call per log-message, avoiding log-message
|
||||
"interlacing" when using multiple threads.
|
||||
* Android: use Android logging when building on Android (#101)
|
||||
* Darwin: make libusb_reset reenumerate device on descriptors change (#89)
|
||||
* Darwin: add support for the LIBUSB_TRANSFER_ADD_ZERO_PACKET flag (#91)
|
||||
* Darwin: add a device cache (#112, #114)
|
||||
* Examples: Add sam3u_benchmark isochronous example by Harald Welte (#109)
|
||||
* Many other bug fixes and improvements
|
||||
The (#xx) numbers are libusbx issue numbers, see ie:
|
||||
https://github.com/libusbx/libusbx/issues/9
|
||||
|
||||
2013-04-15: v1.0.15
|
||||
* Improve transfer cancellation and avoid short read failures on broken descriptors
|
||||
* Filter out 8-bit characters in libusb_get_string_descriptor_ascii()
|
||||
* Add WinCE support
|
||||
* Add library stress tests
|
||||
* Add Cypress FX3 firmware upload support for fxload sample
|
||||
* Add HID and kernel driver detach support capabilities detection
|
||||
* Add SuperSpeed detection on OS X
|
||||
* Fix bInterval value interpretation on OS X
|
||||
* Fix issues with autoclaim, composite HID devices, interface autoclaim and
|
||||
early abort in libusb_close() on Windows. Also add VS2012 solution files.
|
||||
* Improve fd event handling on Linux
|
||||
* Other bug fixes and improvements
|
||||
|
||||
2012-09-26: v1.0.14
|
||||
* Reverts the previous API change with regards to bMaxPower.
|
||||
If this doesn't matter to you, you are encouraged to keep using v1.0.13,
|
||||
as it will use the same attribute as v2.0, to be released soon.
|
||||
* Note that LIBUSB_API_VERSION is *decreased* to 0x010000FF and the previous
|
||||
guidelines with regards to concurrent use of MaxPower/bMaxPower still apply.
|
||||
|
||||
2012-09-20: v1.0.13
|
||||
* [MAJOR] Fix a typo in the API with struct libusb_config_descriptor where
|
||||
MaxPower was used instead of bMaxPower, as defined in the specs. If your
|
||||
application was accessing the MaxPower attribute, and you need to maintain
|
||||
compatibility with libusb or older versions, see APPENDIX A below.
|
||||
* Fix broken support for the 0.1 -> 1.0 libusb-compat layer
|
||||
* Fix unwanted cancellation of pending timeouts as well as major timeout related bugs
|
||||
* Fix handling of HID and composite devices on Windows
|
||||
* Introduce LIBUSB_API_VERSION macro
|
||||
* Add Cypress FX/FX2 firmware upload sample, based on fxload from
|
||||
http://linux-hotplug.sourceforge.net
|
||||
* Add libusb0 (libusb-win32) and libusbK driver support on Windows. Note that while
|
||||
the drivers allow it, isochronous transfers are not supported yet in libusb. Also
|
||||
not supported yet is the use of libusb-win32 filter drivers on composite interfaces
|
||||
* Add support for the new get_capabilities ioctl on Linux and avoid unnecessary
|
||||
splitting of bulk transfers
|
||||
* Improve support for newer Intel and Renesas USB 3.0 controllers on Windows
|
||||
* Harmonize the device number for root hubs across platforms
|
||||
* Other bug fixes and improvements
|
||||
|
||||
2012-06-15: v1.0.12
|
||||
* Fix a potential major regression with pthread on Linux
|
||||
* Fix missing thread ID from debug log output on cygwin
|
||||
* Fix possible crash when using longjmp and MinGW's gcc 4.6
|
||||
* Add topology calls: libusb_get_port_number(), libusb_get_parent() & libusb_get_port_path()
|
||||
* Add toggleable debug, using libusb_set_debug() or the LIBUSB_DEBUG environment variable
|
||||
* Define log levels in libusb.h and set timestamp origin to first libusb_init() call
|
||||
* All logging is now sent to to stderr (info was sent to stdout previously)
|
||||
* Update log messages severity and avoid polluting log output on OS-X
|
||||
* Add HID driver support on Windows
|
||||
* Enable interchangeability of MSVC and MinGW DLLs
|
||||
* Additional bug fixes and improvements
|
||||
|
||||
2012-05-08: v1.0.11
|
||||
* Revert removal of critical Windows event handling that was introduced in 1.0.10
|
||||
* Fix a possible deadlock in Windows when submitting transfers
|
||||
* Add timestamped logging
|
||||
* Add NetBSD support (experimental) and BSD libusb_get_device_speed() data
|
||||
* Add bootstrap.sh alongside autogen.sh (bootstrap.sh doesn't invoke configure)
|
||||
* Search for device nodes in /dev for Android support
|
||||
* Other bug fixes
|
||||
|
||||
2012-04-17: v1.0.10
|
||||
* Public release
|
||||
* Add libusb_get_version
|
||||
* Add Visual Studio 2010 project files
|
||||
* Some Windows code cleanup
|
||||
* Fix xusb sample warnings
|
||||
|
||||
2012-04-02: v1.0.9
|
||||
* First libusbx release
|
||||
* Add libusb_get_device_speed (all, except BSD) and libusb_error_name
|
||||
* Add Windows support (WinUSB driver only)
|
||||
* Add OpenBSD support
|
||||
* Add xusb sample
|
||||
* Tons of bug fixes
|
||||
|
||||
2010-05-07: v1.0.8
|
||||
* Bug fixes
|
||||
|
||||
2010-04-19: v1.0.7
|
||||
* Bug fixes and documentation tweaks
|
||||
* Add more interface class definitions
|
||||
|
||||
2009-11-22: v1.0.6
|
||||
* Bug fixes
|
||||
* Increase libusb_handle_events() timeout to 60s for powersaving
|
||||
|
||||
2009-11-15: v1.0.5
|
||||
* Use timerfd when available for timer management
|
||||
* Small fixes/updates
|
||||
|
||||
2009-11-06: v1.0.4 release
|
||||
* Bug fixes including transfer locking to fix some potential threading races
|
||||
* More flexibility with clock types on Linux
|
||||
* Use new bulk continuation tracking in Linux 2.6.32 for improved handling
|
||||
of short/failed transfers
|
||||
|
||||
2009-08-27: v1.0.3 release
|
||||
* Bug fixes
|
||||
* Add libusb_get_max_iso_packet_size()
|
||||
|
||||
2009-06-13: v1.0.2 release
|
||||
* Bug fixes
|
||||
|
||||
2009-05-12: v1.0.1 release
|
||||
* Bug fixes
|
||||
* Darwin backend
|
||||
|
||||
2008-12-13: v1.0.0 release
|
||||
* Bug fixes
|
||||
|
||||
2008-11-21: v0.9.4 release
|
||||
* Bug fixes
|
||||
* Add libusb_attach_kernel_driver()
|
||||
|
||||
2008-08-23: v0.9.3 release
|
||||
* Bug fixes
|
||||
|
||||
2008-07-19: v0.9.2 release
|
||||
* Bug fixes
|
||||
|
||||
2008-06-28: v0.9.1 release
|
||||
* Bug fixes
|
||||
* Introduce contexts to the API
|
||||
* Compatibility with new Linux kernel features
|
||||
|
||||
2008-05-25: v0.9.0 release
|
||||
* First libusb-1.0 beta release
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
APPENDIX A - How to maintain code compatibility with versions of libusb and
|
||||
libusb that use MaxPower:
|
||||
|
||||
If you must to maintain compatibility with versions of the library that aren't
|
||||
using the bMaxPower attribute in struct libusb_config_descriptor, the
|
||||
recommended way is to use the new LIBUSB_API_VERSION macro with an #ifdef.
|
||||
For instance, if your code was written as follows:
|
||||
|
||||
if (dev->config[0].MaxPower < 250)
|
||||
|
||||
Then you should modify it to have:
|
||||
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000100)
|
||||
if (dev->config[0].bMaxPower < 250)
|
||||
#else
|
||||
if (dev->config[0].MaxPower < 250)
|
||||
#endif
|
||||
73
externals/libusb/libusb/INSTALL_WIN.txt
vendored
Executable file
73
externals/libusb/libusb/INSTALL_WIN.txt
vendored
Executable file
@@ -0,0 +1,73 @@
|
||||
Installation Instructions for Windows
|
||||
*************************************
|
||||
|
||||
If you are compiling for MinGW or cygwin, please refer to the INSTALL file.
|
||||
|
||||
If you are using Microsoft Visual Studio:
|
||||
- Open the relevant solution file in /msvc:
|
||||
libusb.dsw for MSVC6, libusb_2005.sln for Visual Studio 2005 or 2008,
|
||||
libusb_2010.sln for Visual Studio 2010,
|
||||
libusb_2012.sln for Visual Studio 2012 or later,
|
||||
libusb_wince.sln for Windows CE support in Visual Studio 2005.
|
||||
- If you want to debug the library, uncomment the ENABLE_DEBUG_LOGGING define
|
||||
in msvc\config.h
|
||||
- Select your configuration and compile the project
|
||||
|
||||
Note that if you are using Visual Studio Express, you may have to install the
|
||||
Windows SDK to be able to compile the 64 bit version of the library.
|
||||
|
||||
If you are using the freely available Windows DDK/WDK (Driver Development Kit)
|
||||
- If you want to debug the library, uncomment the ENABLE_DEBUG_LOGGING define
|
||||
in msvc\config.h
|
||||
- Open one of the relevant Free Build or Checked Build prompt for your target
|
||||
platform
|
||||
- Navigate to the msvc\ directory where the ddk_build.cmd file is located, and
|
||||
run 'ddk_build'
|
||||
- To produce a DLL rather than a static library, use: 'ddk_build DLL'
|
||||
- To produce a static library that uses LIBCMT[d] instead of MSVCRT[d] (/MT[d]
|
||||
vs /MD[d] in Visual Studio) use: 'ddk_build /MT'
|
||||
|
||||
Note that using the Windows DDK, it is possible to compile both the 32 and 64
|
||||
bit versions of the library.
|
||||
|
||||
If you are building for Windows CE then you will need the Windows CE Standard 5.00 SDK.
|
||||
|
||||
Destination directories
|
||||
***********************
|
||||
|
||||
The 32 bit binaries compiled either from Visual Studio or the DDK are placed in
|
||||
a Win32\ directory at the root of the library
|
||||
The 64 bit binaries are placed in an x64\ directory
|
||||
Windows CE binaries are placed in one of the following directories, depending
|
||||
on the target processor: ARMV4I, MIPSII, MIPSII_FP, MIPSIV, MIPSIV_FP, SH4 or x86.
|
||||
|
||||
|
||||
Troubleshooting
|
||||
***************
|
||||
|
||||
If the compilation process complains about missing libraries, ensure that the
|
||||
default library paths for your project points to the relevant directories.
|
||||
If needed, these libraries can be obtained by installing either the latest
|
||||
Windows SDK or the DDK (Links provided at the end of this file).
|
||||
|
||||
For Windows CE it is necessary to install the CE USB Kernel Wrapper driver for
|
||||
libusb to function on a device.
|
||||
|
||||
Links
|
||||
*****
|
||||
|
||||
Additional information related to the Windows backend:
|
||||
http://windows.libusb.info
|
||||
|
||||
Latest Windows Driver (Development) Kit (WDK):
|
||||
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=36a2630f-5d56-43b5-b996-7633f2ec14ff
|
||||
|
||||
Latest Microsoft Windows SDK:
|
||||
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505
|
||||
|
||||
Windows CE Standard 5.00 SDK:
|
||||
http://www.microsoft.com/en-gb/download/details.aspx?id=17310
|
||||
|
||||
Windows CE USB Kernel Wrapper Driver:
|
||||
https://github.com/RealVNC/CEUSBKWrapper
|
||||
|
||||
28
externals/libusb/libusb/Makefile.am
vendored
Executable file
28
externals/libusb/libusb/Makefile.am
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
DISTCLEANFILES = libusb-1.0.pc
|
||||
EXTRA_DIST = TODO PORTING msvc libusb/libusb-1.0.def libusb/version_nano.h \
|
||||
examples/getopt/getopt.c examples/getopt/getopt1.c examples/getopt/getopt.h \
|
||||
android Xcode
|
||||
SUBDIRS = libusb doc
|
||||
|
||||
if BUILD_EXAMPLES
|
||||
SUBDIRS += examples
|
||||
endif
|
||||
|
||||
if BUILD_TESTS
|
||||
SUBDIRS += tests
|
||||
endif
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfig_DATA=libusb-1.0.pc
|
||||
|
||||
.PHONY: dist-up
|
||||
|
||||
reldir = .release/$(distdir)
|
||||
dist-up: dist
|
||||
rm -rf $(reldir)
|
||||
mkdir -p $(reldir)
|
||||
cp $(distdir).tar.bz2 $(reldir)
|
||||
rsync -rv $(reldir) frs.sourceforge.net:/home/frs/project/l/li/libusb/libusb-1.0/
|
||||
rm -rf $(reldir)
|
||||
2
externals/libusb/libusb/NEWS
vendored
Executable file
2
externals/libusb/libusb/NEWS
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
For the latest libusb news, please refer to the ChangeLog file, or visit:
|
||||
http://libusb.info
|
||||
94
externals/libusb/libusb/PORTING
vendored
Executable file
94
externals/libusb/libusb/PORTING
vendored
Executable file
@@ -0,0 +1,94 @@
|
||||
PORTING LIBUSB TO OTHER PLATFORMS
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document is aimed at developers wishing to port libusb to unsupported
|
||||
platforms. I believe the libusb API is OS-independent, so by supporting
|
||||
multiple operating systems we pave the way for cross-platform USB device
|
||||
drivers.
|
||||
|
||||
Implementation-wise, the basic idea is that you provide an interface to
|
||||
libusb's internal "backend" API, which performs the appropriate operations on
|
||||
your target platform.
|
||||
|
||||
In terms of USB I/O, your backend provides functionality to submit
|
||||
asynchronous transfers (synchronous transfers are implemented in the higher
|
||||
layers, based on the async interface). Your backend must also provide
|
||||
functionality to cancel those transfers.
|
||||
|
||||
Your backend must also provide an event handling function to "reap" ongoing
|
||||
transfers and process their results.
|
||||
|
||||
The backend must also provide standard functions for other USB operations,
|
||||
e.g. setting configuration, obtaining descriptors, etc.
|
||||
|
||||
|
||||
File descriptors for I/O polling
|
||||
================================
|
||||
|
||||
For libusb to work, your event handling function obviously needs to be called
|
||||
at various points in time. Your backend must provide a set of file descriptors
|
||||
which libusb and its users can pass to poll() or select() to determine when
|
||||
it is time to call the event handling function.
|
||||
|
||||
On Linux, this is easy: the usbfs kernel interface exposes a file descriptor
|
||||
which can be passed to poll(). If something similar is not true for your
|
||||
platform, you can emulate this using an internal library thread to reap I/O as
|
||||
necessary, and a pipe() with the main library to raise events. The file
|
||||
descriptor of the pipe can then be provided to libusb as an event source.
|
||||
|
||||
|
||||
Interface semantics and documentation
|
||||
=====================================
|
||||
|
||||
Documentation of the backend interface can be found in libusbi.h inside the
|
||||
usbi_os_backend structure definition.
|
||||
|
||||
Your implementations of these functions will need to call various internal
|
||||
libusb functions, prefixed with "usbi_". Documentation for these functions
|
||||
can be found in the .c files where they are implemented.
|
||||
|
||||
You probably want to skim over *all* the documentation before starting your
|
||||
implementation. For example, you probably need to allocate and store private
|
||||
OS-specific data for device handles, but the documentation for the mechanism
|
||||
for doing so is probably not the first thing you will see.
|
||||
|
||||
The Linux backend acts as a good example - view it as a reference
|
||||
implementation which you should try to match the behaviour of.
|
||||
|
||||
|
||||
Getting started
|
||||
===============
|
||||
|
||||
1. Modify configure.ac to detect your platform appropriately (see the OS_LINUX
|
||||
stuff for an example).
|
||||
|
||||
2. Implement your backend in the libusb/os/ directory, modifying
|
||||
libusb/os/Makefile.am appropriately.
|
||||
|
||||
3. Add preprocessor logic to the top of libusb/core.c to statically assign the
|
||||
right usbi_backend for your platform.
|
||||
|
||||
4. Produce and test your implementation.
|
||||
|
||||
5. Send your implementation to libusb-devel mailing list.
|
||||
|
||||
|
||||
Implementation difficulties? Questions?
|
||||
=======================================
|
||||
|
||||
If you encounter difficulties porting libusb to your platform, please raise
|
||||
these issues on the libusb-devel mailing list. Where possible and sensible, I
|
||||
am interested in solving problems preventing libusb from operating on other
|
||||
platforms.
|
||||
|
||||
The libusb-devel mailing list is also a good place to ask questions and
|
||||
make suggestions about the internal API. Hopefully we can produce some
|
||||
better documentation based on your questions and other input.
|
||||
|
||||
You are encouraged to get involved in the process; if the library needs
|
||||
some infrastructure additions/modifications to better support your platform,
|
||||
you are encouraged to make such changes (in cleanly distinct patch
|
||||
submissions). Even if you do not make such changes yourself, please do raise
|
||||
the issues on the mailing list at the very minimum.
|
||||
32
externals/libusb/libusb/README
vendored
Executable file
32
externals/libusb/libusb/README
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
# libusb
|
||||
|
||||
[](https://travis-ci.org/libusb/libusb)
|
||||
[](https://ci.appveyor.com/project/LudovicRousseau/libusb)
|
||||
[](https://scan.coverity.com/projects/libusb-libusb)
|
||||
|
||||
libusb is a library for USB device access from Linux, macOS,
|
||||
Windows, OpenBSD/NetBSD and Haiku userspace.
|
||||
It is written in C (Haiku backend in C++) and licensed under the GNU
|
||||
Lesser General Public License version 2.1 or, at your option, any later
|
||||
version (see [COPYING](COPYING)).
|
||||
|
||||
libusb is abstracted internally in such a way that it can hopefully
|
||||
be ported to other operating systems. Please see the [PORTING](PORTING)
|
||||
file for more information.
|
||||
|
||||
libusb homepage:
|
||||
http://libusb.info/
|
||||
|
||||
Developers will wish to consult the API documentation:
|
||||
http://api.libusb.info
|
||||
|
||||
Use the mailing list for questions, comments, etc:
|
||||
http://mailing-list.libusb.info
|
||||
|
||||
- Hans de Goede <hdegoede@redhat.com>
|
||||
- Xiaofan Chen <xiaofanc@gmail.com>
|
||||
- Ludovic Rousseau <ludovic.rousseau@gmail.com>
|
||||
- Nathan Hjelm <hjelmn@cs.unm.edu>
|
||||
- Chris Dickens <christopher.a.dickens@gmail.com>
|
||||
|
||||
(Please use the mailing list rather than mailing developers directly)
|
||||
41
externals/libusb/libusb/README.git
vendored
Executable file
41
externals/libusb/libusb/README.git
vendored
Executable file
@@ -0,0 +1,41 @@
|
||||
Notes related to git compilation:
|
||||
--------------------------------
|
||||
|
||||
If you retrieved the libusb repository from git and are using a gcc based
|
||||
toolchain, be mindful that you should have the autotools installed (autoconf,
|
||||
automake) and will need to run either ./autogen.sh or ./bootstrap.sh to produce
|
||||
the configure file.
|
||||
|
||||
The difference between autogen.sh and bootstrap.sh is that the former invokes
|
||||
configure with a default set of options, and will therefore generate a Makefile,
|
||||
whereas the latter does not invoke configure at all. If using autogen.sh, note
|
||||
that you can also append options, that will be passed as is to configure.
|
||||
|
||||
OS X-specific notes:
|
||||
-------------------
|
||||
|
||||
Starting with Xcode 4.3, neither Xcode.app nor the Xcode 'command line tools'
|
||||
includes autotools and so running either autogen.sh or bootstrap.sh will result
|
||||
in the message:
|
||||
|
||||
libtoolize or glibtoolize was not found! Please install libtool.
|
||||
|
||||
To proceed, you must find and install it from somewhere.
|
||||
|
||||
Alternatively, you can use the Xcode project at Xcode/libusb.xcodeproj.
|
||||
|
||||
Notes related to submitting new developments:
|
||||
--------------------------------------------
|
||||
|
||||
If you submit a new development to libusb (eg: new backend), that is unlikely
|
||||
to fit in a couple of small patches, we would kindly suggest that you create a
|
||||
public account on github, if you don't have one already, and then fork a new
|
||||
libusb repository under this account from https://github.com/libusb/libusb.
|
||||
|
||||
Then you can create a git branch for your work, that we will be able to better
|
||||
reference and test.
|
||||
|
||||
We also suggest that, if you are planning to bring in a large development, you
|
||||
try to involve the libusb community early by letting the mailing list know, as
|
||||
you may find that other people might be eager to help you out.
|
||||
See http://mailing-list.libusb.info for details on how to join the mailing list.
|
||||
32
externals/libusb/libusb/README.md
vendored
Executable file
32
externals/libusb/libusb/README.md
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
# libusb
|
||||
|
||||
[](https://travis-ci.org/libusb/libusb)
|
||||
[](https://ci.appveyor.com/project/LudovicRousseau/libusb)
|
||||
[](https://scan.coverity.com/projects/libusb-libusb)
|
||||
|
||||
libusb is a library for USB device access from Linux, macOS,
|
||||
Windows, OpenBSD/NetBSD and Haiku userspace.
|
||||
It is written in C (Haiku backend in C++) and licensed under the GNU
|
||||
Lesser General Public License version 2.1 or, at your option, any later
|
||||
version (see [COPYING](COPYING)).
|
||||
|
||||
libusb is abstracted internally in such a way that it can hopefully
|
||||
be ported to other operating systems. Please see the [PORTING](PORTING)
|
||||
file for more information.
|
||||
|
||||
libusb homepage:
|
||||
http://libusb.info/
|
||||
|
||||
Developers will wish to consult the API documentation:
|
||||
http://api.libusb.info
|
||||
|
||||
Use the mailing list for questions, comments, etc:
|
||||
http://mailing-list.libusb.info
|
||||
|
||||
- Hans de Goede <hdegoede@redhat.com>
|
||||
- Xiaofan Chen <xiaofanc@gmail.com>
|
||||
- Ludovic Rousseau <ludovic.rousseau@gmail.com>
|
||||
- Nathan Hjelm <hjelmn@cs.unm.edu>
|
||||
- Chris Dickens <christopher.a.dickens@gmail.com>
|
||||
|
||||
(Please use the mailing list rather than mailing developers directly)
|
||||
2
externals/libusb/libusb/TODO
vendored
Executable file
2
externals/libusb/libusb/TODO
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
Please see the libusb roadmap by visiting:
|
||||
https://github.com/libusb/libusb/milestones?direction=asc&sort=due_date&state=open
|
||||
61
externals/libusb/libusb/Xcode/common.xcconfig
vendored
Executable file
61
externals/libusb/libusb/Xcode/common.xcconfig
vendored
Executable file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// libusb Xcode configuration file
|
||||
// Copyright © 2012 Pete Batard <pete@akeo.ie>
|
||||
// For more information, please visit: <http://libusb.info>
|
||||
//
|
||||
// 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
|
||||
|
||||
// libusb does not follow C99 strict aliasing rules, so disable it.
|
||||
GCC_STRICT_ALIASING = NO
|
||||
|
||||
// Use C99 dialect.
|
||||
GCC_C_LANGUAGE_STANDARD = c99
|
||||
|
||||
// Don't search user paths with <> style #includes.
|
||||
ALWAYS_SEARCH_USER_PATHS = NO
|
||||
|
||||
// Compiler warnings.
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES
|
||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES
|
||||
GCC_WARN_SHADOW = YES
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES
|
||||
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES
|
||||
GCC_WARN_UNUSED_FUNCTION = YES
|
||||
GCC_WARN_UNUSED_LABEL = YES
|
||||
GCC_WARN_UNUSED_VARIABLE = YES
|
||||
GCC_WARN_UNUSED_PARAMETER = YES
|
||||
CLANG_WARN_EMPTY_BODY = YES
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES
|
||||
CLANG_WARN_ENUM_CONVERSION = YES
|
||||
CLANG_WARN_INT_CONVERSION = YES
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES
|
||||
CLANG_WARN_BOOL_CONVERSION = YES
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES
|
||||
CLANG_WARN_FLOAT_CONVERSION = YES
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES
|
||||
CLANG_WARN_INFINITE_RECURSION = YES
|
||||
CLANG_WARN_ASSIGN_ENUM = YES
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES
|
||||
CLANG_WARN_COMMA = YES
|
||||
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES
|
||||
|
||||
// Static analyzer warnings.
|
||||
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES
|
||||
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES
|
||||
25
externals/libusb/libusb/Xcode/config.h
vendored
Executable file
25
externals/libusb/libusb/Xcode/config.h
vendored
Executable file
@@ -0,0 +1,25 @@
|
||||
/* config.h. Manually generated for Xcode. */
|
||||
|
||||
/* Default visibility */
|
||||
#define DEFAULT_VISIBILITY /**/
|
||||
|
||||
/* Message logging */
|
||||
#define ENABLE_LOGGING 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Darwin backend */
|
||||
#define OS_DARWIN 1
|
||||
|
||||
/* type of second poll() argument */
|
||||
#define POLL_NFDS_TYPE nfds_t
|
||||
|
||||
/* Use POSIX Threads */
|
||||
#define THREADS_POSIX 1
|
||||
|
||||
/* Use GNU extensions */
|
||||
#define _GNU_SOURCE 1
|
||||
29
externals/libusb/libusb/Xcode/debug.xcconfig
vendored
Executable file
29
externals/libusb/libusb/Xcode/debug.xcconfig
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// libusb Xcode configuration file
|
||||
// Copyright © 2012 Pete Batard <pete@akeo.ie>
|
||||
// For more information, please visit: <http://libusb.info>
|
||||
//
|
||||
// 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 "common.xcconfig"
|
||||
|
||||
// Embed debug symbols in binary itself.
|
||||
DEBUG_INFORMATION_FORMAT = dwarf
|
||||
|
||||
// No optimizations in debug.
|
||||
GCC_OPTIMIZATION_LEVEL = 0
|
||||
|
||||
//
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1
|
||||
21
externals/libusb/libusb/Xcode/libusb.xcconfig
vendored
Executable file
21
externals/libusb/libusb/Xcode/libusb.xcconfig
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// libusb Xcode configuration file
|
||||
// Copyright © 2012 Pete Batard <pete@akeo.ie>
|
||||
// For more information, please visit: <http://libusb.info>
|
||||
//
|
||||
// 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
|
||||
|
||||
PRODUCT_NAME = libusb-1.0.0
|
||||
LD_DYLIB_INSTALL_NAME = @rpath/libusb-1.0.0.dylib
|
||||
959
externals/libusb/libusb/Xcode/libusb.xcodeproj/project.pbxproj
vendored
Executable file
959
externals/libusb/libusb/Xcode/libusb.xcodeproj/project.pbxproj
vendored
Executable file
@@ -0,0 +1,959 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 45;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
008FC0321628BC9400BC5BE2 /* all */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = 008FC0331628BC9400BC5BE2 /* Build configuration list for PBXAggregateTarget "all" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
006AD4281C8C5BBC007F8C6A /* PBXTargetDependency */,
|
||||
008FC0371628BC9A00BC5BE2 /* PBXTargetDependency */,
|
||||
008FC0391628BC9A00BC5BE2 /* PBXTargetDependency */,
|
||||
008FC03B1628BC9A00BC5BE2 /* PBXTargetDependency */,
|
||||
008FC03D1628BC9A00BC5BE2 /* PBXTargetDependency */,
|
||||
008FC03F1628BC9A00BC5BE2 /* PBXTargetDependency */,
|
||||
008FC0411628BC9A00BC5BE2 /* PBXTargetDependency */,
|
||||
);
|
||||
name = all;
|
||||
productName = all;
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
006AD4241C8C5AAE007F8C6A /* hotplugtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 006AD4231C8C5AAE007F8C6A /* hotplugtest.c */; };
|
||||
006AD4251C8C5AC4007F8C6A /* hotplugtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 006AD4231C8C5AAE007F8C6A /* hotplugtest.c */; };
|
||||
006AD4261C8C5AD9007F8C6A /* libusb-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */; };
|
||||
008FBF861628B7E800BC5BE2 /* core.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBF541628B7E800BC5BE2 /* core.c */; };
|
||||
008FBF871628B7E800BC5BE2 /* descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBF551628B7E800BC5BE2 /* descriptor.c */; };
|
||||
008FBF881628B7E800BC5BE2 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBF561628B7E800BC5BE2 /* io.c */; };
|
||||
008FBF891628B7E800BC5BE2 /* libusb.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF5A1628B7E800BC5BE2 /* libusb.h */; };
|
||||
008FBF901628B7E800BC5BE2 /* libusbi.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF671628B7E800BC5BE2 /* libusbi.h */; };
|
||||
008FBF921628B7E800BC5BE2 /* darwin_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBF6C1628B7E800BC5BE2 /* darwin_usb.c */; };
|
||||
008FBF931628B7E800BC5BE2 /* darwin_usb.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF6D1628B7E800BC5BE2 /* darwin_usb.h */; };
|
||||
008FBF971628B7E800BC5BE2 /* poll_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF711628B7E800BC5BE2 /* poll_posix.h */; };
|
||||
008FBF9A1628B7E800BC5BE2 /* threads_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBF741628B7E800BC5BE2 /* threads_posix.c */; };
|
||||
008FBF9B1628B7E800BC5BE2 /* threads_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF751628B7E800BC5BE2 /* threads_posix.h */; };
|
||||
008FBFA01628B7E800BC5BE2 /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBF7A1628B7E800BC5BE2 /* sync.c */; };
|
||||
008FBFA11628B7E800BC5BE2 /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF7B1628B7E800BC5BE2 /* version.h */; };
|
||||
008FBFA21628B7E800BC5BE2 /* version_nano.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBF7C1628B7E800BC5BE2 /* version_nano.h */; };
|
||||
008FBFA51628B84200BC5BE2 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 008FBFA41628B84200BC5BE2 /* config.h */; };
|
||||
008FBFA71628B87000BC5BE2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBFA61628B87000BC5BE2 /* CoreFoundation.framework */; };
|
||||
008FBFA91628B88000BC5BE2 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBFA81628B88000BC5BE2 /* IOKit.framework */; };
|
||||
008FBFAB1628B8CB00BC5BE2 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBFAA1628B8CB00BC5BE2 /* libobjc.dylib */; };
|
||||
008FBFEF1628BA3500BC5BE2 /* xusb.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBFED1628BA0E00BC5BE2 /* xusb.c */; };
|
||||
008FBFF01628BA3A00BC5BE2 /* libusb-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */; };
|
||||
008FBFFF1628BB9600BC5BE2 /* dpfp.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBFD71628BA0E00BC5BE2 /* dpfp.c */; };
|
||||
008FC0001628BBCD00BC5BE2 /* libusb-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */; };
|
||||
008FC00F1628BBE400BC5BE2 /* dpfp_threaded.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBFDB1628BA0E00BC5BE2 /* dpfp_threaded.c */; };
|
||||
008FC0101628BBE900BC5BE2 /* libusb-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */; };
|
||||
008FC01F1628BC1500BC5BE2 /* fxload.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBFE11628BA0E00BC5BE2 /* fxload.c */; };
|
||||
008FC0201628BC1B00BC5BE2 /* libusb-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */; };
|
||||
008FC0211628BC5200BC5BE2 /* ezusb.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBFDC1628BA0E00BC5BE2 /* ezusb.c */; };
|
||||
008FC0301628BC7400BC5BE2 /* listdevs.c in Sources */ = {isa = PBXBuildFile; fileRef = 008FBFE71628BA0E00BC5BE2 /* listdevs.c */; };
|
||||
008FC0311628BC7800BC5BE2 /* libusb-1.0.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */; };
|
||||
1438D77A17A2ED9F00166101 /* hotplug.c in Sources */ = {isa = PBXBuildFile; fileRef = 1438D77817A2ED9F00166101 /* hotplug.c */; };
|
||||
1438D77B17A2ED9F00166101 /* hotplug.h in Headers */ = {isa = PBXBuildFile; fileRef = 1438D77917A2ED9F00166101 /* hotplug.h */; };
|
||||
1438D77D17A2EDCD00166101 /* poll_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = 1438D77C17A2EDCD00166101 /* poll_posix.c */; };
|
||||
1438D77F17A2F0EA00166101 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 1438D77E17A2F0EA00166101 /* strerror.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
006AD4271C8C5BBC007F8C6A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 006AD41B1C8C5A90007F8C6A;
|
||||
remoteInfo = hotplugtest;
|
||||
};
|
||||
008FC0361628BC9A00BC5BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBF301628B79300BC5BE2;
|
||||
remoteInfo = libusb;
|
||||
};
|
||||
008FC0381628BC9A00BC5BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBFBC1628B9FE00BC5BE2;
|
||||
remoteInfo = xusb;
|
||||
};
|
||||
008FC03A1628BC9A00BC5BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBFF41628BB8B00BC5BE2;
|
||||
remoteInfo = dpfp;
|
||||
};
|
||||
008FC03C1628BC9A00BC5BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FC0041628BBDB00BC5BE2;
|
||||
remoteInfo = dpfp_threaded;
|
||||
};
|
||||
008FC03E1628BC9A00BC5BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FC0141628BC0300BC5BE2;
|
||||
remoteInfo = fxload;
|
||||
};
|
||||
008FC0401628BC9A00BC5BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FC0251628BC6B00BC5BE2;
|
||||
remoteInfo = listdevs;
|
||||
};
|
||||
1443EE8B1641926D007E0579 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBF301628B79300BC5BE2;
|
||||
remoteInfo = libusb;
|
||||
};
|
||||
1443EE8D16419273007E0579 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBF301628B79300BC5BE2;
|
||||
remoteInfo = libusb;
|
||||
};
|
||||
1443EE8F16419276007E0579 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBF301628B79300BC5BE2;
|
||||
remoteInfo = libusb;
|
||||
};
|
||||
1443EE911641927A007E0579 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBF301628B79300BC5BE2;
|
||||
remoteInfo = libusb;
|
||||
};
|
||||
1443EE931641927D007E0579 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 008FBF301628B79300BC5BE2;
|
||||
remoteInfo = libusb;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
006AD41A1C8C5A90007F8C6A /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
008FBFBB1628B9FE00BC5BE2 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
008FBFF31628BB8B00BC5BE2 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
008FC0031628BBDB00BC5BE2 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
008FC0131628BC0300BC5BE2 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
008FC0241628BC6B00BC5BE2 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
006AD41C1C8C5A90007F8C6A /* hotplugtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = hotplugtest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
006AD4231C8C5AAE007F8C6A /* hotplugtest.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = hotplugtest.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "libusb-1.0.0.dylib"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
008FBF541628B7E800BC5BE2 /* core.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = core.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF551628B7E800BC5BE2 /* descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = descriptor.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF561628B7E800BC5BE2 /* io.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF5A1628B7E800BC5BE2 /* libusb.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = libusb.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF671628B7E800BC5BE2 /* libusbi.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = libusbi.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF6C1628B7E800BC5BE2 /* darwin_usb.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = darwin_usb.c; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
008FBF6D1628B7E800BC5BE2 /* darwin_usb.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = darwin_usb.h; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||
008FBF711628B7E800BC5BE2 /* poll_posix.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = poll_posix.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF741628B7E800BC5BE2 /* threads_posix.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = threads_posix.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF751628B7E800BC5BE2 /* threads_posix.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = threads_posix.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF7A1628B7E800BC5BE2 /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = sync.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF7B1628B7E800BC5BE2 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBF7C1628B7E800BC5BE2 /* version_nano.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = version_nano.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFA41628B84200BC5BE2 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFA61628B87000BC5BE2 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
||||
008FBFA81628B88000BC5BE2 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
008FBFAA1628B8CB00BC5BE2 /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = usr/lib/libobjc.dylib; sourceTree = SDKROOT; };
|
||||
008FBFBD1628B9FE00BC5BE2 /* xusb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = xusb; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
008FBFD71628BA0E00BC5BE2 /* dpfp.c */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = dpfp.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFDB1628BA0E00BC5BE2 /* dpfp_threaded.c */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = dpfp_threaded.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFDC1628BA0E00BC5BE2 /* ezusb.c */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = ezusb.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFDD1628BA0E00BC5BE2 /* ezusb.h */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ezusb.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFE11628BA0E00BC5BE2 /* fxload.c */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = fxload.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFE71628BA0E00BC5BE2 /* listdevs.c */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = listdevs.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFED1628BA0E00BC5BE2 /* xusb.c */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = xusb.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
008FBFF51628BB8B00BC5BE2 /* dpfp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dpfp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
008FC0051628BBDB00BC5BE2 /* dpfp_threaded */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dpfp_threaded; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
008FC0151628BC0300BC5BE2 /* fxload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fxload; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
008FC0261628BC6B00BC5BE2 /* listdevs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = listdevs; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1438D77817A2ED9F00166101 /* hotplug.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = hotplug.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
1438D77917A2ED9F00166101 /* hotplug.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = hotplug.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
1438D77C17A2EDCD00166101 /* poll_posix.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = poll_posix.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
1438D77E17A2F0EA00166101 /* strerror.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.c; path = strerror.c; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
|
||||
1443EE8416417E63007E0579 /* common.xcconfig */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xcconfig; path = common.xcconfig; sourceTree = SOURCE_ROOT; tabWidth = 4; usesTabs = 1; };
|
||||
1443EE8516417E63007E0579 /* debug.xcconfig */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = SOURCE_ROOT; tabWidth = 4; usesTabs = 1; };
|
||||
1443EE8616417E63007E0579 /* libusb_debug.xcconfig */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xcconfig; path = libusb_debug.xcconfig; sourceTree = SOURCE_ROOT; tabWidth = 4; usesTabs = 1; };
|
||||
1443EE8716417E63007E0579 /* libusb.xcconfig */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xcconfig; path = libusb.xcconfig; sourceTree = SOURCE_ROOT; tabWidth = 4; usesTabs = 1; };
|
||||
1443EE8816417E63007E0579 /* release.xcconfig */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = SOURCE_ROOT; tabWidth = 4; usesTabs = 1; };
|
||||
1443EE8916417EA6007E0579 /* libusb_release.xcconfig */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xcconfig; path = libusb_release.xcconfig; sourceTree = SOURCE_ROOT; tabWidth = 4; usesTabs = 1; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
006AD4191C8C5A90007F8C6A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
006AD4261C8C5AD9007F8C6A /* libusb-1.0.0.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FBF2E1628B79300BC5BE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FBFAB1628B8CB00BC5BE2 /* libobjc.dylib in Frameworks */,
|
||||
008FBFA91628B88000BC5BE2 /* IOKit.framework in Frameworks */,
|
||||
008FBFA71628B87000BC5BE2 /* CoreFoundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FBFBA1628B9FE00BC5BE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FBFF01628BA3A00BC5BE2 /* libusb-1.0.0.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FBFF21628BB8B00BC5BE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC0001628BBCD00BC5BE2 /* libusb-1.0.0.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FC0021628BBDB00BC5BE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC0101628BBE900BC5BE2 /* libusb-1.0.0.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FC0121628BC0300BC5BE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC0201628BC1B00BC5BE2 /* libusb-1.0.0.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FC0231628BC6B00BC5BE2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC0311628BC7800BC5BE2 /* libusb-1.0.0.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
008FBF261628B79300BC5BE2 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1443EE8316417DE3007E0579 /* xcconfig */,
|
||||
008FBFA41628B84200BC5BE2 /* config.h */,
|
||||
008FBF3B1628B7E800BC5BE2 /* libusb */,
|
||||
008FBFC81628BA0E00BC5BE2 /* examples */,
|
||||
1443EE8A16419057007E0579 /* Apple */,
|
||||
008FBF321628B79300BC5BE2 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
008FBF321628B79300BC5BE2 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */,
|
||||
008FBFBD1628B9FE00BC5BE2 /* xusb */,
|
||||
008FBFF51628BB8B00BC5BE2 /* dpfp */,
|
||||
008FC0051628BBDB00BC5BE2 /* dpfp_threaded */,
|
||||
008FC0151628BC0300BC5BE2 /* fxload */,
|
||||
008FC0261628BC6B00BC5BE2 /* listdevs */,
|
||||
006AD41C1C8C5A90007F8C6A /* hotplugtest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
008FBF3B1628B7E800BC5BE2 /* libusb */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
008FBF541628B7E800BC5BE2 /* core.c */,
|
||||
008FBF551628B7E800BC5BE2 /* descriptor.c */,
|
||||
1438D77817A2ED9F00166101 /* hotplug.c */,
|
||||
1438D77917A2ED9F00166101 /* hotplug.h */,
|
||||
008FBF561628B7E800BC5BE2 /* io.c */,
|
||||
008FBF5A1628B7E800BC5BE2 /* libusb.h */,
|
||||
008FBF671628B7E800BC5BE2 /* libusbi.h */,
|
||||
008FBF6B1628B7E800BC5BE2 /* os */,
|
||||
1438D77E17A2F0EA00166101 /* strerror.c */,
|
||||
008FBF7A1628B7E800BC5BE2 /* sync.c */,
|
||||
008FBF7B1628B7E800BC5BE2 /* version.h */,
|
||||
008FBF7C1628B7E800BC5BE2 /* version_nano.h */,
|
||||
);
|
||||
name = libusb;
|
||||
path = ../libusb;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
008FBF6B1628B7E800BC5BE2 /* os */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
008FBF6C1628B7E800BC5BE2 /* darwin_usb.c */,
|
||||
008FBF6D1628B7E800BC5BE2 /* darwin_usb.h */,
|
||||
1438D77C17A2EDCD00166101 /* poll_posix.c */,
|
||||
008FBF711628B7E800BC5BE2 /* poll_posix.h */,
|
||||
008FBF741628B7E800BC5BE2 /* threads_posix.c */,
|
||||
008FBF751628B7E800BC5BE2 /* threads_posix.h */,
|
||||
);
|
||||
path = os;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
008FBFC81628BA0E00BC5BE2 /* examples */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
008FBFDB1628BA0E00BC5BE2 /* dpfp_threaded.c */,
|
||||
008FBFD71628BA0E00BC5BE2 /* dpfp.c */,
|
||||
008FBFDC1628BA0E00BC5BE2 /* ezusb.c */,
|
||||
008FBFDD1628BA0E00BC5BE2 /* ezusb.h */,
|
||||
008FBFE11628BA0E00BC5BE2 /* fxload.c */,
|
||||
006AD4231C8C5AAE007F8C6A /* hotplugtest.c */,
|
||||
008FBFE71628BA0E00BC5BE2 /* listdevs.c */,
|
||||
008FBFED1628BA0E00BC5BE2 /* xusb.c */,
|
||||
);
|
||||
name = examples;
|
||||
path = ../examples;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1443EE8316417DE3007E0579 /* xcconfig */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1443EE8416417E63007E0579 /* common.xcconfig */,
|
||||
1443EE8516417E63007E0579 /* debug.xcconfig */,
|
||||
1443EE8816417E63007E0579 /* release.xcconfig */,
|
||||
1443EE8716417E63007E0579 /* libusb.xcconfig */,
|
||||
1443EE8616417E63007E0579 /* libusb_debug.xcconfig */,
|
||||
1443EE8916417EA6007E0579 /* libusb_release.xcconfig */,
|
||||
);
|
||||
name = xcconfig;
|
||||
path = ../libusb;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1443EE8A16419057007E0579 /* Apple */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
008FBFAA1628B8CB00BC5BE2 /* libobjc.dylib */,
|
||||
008FBFA81628B88000BC5BE2 /* IOKit.framework */,
|
||||
008FBFA61628B87000BC5BE2 /* CoreFoundation.framework */,
|
||||
);
|
||||
name = Apple;
|
||||
path = ../libusb;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
008FBF2F1628B79300BC5BE2 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FBF891628B7E800BC5BE2 /* libusb.h in Headers */,
|
||||
008FBF901628B7E800BC5BE2 /* libusbi.h in Headers */,
|
||||
008FBF931628B7E800BC5BE2 /* darwin_usb.h in Headers */,
|
||||
008FBF971628B7E800BC5BE2 /* poll_posix.h in Headers */,
|
||||
008FBF9B1628B7E800BC5BE2 /* threads_posix.h in Headers */,
|
||||
008FBFA11628B7E800BC5BE2 /* version.h in Headers */,
|
||||
008FBFA21628B7E800BC5BE2 /* version_nano.h in Headers */,
|
||||
008FBFA51628B84200BC5BE2 /* config.h in Headers */,
|
||||
1438D77B17A2ED9F00166101 /* hotplug.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
006AD41B1C8C5A90007F8C6A /* hotplugtest */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 006AD4221C8C5A90007F8C6A /* Build configuration list for PBXNativeTarget "hotplugtest" */;
|
||||
buildPhases = (
|
||||
006AD4181C8C5A90007F8C6A /* Sources */,
|
||||
006AD4191C8C5A90007F8C6A /* Frameworks */,
|
||||
006AD41A1C8C5A90007F8C6A /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = hotplugtest;
|
||||
productName = hotplugtest;
|
||||
productReference = 006AD41C1C8C5A90007F8C6A /* hotplugtest */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
008FBF301628B79300BC5BE2 /* libusb */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 008FBF351628B79300BC5BE2 /* Build configuration list for PBXNativeTarget "libusb" */;
|
||||
buildPhases = (
|
||||
008FBF2D1628B79300BC5BE2 /* Sources */,
|
||||
008FBF2E1628B79300BC5BE2 /* Frameworks */,
|
||||
008FBF2F1628B79300BC5BE2 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = libusb;
|
||||
productName = libusb;
|
||||
productReference = 008FBF311628B79300BC5BE2 /* libusb-1.0.0.dylib */;
|
||||
productType = "com.apple.product-type.library.dynamic";
|
||||
};
|
||||
008FBFBC1628B9FE00BC5BE2 /* xusb */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 008FBFC61628B9FE00BC5BE2 /* Build configuration list for PBXNativeTarget "xusb" */;
|
||||
buildPhases = (
|
||||
008FBFB91628B9FE00BC5BE2 /* Sources */,
|
||||
008FBFBA1628B9FE00BC5BE2 /* Frameworks */,
|
||||
008FBFBB1628B9FE00BC5BE2 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1443EE941641927D007E0579 /* PBXTargetDependency */,
|
||||
);
|
||||
name = xusb;
|
||||
productName = xusb;
|
||||
productReference = 008FBFBD1628B9FE00BC5BE2 /* xusb */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
008FBFF41628BB8B00BC5BE2 /* dpfp */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 008FBFFC1628BB8C00BC5BE2 /* Build configuration list for PBXNativeTarget "dpfp" */;
|
||||
buildPhases = (
|
||||
008FBFF11628BB8B00BC5BE2 /* Sources */,
|
||||
008FBFF21628BB8B00BC5BE2 /* Frameworks */,
|
||||
008FBFF31628BB8B00BC5BE2 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1443EE921641927A007E0579 /* PBXTargetDependency */,
|
||||
);
|
||||
name = dpfp;
|
||||
productName = dpfp;
|
||||
productReference = 008FBFF51628BB8B00BC5BE2 /* dpfp */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
008FC0041628BBDB00BC5BE2 /* dpfp_threaded */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 008FC00C1628BBDB00BC5BE2 /* Build configuration list for PBXNativeTarget "dpfp_threaded" */;
|
||||
buildPhases = (
|
||||
008FC0011628BBDB00BC5BE2 /* Sources */,
|
||||
008FC0021628BBDB00BC5BE2 /* Frameworks */,
|
||||
008FC0031628BBDB00BC5BE2 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1443EE9016419276007E0579 /* PBXTargetDependency */,
|
||||
);
|
||||
name = dpfp_threaded;
|
||||
productName = dpfp_threaded;
|
||||
productReference = 008FC0051628BBDB00BC5BE2 /* dpfp_threaded */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
008FC0141628BC0300BC5BE2 /* fxload */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 008FC01C1628BC0300BC5BE2 /* Build configuration list for PBXNativeTarget "fxload" */;
|
||||
buildPhases = (
|
||||
008FC0111628BC0300BC5BE2 /* Sources */,
|
||||
008FC0121628BC0300BC5BE2 /* Frameworks */,
|
||||
008FC0131628BC0300BC5BE2 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1443EE8E16419273007E0579 /* PBXTargetDependency */,
|
||||
);
|
||||
name = fxload;
|
||||
productName = fxload;
|
||||
productReference = 008FC0151628BC0300BC5BE2 /* fxload */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
008FC0251628BC6B00BC5BE2 /* listdevs */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 008FC02D1628BC6B00BC5BE2 /* Build configuration list for PBXNativeTarget "listdevs" */;
|
||||
buildPhases = (
|
||||
008FC0221628BC6B00BC5BE2 /* Sources */,
|
||||
008FC0231628BC6B00BC5BE2 /* Frameworks */,
|
||||
008FC0241628BC6B00BC5BE2 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1443EE8C1641926D007E0579 /* PBXTargetDependency */,
|
||||
);
|
||||
name = listdevs;
|
||||
productName = listdevs;
|
||||
productReference = 008FC0261628BC6B00BC5BE2 /* listdevs */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
008FBF281628B79300BC5BE2 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0450;
|
||||
ORGANIZATIONNAME = libusb;
|
||||
TargetAttributes = {
|
||||
006AD41B1C8C5A90007F8C6A = {
|
||||
CreatedOnToolsVersion = 7.2.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 008FBF2B1628B79300BC5BE2 /* Build configuration list for PBXProject "libusb" */;
|
||||
compatibilityVersion = "Xcode 3.1";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 008FBF261628B79300BC5BE2;
|
||||
productRefGroup = 008FBF321628B79300BC5BE2 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
008FBF301628B79300BC5BE2 /* libusb */,
|
||||
008FBFBC1628B9FE00BC5BE2 /* xusb */,
|
||||
008FBFF41628BB8B00BC5BE2 /* dpfp */,
|
||||
008FC0041628BBDB00BC5BE2 /* dpfp_threaded */,
|
||||
008FC0141628BC0300BC5BE2 /* fxload */,
|
||||
008FC0251628BC6B00BC5BE2 /* listdevs */,
|
||||
006AD41B1C8C5A90007F8C6A /* hotplugtest */,
|
||||
008FC0321628BC9400BC5BE2 /* all */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
006AD4181C8C5A90007F8C6A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
006AD4251C8C5AC4007F8C6A /* hotplugtest.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FBF2D1628B79300BC5BE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FBF861628B7E800BC5BE2 /* core.c in Sources */,
|
||||
008FBF871628B7E800BC5BE2 /* descriptor.c in Sources */,
|
||||
008FBF881628B7E800BC5BE2 /* io.c in Sources */,
|
||||
008FBF921628B7E800BC5BE2 /* darwin_usb.c in Sources */,
|
||||
008FBF9A1628B7E800BC5BE2 /* threads_posix.c in Sources */,
|
||||
008FBFA01628B7E800BC5BE2 /* sync.c in Sources */,
|
||||
1438D77A17A2ED9F00166101 /* hotplug.c in Sources */,
|
||||
1438D77D17A2EDCD00166101 /* poll_posix.c in Sources */,
|
||||
1438D77F17A2F0EA00166101 /* strerror.c in Sources */,
|
||||
006AD4241C8C5AAE007F8C6A /* hotplugtest.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FBFB91628B9FE00BC5BE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FBFEF1628BA3500BC5BE2 /* xusb.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FBFF11628BB8B00BC5BE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FBFFF1628BB9600BC5BE2 /* dpfp.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FC0011628BBDB00BC5BE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC00F1628BBE400BC5BE2 /* dpfp_threaded.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FC0111628BC0300BC5BE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC0211628BC5200BC5BE2 /* ezusb.c in Sources */,
|
||||
008FC01F1628BC1500BC5BE2 /* fxload.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
008FC0221628BC6B00BC5BE2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
008FC0301628BC7400BC5BE2 /* listdevs.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
006AD4281C8C5BBC007F8C6A /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 006AD41B1C8C5A90007F8C6A /* hotplugtest */;
|
||||
targetProxy = 006AD4271C8C5BBC007F8C6A /* PBXContainerItemProxy */;
|
||||
};
|
||||
008FC0371628BC9A00BC5BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBF301628B79300BC5BE2 /* libusb */;
|
||||
targetProxy = 008FC0361628BC9A00BC5BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
008FC0391628BC9A00BC5BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBFBC1628B9FE00BC5BE2 /* xusb */;
|
||||
targetProxy = 008FC0381628BC9A00BC5BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
008FC03B1628BC9A00BC5BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBFF41628BB8B00BC5BE2 /* dpfp */;
|
||||
targetProxy = 008FC03A1628BC9A00BC5BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
008FC03D1628BC9A00BC5BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FC0041628BBDB00BC5BE2 /* dpfp_threaded */;
|
||||
targetProxy = 008FC03C1628BC9A00BC5BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
008FC03F1628BC9A00BC5BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FC0141628BC0300BC5BE2 /* fxload */;
|
||||
targetProxy = 008FC03E1628BC9A00BC5BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
008FC0411628BC9A00BC5BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FC0251628BC6B00BC5BE2 /* listdevs */;
|
||||
targetProxy = 008FC0401628BC9A00BC5BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1443EE8C1641926D007E0579 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBF301628B79300BC5BE2 /* libusb */;
|
||||
targetProxy = 1443EE8B1641926D007E0579 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1443EE8E16419273007E0579 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBF301628B79300BC5BE2 /* libusb */;
|
||||
targetProxy = 1443EE8D16419273007E0579 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1443EE9016419276007E0579 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBF301628B79300BC5BE2 /* libusb */;
|
||||
targetProxy = 1443EE8F16419276007E0579 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1443EE921641927A007E0579 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBF301628B79300BC5BE2 /* libusb */;
|
||||
targetProxy = 1443EE911641927A007E0579 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1443EE941641927D007E0579 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 008FBF301628B79300BC5BE2 /* libusb */;
|
||||
targetProxy = 1443EE931641927D007E0579 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
006AD4201C8C5A90007F8C6A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
006AD4211C8C5A90007F8C6A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FBF331628B79300BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FBF341628B79300BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FBF361628B79300BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8616417E63007E0579 /* libusb_debug.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FBF371628B79300BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8916417EA6007E0579 /* libusb_release.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FBFC41628B9FE00BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FBFC51628B9FE00BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FBFFD1628BB8C00BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FBFFE1628BB8C00BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FC00D1628BBDB00BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FC00E1628BBDB00BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FC01D1628BC0300BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FC01E1628BC0300BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FC02E1628BC6B00BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8516417E63007E0579 /* debug.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FC02F1628BC6B00BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1443EE8816417E63007E0579 /* release.xcconfig */;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
008FC0341628BC9400BC5BE2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
008FC0351628BC9400BC5BE2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
006AD4221C8C5A90007F8C6A /* Build configuration list for PBXNativeTarget "hotplugtest" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
006AD4201C8C5A90007F8C6A /* Debug */,
|
||||
006AD4211C8C5A90007F8C6A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
008FBF2B1628B79300BC5BE2 /* Build configuration list for PBXProject "libusb" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FBF331628B79300BC5BE2 /* Debug */,
|
||||
008FBF341628B79300BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FBF351628B79300BC5BE2 /* Build configuration list for PBXNativeTarget "libusb" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FBF361628B79300BC5BE2 /* Debug */,
|
||||
008FBF371628B79300BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FBFC61628B9FE00BC5BE2 /* Build configuration list for PBXNativeTarget "xusb" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FBFC41628B9FE00BC5BE2 /* Debug */,
|
||||
008FBFC51628B9FE00BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FBFFC1628BB8C00BC5BE2 /* Build configuration list for PBXNativeTarget "dpfp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FBFFD1628BB8C00BC5BE2 /* Debug */,
|
||||
008FBFFE1628BB8C00BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FC00C1628BBDB00BC5BE2 /* Build configuration list for PBXNativeTarget "dpfp_threaded" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FC00D1628BBDB00BC5BE2 /* Debug */,
|
||||
008FC00E1628BBDB00BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FC01C1628BC0300BC5BE2 /* Build configuration list for PBXNativeTarget "fxload" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FC01D1628BC0300BC5BE2 /* Debug */,
|
||||
008FC01E1628BC0300BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FC02D1628BC6B00BC5BE2 /* Build configuration list for PBXNativeTarget "listdevs" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FC02E1628BC6B00BC5BE2 /* Debug */,
|
||||
008FC02F1628BC6B00BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
008FC0331628BC9400BC5BE2 /* Build configuration list for PBXAggregateTarget "all" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
008FC0341628BC9400BC5BE2 /* Debug */,
|
||||
008FC0351628BC9400BC5BE2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 008FBF281628B79300BC5BE2 /* Project object */;
|
||||
}
|
||||
21
externals/libusb/libusb/Xcode/libusb_debug.xcconfig
vendored
Executable file
21
externals/libusb/libusb/Xcode/libusb_debug.xcconfig
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// libusb Xcode configuration file
|
||||
// Copyright © 2012 Pete Batard <pete@akeo.ie>
|
||||
// For more information, please visit: <http://libusb.info>
|
||||
//
|
||||
// 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 "debug.xcconfig"
|
||||
#include "libusb.xcconfig"
|
||||
21
externals/libusb/libusb/Xcode/libusb_release.xcconfig
vendored
Executable file
21
externals/libusb/libusb/Xcode/libusb_release.xcconfig
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// libusb Xcode configuration file
|
||||
// Copyright © 2012 Pete Batard <pete@akeo.ie>
|
||||
// For more information, please visit: <http://libusb.info>
|
||||
//
|
||||
// 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 "release.xcconfig"
|
||||
#include "libusb.xcconfig"
|
||||
30
externals/libusb/libusb/Xcode/release.xcconfig
vendored
Executable file
30
externals/libusb/libusb/Xcode/release.xcconfig
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// libusb Xcode configuration file
|
||||
// Copyright © 2012 Pete Batard <pete@akeo.ie>
|
||||
// For more information, please visit: <http://libusb.info>
|
||||
//
|
||||
// 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 "common.xcconfig"
|
||||
|
||||
// Put debug symbols in separate .dym file.
|
||||
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
|
||||
|
||||
// Optimizations in release.
|
||||
GCC_OPTIMIZATION_LEVEL = s
|
||||
LLVM_LTO = YES
|
||||
|
||||
// Define NDEBUG so asserts go away in release.
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) NDEBUG=1
|
||||
116
externals/libusb/libusb/android/README
vendored
Executable file
116
externals/libusb/libusb/android/README
vendored
Executable file
@@ -0,0 +1,116 @@
|
||||
libusb for Android
|
||||
==================
|
||||
|
||||
Building:
|
||||
---------
|
||||
|
||||
To build libusb for Android do the following:
|
||||
|
||||
1. Download the latest NDK from:
|
||||
http://developer.android.com/tools/sdk/ndk/index.html
|
||||
|
||||
2. Extract the NDK.
|
||||
|
||||
3. Open a shell and make sure there exist an NDK global variable
|
||||
set to the directory where you extracted the NDK.
|
||||
|
||||
4. Change directory to libusb's "android/jni"
|
||||
|
||||
5. Run "$NDK/ndk-build".
|
||||
|
||||
The libusb library, examples and tests can then be found in:
|
||||
"android/libs/$ARCH"
|
||||
|
||||
Where $ARCH is one of:
|
||||
armeabi
|
||||
armeabi-v7a
|
||||
mips
|
||||
mips64
|
||||
x86
|
||||
x86_64
|
||||
|
||||
Installing:
|
||||
-----------
|
||||
|
||||
If you wish to use libusb from native code in own Android application
|
||||
then you should add the following line to your Android.mk file:
|
||||
|
||||
include $(PATH_TO_LIBUSB_SRC)/android/jni/libusb.mk
|
||||
|
||||
You will then need to add the following lines to the build
|
||||
configuration for each native binary which uses libusb:
|
||||
|
||||
LOCAL_C_INCLUDES += $(LIBUSB_ROOT_ABS)
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
The Android build system will then correctly include libusb in the
|
||||
application package (APK) file, provided ndk-build is invoked before
|
||||
the package is built.
|
||||
|
||||
|
||||
For a rooted device it is possible to install libusb into the system
|
||||
image of a running device:
|
||||
|
||||
1. Enable ADB on the device.
|
||||
|
||||
2. Connect the device to a machine running ADB.
|
||||
|
||||
3. Execute the following commands on the machine
|
||||
running ADB:
|
||||
|
||||
# Make the system partition writable
|
||||
adb shell su -c "mount -o remount,rw /system"
|
||||
|
||||
# Install libusb
|
||||
adb push obj/local/armeabi/libusb1.0.so /sdcard/
|
||||
adb shell su -c "cat > /system/lib/libusb1.0.so < /sdcard/libusb1.0.so"
|
||||
adb shell rm /sdcard/libusb1.0.so
|
||||
|
||||
# Install the samples and tests
|
||||
for B in listdevs fxload xusb sam3u_benchmark hotplugtest stress
|
||||
do
|
||||
adb push "obj/local/armeabi/$B" /sdcard/
|
||||
adb shell su -c "cat > /system/bin/$B < /sdcard/$B"
|
||||
adb shell su -c "chmod 0755 /system/bin/$B"
|
||||
adb shell rm "/sdcard/$B"
|
||||
done
|
||||
|
||||
# Make the system partition read only again
|
||||
adb shell su -c "mount -o remount,ro /system"
|
||||
|
||||
# Run listdevs to
|
||||
adb shell su -c "listdevs"
|
||||
|
||||
4. If your device only has a single OTG port then ADB can generally
|
||||
be switched to using Wifi with the following commands when connected
|
||||
via USB:
|
||||
|
||||
adb shell netcfg
|
||||
# Note the wifi IP address of the phone
|
||||
adb tcpip 5555
|
||||
# Use the IP address from netcfg
|
||||
adb connect 192.168.1.123:5555
|
||||
|
||||
Runtime Permissions:
|
||||
--------------------
|
||||
|
||||
The default system configuration on most Android device will not allow
|
||||
access to USB devices. There are several options for changing this.
|
||||
|
||||
If you have control of the system image then you can modify the
|
||||
ueventd.rc used in the image to change the permissions on
|
||||
/dev/bus/usb/*/*. If using this approach then it is advisable to
|
||||
create a new Android permission to protect access to these files.
|
||||
It is not advisable to give all applications read and write permissions
|
||||
to these files.
|
||||
|
||||
For rooted devices the code using libusb could be executed as root
|
||||
using the "su" command. An alternative would be to use the "su" command
|
||||
to change the permissions on the appropriate /dev/bus/usb/ files.
|
||||
|
||||
Users have reported success in using android.hardware.usb.UsbManager
|
||||
to request permission to use the UsbDevice and then opening the
|
||||
device. The difficulties in this method is that there is no guarantee
|
||||
that it will continue to work in the future Android versions, it
|
||||
requires invoking Java APIs and running code to match each
|
||||
android.hardware.usb.UsbDevice to a libusb_device.
|
||||
75
externals/libusb/libusb/android/config.h
vendored
Executable file
75
externals/libusb/libusb/android/config.h
vendored
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Android build config for libusb
|
||||
* Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.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
|
||||
*/
|
||||
|
||||
/* Start with debug message logging enabled */
|
||||
/* #undef ENABLE_DEBUG_LOGGING */
|
||||
|
||||
/* Message logging */
|
||||
#define ENABLE_LOGGING
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Linux backend */
|
||||
#define OS_LINUX 1
|
||||
|
||||
/* Enable output to system log */
|
||||
#define USE_SYSTEM_LOGGING_FACILITY 1
|
||||
|
||||
/* type of second poll() argument */
|
||||
#define POLL_NFDS_TYPE nfds_t
|
||||
|
||||
/* Use POSIX Threads */
|
||||
#define THREADS_POSIX 1
|
||||
|
||||
/* Default visibility */
|
||||
#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/filter.h> header file. */
|
||||
#define HAVE_LINUX_FILTER_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
||||
#define HAVE_LINUX_NETLINK_H 1
|
||||
|
||||
/* Define to 1 if you have the <asm/types.h> header file. */
|
||||
#define HAVE_ASM_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
23
externals/libusb/libusb/android/jni/Android.mk
vendored
Executable file
23
externals/libusb/libusb/android/jni/Android.mk
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
# Android build config for libusb, examples and tests
|
||||
# Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.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
|
||||
#
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(LOCAL_PATH)/libusb.mk
|
||||
include $(LOCAL_PATH)/examples.mk
|
||||
include $(LOCAL_PATH)/tests.mk
|
||||
24
externals/libusb/libusb/android/jni/Application.mk
vendored
Executable file
24
externals/libusb/libusb/android/jni/Application.mk
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
# Android application build config for libusb
|
||||
# Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.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
|
||||
#
|
||||
|
||||
APP_ABI := all
|
||||
|
||||
# Workaround for MIPS toolchain linker being unable to find liblog dependency
|
||||
# of shared object in NDK versions at least up to r9.
|
||||
#
|
||||
APP_LDFLAGS := -llog
|
||||
134
externals/libusb/libusb/android/jni/examples.mk
vendored
Executable file
134
externals/libusb/libusb/android/jni/examples.mk
vendored
Executable file
@@ -0,0 +1,134 @@
|
||||
# Android build config for libusb examples
|
||||
# Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.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
|
||||
#
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
LIBUSB_ROOT_REL:= ../..
|
||||
LIBUSB_ROOT_ABS:= $(LOCAL_PATH)/../..
|
||||
|
||||
# listdevs
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/listdevs.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= listdevs
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# xusb
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/xusb.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= xusb
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# hotplugtest
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/hotplugtest.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= hotplugtest
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# fxload
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/fxload.c \
|
||||
$(LIBUSB_ROOT_REL)/examples/ezusb.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= fxload
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# sam3u_benchmake
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/sam3u_benchmark.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= sam3u_benchmark
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# dpfp
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/dpfp.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= dpfp
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
# dpfp_threaded
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/examples/dpfp_threaded.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
|
||||
LOCAL_MODULE:= dpfp_threaded
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
54
externals/libusb/libusb/android/jni/libusb.mk
vendored
Executable file
54
externals/libusb/libusb/android/jni/libusb.mk
vendored
Executable file
@@ -0,0 +1,54 @@
|
||||
# Android build config for libusb
|
||||
# Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.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
|
||||
#
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
LIBUSB_ROOT_REL:= ../..
|
||||
LIBUSB_ROOT_ABS:= $(LOCAL_PATH)/../..
|
||||
|
||||
# libusb
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LIBUSB_ROOT_REL:= ../..
|
||||
LIBUSB_ROOT_ABS:= $(LOCAL_PATH)/../..
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/libusb/core.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/descriptor.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/hotplug.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/io.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/sync.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/strerror.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/os/linux_usbfs.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/os/poll_posix.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/os/threads_posix.c \
|
||||
$(LIBUSB_ROOT_REL)/libusb/os/linux_netlink.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH)/.. \
|
||||
$(LIBUSB_ROOT_ABS)/libusb \
|
||||
$(LIBUSB_ROOT_ABS)/libusb/os
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := \
|
||||
$(LIBUSB_ROOT_ABS)/libusb
|
||||
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
LOCAL_MODULE := libusb1.0
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
56
externals/libusb/libusb/android/jni/tests.mk
vendored
Executable file
56
externals/libusb/libusb/android/jni/tests.mk
vendored
Executable file
@@ -0,0 +1,56 @@
|
||||
# Android build config for libusb tests
|
||||
# Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.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
|
||||
#
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
LIBUSB_ROOT_REL:= ../..
|
||||
LIBUSB_ROOT_ABS:= $(LOCAL_PATH)/../..
|
||||
|
||||
# testlib
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/tests/testlib.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)/tests
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := \
|
||||
$(LIBUSB_ROOT_ABS)/tests
|
||||
|
||||
LOCAL_MODULE := testlib
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
# stress
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LIBUSB_ROOT_REL)/tests/stress.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LIBUSB_ROOT_ABS)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libusb1.0
|
||||
LOCAL_STATIC_LIBRARIES += testlib
|
||||
|
||||
LOCAL_MODULE:= stress
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
41
externals/libusb/libusb/appveyor.yml
vendored
Executable file
41
externals/libusb/libusb/appveyor.yml
vendored
Executable file
@@ -0,0 +1,41 @@
|
||||
version: 1.0.{build}
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
platform:
|
||||
- x64
|
||||
- Win32
|
||||
build:
|
||||
project: msvc\libusb_2013.sln
|
||||
parallel: true
|
||||
verbosity: detailed
|
||||
environment:
|
||||
matrix:
|
||||
- libusb_2015: msvc\libusb_2015.sln
|
||||
libusb_2013: msvc\libusb_2013.sln
|
||||
libusb_2012: msvc\libusb_2012.sln
|
||||
libusb_2010: msvc\libusb_2010.sln
|
||||
install:
|
||||
|
||||
- cmd: >-
|
||||
rem Copying libusb to cygwin home directory
|
||||
|
||||
xcopy /S C:\projects\libusb C:\cygwin\home\appveyor\
|
||||
|
||||
rem Copying libusb to MinGW home directory
|
||||
|
||||
xcopy /S C:\projects\libusb C:\msys64\home\appveyor\
|
||||
|
||||
build_script:
|
||||
- cmd: >-
|
||||
msbuild %libusb_2015% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
msbuild %libusb_2013% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
msbuild %libusb_2012% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
|
||||
msvc/appveyor.bat
|
||||
|
||||
appveyor_minGW.bat
|
||||
|
||||
appveyor_cygwin.bat
|
||||
11
externals/libusb/libusb/appveyor_cygwin.bat
vendored
Executable file
11
externals/libusb/libusb/appveyor_cygwin.bat
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
echo on
|
||||
SetLocal EnableDelayedExpansion
|
||||
|
||||
if [%Configuration%] NEQ [Release] exit 0
|
||||
if [%Platform%] NEQ [Win32] exit 0
|
||||
|
||||
C:\cygwin\bin\bash -e -l -c "./bootstrap.sh" || exit /B
|
||||
C:\cygwin\bin\bash -e -l -c "mkdir build-Win32-cygwin" || exit /B
|
||||
C:\cygwin\bin\bash -e -l -c "cd build-Win32-cygwin && ../configure --enable-examples-build --enable-tests-build" || exit /B
|
||||
C:\cygwin\bin\bash -e -l -c "cd build-Win32-cygwin && make -j4" || exit /B
|
||||
C:\cygwin\bin\bash -e -l -c "cd build-Win32-cygwin && make install" || exit /B
|
||||
19
externals/libusb/libusb/appveyor_minGW.bat
vendored
Executable file
19
externals/libusb/libusb/appveyor_minGW.bat
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
echo on
|
||||
SetLocal EnableDelayedExpansion
|
||||
|
||||
if [%Configuration%] NEQ [Release] exit 0
|
||||
|
||||
if [%Platform%] NEQ [x64] goto Win32
|
||||
C:\msys64\usr\bin\bash -e -l -c "./bootstrap.sh" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "mkdir build-x64" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "cd build-x64 && ../configure --prefix=/mingw64 --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "cd build-x64 && make -j4" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "cd build-x64 && make install" || exit /B
|
||||
|
||||
:Win32
|
||||
if [%Platform%] NEQ [Win32] exit 0
|
||||
C:\msys64\usr\bin\bash -e -l -c "./bootstrap.sh" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "mkdir build-Win32" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "cd build-Win32 && ../configure --prefix=/mingw32 --build=i686-w64-mingw32 --host=i686-w64-mingw32" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "cd build-Win32 && make -j4" || exit /B
|
||||
C:\msys64\usr\bin\bash -e -l -c "cd build-Win32 && make install" || exit /B
|
||||
8
externals/libusb/libusb/autogen.sh
vendored
Executable file
8
externals/libusb/libusb/autogen.sh
vendored
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
./bootstrap.sh
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
exec ./configure --enable-examples-build --enable-tests-build "$@"
|
||||
fi
|
||||
6
externals/libusb/libusb/bootstrap.sh
vendored
Executable file
6
externals/libusb/libusb/bootstrap.sh
vendored
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! test -d m4 ; then
|
||||
mkdir m4
|
||||
fi
|
||||
autoreconf -ivf || exit 1
|
||||
332
externals/libusb/libusb/configure.ac
vendored
Executable file
332
externals/libusb/libusb/configure.ac
vendored
Executable file
@@ -0,0 +1,332 @@
|
||||
dnl These m4 macros are whitespace sensitive and break if moved around much.
|
||||
m4_define([LU_VERSION_H], m4_include([libusb/version.h]))
|
||||
m4_define([LU_DEFINE_VERSION_ATOM],
|
||||
[m4_define([$1], m4_bregexp(LU_VERSION_H,
|
||||
[^#define\s*$1\s*\([0-9]*\).*], [\1]))])
|
||||
m4_define([LU_DEFINE_VERSION_RC_ATOM],
|
||||
[m4_define([$1], m4_bregexp(LU_VERSION_H,
|
||||
[^#define\s*$1\s*"\(-rc[0-9]*\)".*], [\1]))])
|
||||
dnl The m4_bregexp() returns (only) the numbers following the #define named
|
||||
dnl in the first macro parameter. m4_define() then defines the name for use
|
||||
dnl in AC_INIT.
|
||||
|
||||
LU_DEFINE_VERSION_ATOM([LIBUSB_MAJOR])
|
||||
LU_DEFINE_VERSION_ATOM([LIBUSB_MINOR])
|
||||
LU_DEFINE_VERSION_ATOM([LIBUSB_MICRO])
|
||||
LU_DEFINE_VERSION_RC_ATOM([LIBUSB_RC])
|
||||
|
||||
AC_INIT([libusb],[LIBUSB_MAJOR[.]LIBUSB_MINOR[.]LIBUSB_MICRO[]LIBUSB_RC],[libusb-devel@lists.sourceforge.net],[libusb],[http://libusb.info])
|
||||
|
||||
# Library versioning
|
||||
# These numbers should be tweaked on every release. Read carefully:
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
# http://sourceware.org/autobook/autobook/autobook_91.html
|
||||
lt_current=2
|
||||
lt_revision=0
|
||||
lt_age=2
|
||||
LTLDFLAGS="-version-info ${lt_current}:${lt_revision}:${lt_age}"
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_CONFIG_SRCDIR([libusb/core.c])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
LT_INIT
|
||||
LT_LANG([Windows Resource])
|
||||
AC_C_INLINE
|
||||
AM_PROG_CC_C_O
|
||||
AC_DEFINE([_GNU_SOURCE], 1, [Use GNU extensions])
|
||||
|
||||
LTLDFLAGS="${LTLDFLAGS} -no-undefined"
|
||||
|
||||
AC_MSG_CHECKING([operating system])
|
||||
|
||||
dnl on linux-android platform, some functions are in different places
|
||||
case $host in
|
||||
*-linux-android*)
|
||||
AC_MSG_RESULT([This is a Linux-Android system])
|
||||
is_backend_android=yes
|
||||
;;
|
||||
*)
|
||||
is_backend_android=no
|
||||
esac
|
||||
|
||||
case $host in
|
||||
*-linux* | *-uclinux*)
|
||||
AC_MSG_RESULT([Linux])
|
||||
backend=linux
|
||||
threads=posix
|
||||
;;
|
||||
*-darwin*)
|
||||
AC_MSG_RESULT([Darwin/Mac OS X])
|
||||
backend=darwin
|
||||
threads=posix
|
||||
;;
|
||||
*-openbsd*)
|
||||
AC_MSG_RESULT([OpenBSD])
|
||||
backend=openbsd
|
||||
threads=posix
|
||||
;;
|
||||
*-netbsd*)
|
||||
AC_MSG_RESULT([NetBSD])
|
||||
backend=netbsd
|
||||
threads=posix
|
||||
;;
|
||||
*-mingw* | *msys*)
|
||||
AC_MSG_RESULT([Windows])
|
||||
backend=windows
|
||||
threads=windows
|
||||
create_import_lib=yes
|
||||
AM_CFLAGS="${AM_CFLAGS} -fno-omit-frame-pointer"
|
||||
;;
|
||||
*-cygwin*)
|
||||
AC_MSG_RESULT([Cygwin (using Windows backend)])
|
||||
backend=windows
|
||||
threads=posix
|
||||
;;
|
||||
*-haiku*)
|
||||
AC_MSG_RESULT([Haiku])
|
||||
backend=haiku
|
||||
threads=posix
|
||||
;;
|
||||
*-solaris*)
|
||||
AC_MSG_RESULT([SunOS])
|
||||
backend=sunos
|
||||
threads=posix
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([unsupported operating system $host])
|
||||
esac
|
||||
|
||||
case $backend in
|
||||
linux)
|
||||
AC_DEFINE(OS_LINUX, 1, [Linux backend])
|
||||
AC_SUBST(OS_LINUX)
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt], [], [], [-pthread])
|
||||
AC_ARG_ENABLE([udev],
|
||||
[AC_HELP_STRING([--enable-udev], [use udev for device enumeration and hotplug support (recommended) [default=yes]])],
|
||||
[], [enable_udev=yes])
|
||||
if test "x$enable_udev" = xyes ; then
|
||||
# system has udev. use it or fail!
|
||||
AC_CHECK_HEADERS([libudev.h], [], [AC_MSG_ERROR([udev support requested but libudev header not installed])])
|
||||
AC_CHECK_LIB([udev], [udev_new], [], [AC_MSG_ERROR([udev support requested but libudev not installed])])
|
||||
AC_DEFINE(USE_UDEV, 1, [Use udev for device enumeration/hotplug])
|
||||
else
|
||||
AC_CHECK_HEADERS([asm/types.h], [], [])
|
||||
AC_CHECK_HEADERS([sys/socket.h linux/netlink.h], [], [AC_MSG_ERROR([Linux netlink headers not found])], [
|
||||
#ifdef HAVE_ASM_TYPES_H
|
||||
#include <asm/types.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
fi
|
||||
AC_SUBST(USE_UDEV)
|
||||
|
||||
if test "x$is_backend_android" != xyes; then
|
||||
THREAD_CFLAGS="-pthread"
|
||||
LIBS="${LIBS} -pthread"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
|
||||
;;
|
||||
darwin)
|
||||
AC_DEFINE(OS_DARWIN, 1, [Darwin backend])
|
||||
AC_SUBST(OS_DARWIN)
|
||||
LIBS="-lobjc -Wl,-framework,IOKit -Wl,-framework,CoreFoundation"
|
||||
LTLDFLAGS="${LTLDFLAGS} -Wl,-prebind"
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_CHECK_TYPE([nfds_t],
|
||||
[AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])],
|
||||
[AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument])],
|
||||
[#include <poll.h>])
|
||||
;;
|
||||
openbsd)
|
||||
AC_DEFINE(OS_OPENBSD, 1, [OpenBSD backend])
|
||||
AC_SUBST(OS_OPENBSD)
|
||||
THREAD_CFLAGS="-pthread"
|
||||
LIBS="-pthread"
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
|
||||
;;
|
||||
sunos)
|
||||
AC_DEFINE(OS_SUNOS, 1, [SunOS backend])
|
||||
AC_SUBST(OS_SUNOS)
|
||||
THREAD_CFLAGS="-pthread"
|
||||
LIBS="-pthread -ldevinfo"
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
|
||||
;;
|
||||
netbsd)
|
||||
AC_DEFINE(OS_NETBSD, 1, [NetBSD backend])
|
||||
AC_SUBST(OS_NETBSD)
|
||||
THREAD_CFLAGS="-pthread"
|
||||
LIBS="-pthread"
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
|
||||
;;
|
||||
windows)
|
||||
AC_DEFINE(OS_WINDOWS, 1, [Windows backend])
|
||||
AC_SUBST(OS_WINDOWS)
|
||||
LIBS=""
|
||||
LTLDFLAGS="${LTLDFLAGS} -avoid-version -Wl,--add-stdcall-alias"
|
||||
AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[type of second poll() argument])
|
||||
AC_DEFINE([WINVER], 0x0501, [Oldest Windows version supported])
|
||||
AC_DEFINE([_WIN32_WINNT], 0x0501, [Oldest Windows version supported])
|
||||
;;
|
||||
haiku)
|
||||
AC_DEFINE(OS_HAIKU, 1, [Haiku backend])
|
||||
AC_SUBST(OS_HAIKU)
|
||||
LIBS="${LIBS} -lbe"
|
||||
AC_CHECK_HEADERS([poll.h])
|
||||
AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[type of second poll() argument])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(LIBS)
|
||||
|
||||
AM_CONDITIONAL(OS_LINUX, test "x$backend" = xlinux)
|
||||
AM_CONDITIONAL(OS_DARWIN, test "x$backend" = xdarwin)
|
||||
AM_CONDITIONAL(OS_OPENBSD, test "x$backend" = xopenbsd)
|
||||
AM_CONDITIONAL(OS_SUNOS, test "x$backend" = xsunos)
|
||||
AM_CONDITIONAL(OS_NETBSD, test "x$backend" = xnetbsd)
|
||||
AM_CONDITIONAL(OS_WINDOWS, test "x$backend" = xwindows)
|
||||
AM_CONDITIONAL(OS_HAIKU, test "x$backend" = xhaiku)
|
||||
AM_CONDITIONAL(THREADS_POSIX, test "x$threads" = xposix)
|
||||
AM_CONDITIONAL(CREATE_IMPORT_LIB, test "x$create_import_lib" = xyes)
|
||||
AM_CONDITIONAL(USE_UDEV, test "x$enable_udev" = xyes)
|
||||
if test "x$threads" = xposix; then
|
||||
AC_DEFINE(THREADS_POSIX, 1, [Use POSIX Threads])
|
||||
fi
|
||||
|
||||
# timerfd
|
||||
AC_CHECK_HEADER([sys/timerfd.h], [timerfd_h=1], [timerfd_h=0])
|
||||
AC_ARG_ENABLE([timerfd],
|
||||
[AS_HELP_STRING([--enable-timerfd],
|
||||
[use timerfd for timing [default=auto]])],
|
||||
[use_timerfd=$enableval], [use_timerfd=auto])
|
||||
|
||||
if test "x$use_timerfd" = xyes -a "x$timerfd_h" = x0; then
|
||||
AC_MSG_ERROR([timerfd header not available; glibc 2.9+ required])
|
||||
fi
|
||||
|
||||
AC_CHECK_DECLS([TFD_NONBLOCK, TFD_CLOEXEC], [tfd_hdr_ok=yes], [tfd_hdr_ok=no], [#include <sys/timerfd.h>])
|
||||
if test "x$use_timerfd" = xyes -a "x$tfd_hdr_ok" = xno; then
|
||||
AC_MSG_ERROR([timerfd header not usable; glibc 2.9+ required])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to use timerfd for timing])
|
||||
if test "x$use_timerfd" = xno; then
|
||||
AC_MSG_RESULT([no (disabled by user)])
|
||||
else
|
||||
if test "x$timerfd_h" = x1 -a "x$tfd_hdr_ok" = xyes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(USBI_TIMERFD_AVAILABLE, 1, [timerfd headers available])
|
||||
else
|
||||
AC_MSG_RESULT([no (header not available)])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS([pipe2])
|
||||
AC_CHECK_TYPES([struct timespec])
|
||||
|
||||
# Message logging
|
||||
AC_ARG_ENABLE([log], [AS_HELP_STRING([--disable-log], [disable all logging])],
|
||||
[log_enabled=$enableval],
|
||||
[log_enabled=yes])
|
||||
if test "x$log_enabled" != xno; then
|
||||
AC_DEFINE([ENABLE_LOGGING], 1, [Message logging])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([debug-log], [AS_HELP_STRING([--enable-debug-log],
|
||||
[start with debug message logging enabled [default=no]])],
|
||||
[debug_log_enabled=$enableval],
|
||||
[debug_log_enabled=no])
|
||||
if test "x$debug_log_enabled" != xno; then
|
||||
AC_DEFINE([ENABLE_DEBUG_LOGGING], 1, [Start with debug message logging enabled])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([system-log], [AS_HELP_STRING([--enable-system-log],
|
||||
[output logging messages to system wide log, if supported by the OS [default=no]])],
|
||||
[system_log_enabled=$enableval],
|
||||
[system_log_enabled=no])
|
||||
if test "x$system_log_enabled" != xno; then
|
||||
AC_DEFINE([USE_SYSTEM_LOGGING_FACILITY], 1, [Enable output to system log])
|
||||
|
||||
# Check if syslog is available in standard C library
|
||||
AC_CHECK_HEADERS(syslog.h)
|
||||
AC_CHECK_FUNC([syslog], [have_syslog=yes], [have_syslog=no])
|
||||
if test "x$have_syslog" != xno; then
|
||||
AC_DEFINE([HAVE_SYSLOG_FUNC], 1, [syslog() function available])
|
||||
fi
|
||||
fi
|
||||
|
||||
# Examples build
|
||||
AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build],
|
||||
[build example applications [default=no]])],
|
||||
[build_examples=$enableval],
|
||||
[build_examples=no])
|
||||
AM_CONDITIONAL(BUILD_EXAMPLES, test "x$build_examples" != xno)
|
||||
|
||||
# Tests build
|
||||
AC_ARG_ENABLE([tests-build], [AS_HELP_STRING([--enable-tests-build],
|
||||
[build test applications [default=no]])],
|
||||
[build_tests=$enableval],
|
||||
[build_tests=no])
|
||||
AM_CONDITIONAL(BUILD_TESTS, test "x$build_tests" != xno)
|
||||
|
||||
# headers not available on all platforms but required on others
|
||||
AC_CHECK_HEADERS([sys/time.h])
|
||||
|
||||
# sigaction not available on MinGW
|
||||
AC_CHECK_FUNC([sigaction], [have_sigaction=yes], [have_sigaction=no])
|
||||
AM_CONDITIONAL(HAVE_SIGACTION, test "x$have_sigaction" = xyes)
|
||||
|
||||
# check for -fvisibility=hidden compiler support (GCC >= 3.4)
|
||||
saved_cflags="$CFLAGS"
|
||||
# -Werror required for cygwin
|
||||
CFLAGS="$CFLAGS -Werror -fvisibility=hidden"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
|
||||
[VISIBILITY_CFLAGS="-fvisibility=hidden"
|
||||
AC_DEFINE([DEFAULT_VISIBILITY], [__attribute__((visibility("default")))], [Default visibility])],
|
||||
[VISIBILITY_CFLAGS=""
|
||||
AC_DEFINE([DEFAULT_VISIBILITY], [], [Default visibility])],
|
||||
])
|
||||
CFLAGS="$saved_cflags"
|
||||
|
||||
# check for -Wno-pointer-sign compiler support (GCC >= 4)
|
||||
saved_cflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wno-pointer-sign"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
|
||||
nopointersign_cflags="-Wno-pointer-sign", nopointersign_cflags="")
|
||||
CFLAGS="$saved_cflags"
|
||||
|
||||
# check for -std=gnu99 compiler support
|
||||
saved_cflags="$CFLAGS"
|
||||
CFLAGS="-std=gnu99"
|
||||
AC_MSG_CHECKING([whether CC supports -std=gnu99])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
|
||||
[AC_MSG_RESULT([yes])]
|
||||
[AM_CFLAGS="${AM_CFLAGS} -std=gnu99"],
|
||||
[AC_MSG_RESULT([no])]
|
||||
)
|
||||
CFLAGS="$saved_cflags"
|
||||
|
||||
AM_CFLAGS="${AM_CFLAGS} -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration $nopointersign_cflags -Wshadow ${THREAD_CFLAGS} ${VISIBILITY_CFLAGS}"
|
||||
|
||||
AC_SUBST(AM_CFLAGS)
|
||||
AC_SUBST(LTLDFLAGS)
|
||||
|
||||
AC_CONFIG_FILES([libusb-1.0.pc])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([libusb/Makefile])
|
||||
AC_CONFIG_FILES([examples/Makefile])
|
||||
AC_CONFIG_FILES([tests/Makefile])
|
||||
AC_CONFIG_FILES([doc/Makefile])
|
||||
AC_CONFIG_FILES([doc/doxygen.cfg])
|
||||
AC_OUTPUT
|
||||
9
externals/libusb/libusb/doc/Makefile.am
vendored
Executable file
9
externals/libusb/libusb/doc/Makefile.am
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
EXTRA_DIST = doxygen.cfg.in
|
||||
|
||||
docs: doxygen.cfg
|
||||
doxygen $^
|
||||
|
||||
docs-upload: docs
|
||||
ln -s html api-1.0
|
||||
scp -r api-1.0 pbatard@web.sourceforge.net:/home/project-web/libusb/htdocs
|
||||
rm -f api-1.0
|
||||
2334
externals/libusb/libusb/doc/doxygen.cfg.in
vendored
Executable file
2334
externals/libusb/libusb/doc/doxygen.cfg.in
vendored
Executable file
File diff suppressed because it is too large
Load Diff
BIN
externals/libusb/libusb/doc/libusb.png
vendored
Executable file
BIN
externals/libusb/libusb/doc/libusb.png
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
19
externals/libusb/libusb/examples/Makefile.am
vendored
Executable file
19
externals/libusb/libusb/examples/Makefile.am
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/libusb
|
||||
LDADD = ../libusb/libusb-1.0.la
|
||||
|
||||
noinst_PROGRAMS = listdevs xusb fxload hotplugtest testlibusb
|
||||
|
||||
if HAVE_SIGACTION
|
||||
noinst_PROGRAMS += dpfp
|
||||
|
||||
if THREADS_POSIX
|
||||
dpfp_threaded_CFLAGS = $(AM_CFLAGS)
|
||||
noinst_PROGRAMS += dpfp_threaded
|
||||
endif
|
||||
|
||||
sam3u_benchmark_SOURCES = sam3u_benchmark.c
|
||||
noinst_PROGRAMS += sam3u_benchmark
|
||||
endif
|
||||
|
||||
fxload_SOURCES = ezusb.c ezusb.h fxload.c
|
||||
fxload_CFLAGS = $(THREAD_CFLAGS) $(AM_CFLAGS)
|
||||
508
externals/libusb/libusb/examples/dpfp.c
vendored
Executable file
508
externals/libusb/libusb/examples/dpfp.c
vendored
Executable file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
* libusb example program to manipulate U.are.U 4000B fingerprint scanner.
|
||||
* Copyright © 2007 Daniel Drake <dsd@gentoo.org>
|
||||
*
|
||||
* Basic image capture program only, does not consider the powerup quirks or
|
||||
* the fact that image encryption may be enabled. Not expected to work
|
||||
* flawlessly all of the time.
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libusb.h"
|
||||
|
||||
#define EP_INTR (1 | LIBUSB_ENDPOINT_IN)
|
||||
#define EP_DATA (2 | LIBUSB_ENDPOINT_IN)
|
||||
#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN)
|
||||
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT)
|
||||
#define USB_RQ 0x04
|
||||
#define INTR_LENGTH 64
|
||||
|
||||
enum {
|
||||
MODE_INIT = 0x00,
|
||||
MODE_AWAIT_FINGER_ON = 0x10,
|
||||
MODE_AWAIT_FINGER_OFF = 0x12,
|
||||
MODE_CAPTURE = 0x20,
|
||||
MODE_SHUT_UP = 0x30,
|
||||
MODE_READY = 0x80,
|
||||
};
|
||||
|
||||
static int next_state(void);
|
||||
|
||||
enum {
|
||||
STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_ON = 1,
|
||||
STATE_AWAIT_IRQ_FINGER_DETECTED,
|
||||
STATE_AWAIT_MODE_CHANGE_CAPTURE,
|
||||
STATE_AWAIT_IMAGE,
|
||||
STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_OFF,
|
||||
STATE_AWAIT_IRQ_FINGER_REMOVED,
|
||||
};
|
||||
|
||||
static int state = 0;
|
||||
static struct libusb_device_handle *devh = NULL;
|
||||
static unsigned char imgbuf[0x1b340];
|
||||
static unsigned char irqbuf[INTR_LENGTH];
|
||||
static struct libusb_transfer *img_transfer = NULL;
|
||||
static struct libusb_transfer *irq_transfer = NULL;
|
||||
static int img_idx = 0;
|
||||
static int do_exit = 0;
|
||||
|
||||
static int find_dpfp_device(void)
|
||||
{
|
||||
devh = libusb_open_device_with_vid_pid(NULL, 0x05ba, 0x000a);
|
||||
return devh ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int print_f0_data(void)
|
||||
{
|
||||
unsigned char data[0x10];
|
||||
int r;
|
||||
unsigned int i;
|
||||
|
||||
r = libusb_control_transfer(devh, CTRL_IN, USB_RQ, 0xf0, 0, data,
|
||||
sizeof(data), 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "F0 error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < sizeof(data)) {
|
||||
fprintf(stderr, "short read (%d)\n", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("F0 data:");
|
||||
for (i = 0; i < sizeof(data); i++)
|
||||
printf("%02x ", data[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_hwstat(unsigned char *status)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = libusb_control_transfer(devh, CTRL_IN, USB_RQ, 0x07, 0, status, 1, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "read hwstat error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < 1) {
|
||||
fprintf(stderr, "short read (%d)\n", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("hwstat reads %02x\n", *status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_hwstat(unsigned char data)
|
||||
{
|
||||
int r;
|
||||
|
||||
printf("set hwstat to %02x\n", data);
|
||||
r = libusb_control_transfer(devh, CTRL_OUT, USB_RQ, 0x07, 0, &data, 1, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "set hwstat error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < 1) {
|
||||
fprintf(stderr, "short write (%d)", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_mode(unsigned char data)
|
||||
{
|
||||
int r;
|
||||
printf("set mode %02x\n", data);
|
||||
|
||||
r = libusb_control_transfer(devh, CTRL_OUT, USB_RQ, 0x4e, 0, &data, 1, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "set mode error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < 1) {
|
||||
fprintf(stderr, "short write (%d)", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL cb_mode_changed(struct libusb_transfer *transfer)
|
||||
{
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "mode change transfer not completed!\n");
|
||||
do_exit = 2;
|
||||
}
|
||||
|
||||
printf("async cb_mode_changed length=%d actual_length=%d\n",
|
||||
transfer->length, transfer->actual_length);
|
||||
if (next_state() < 0)
|
||||
do_exit = 2;
|
||||
}
|
||||
|
||||
static int set_mode_async(unsigned char data)
|
||||
{
|
||||
unsigned char *buf = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
||||
struct libusb_transfer *transfer;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
transfer = libusb_alloc_transfer(0);
|
||||
if (!transfer) {
|
||||
free(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
printf("async set mode %02x\n", data);
|
||||
libusb_fill_control_setup(buf, CTRL_OUT, USB_RQ, 0x4e, 0, 1);
|
||||
buf[LIBUSB_CONTROL_SETUP_SIZE] = data;
|
||||
libusb_fill_control_transfer(transfer, devh, buf, cb_mode_changed, NULL,
|
||||
1000);
|
||||
|
||||
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK
|
||||
| LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
return libusb_submit_transfer(transfer);
|
||||
}
|
||||
|
||||
static int do_sync_intr(unsigned char *data)
|
||||
{
|
||||
int r;
|
||||
int transferred;
|
||||
|
||||
r = libusb_interrupt_transfer(devh, EP_INTR, data, INTR_LENGTH,
|
||||
&transferred, 1000);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "intr error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if (transferred < INTR_LENGTH) {
|
||||
fprintf(stderr, "short read (%d)\n", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("recv interrupt %04x\n", *((uint16_t *) data));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sync_intr(unsigned char type)
|
||||
{
|
||||
int r;
|
||||
unsigned char data[INTR_LENGTH];
|
||||
|
||||
while (1) {
|
||||
r = do_sync_intr(data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (data[0] == type)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int save_to_file(unsigned char *data)
|
||||
{
|
||||
FILE *fd;
|
||||
char filename[64];
|
||||
|
||||
snprintf(filename, sizeof(filename), "finger%d.pgm", img_idx++);
|
||||
fd = fopen(filename, "w");
|
||||
if (!fd)
|
||||
return -1;
|
||||
|
||||
fputs("P5 384 289 255 ", fd);
|
||||
(void) fwrite(data + 64, 1, 384*289, fd);
|
||||
fclose(fd);
|
||||
printf("saved image to %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int next_state(void)
|
||||
{
|
||||
int r = 0;
|
||||
printf("old state: %d\n", state);
|
||||
switch (state) {
|
||||
case STATE_AWAIT_IRQ_FINGER_REMOVED:
|
||||
state = STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_ON;
|
||||
r = set_mode_async(MODE_AWAIT_FINGER_ON);
|
||||
break;
|
||||
case STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_ON:
|
||||
state = STATE_AWAIT_IRQ_FINGER_DETECTED;
|
||||
break;
|
||||
case STATE_AWAIT_IRQ_FINGER_DETECTED:
|
||||
state = STATE_AWAIT_MODE_CHANGE_CAPTURE;
|
||||
r = set_mode_async(MODE_CAPTURE);
|
||||
break;
|
||||
case STATE_AWAIT_MODE_CHANGE_CAPTURE:
|
||||
state = STATE_AWAIT_IMAGE;
|
||||
break;
|
||||
case STATE_AWAIT_IMAGE:
|
||||
state = STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_OFF;
|
||||
r = set_mode_async(MODE_AWAIT_FINGER_OFF);
|
||||
break;
|
||||
case STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_OFF:
|
||||
state = STATE_AWAIT_IRQ_FINGER_REMOVED;
|
||||
break;
|
||||
default:
|
||||
printf("unrecognised state %d\n", state);
|
||||
}
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "error detected changing state\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("new state: %d\n", state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL cb_irq(struct libusb_transfer *transfer)
|
||||
{
|
||||
unsigned char irqtype = transfer->buffer[0];
|
||||
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "irq transfer status %d?\n", transfer->status);
|
||||
do_exit = 2;
|
||||
libusb_free_transfer(transfer);
|
||||
irq_transfer = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
printf("IRQ callback %02x\n", irqtype);
|
||||
switch (state) {
|
||||
case STATE_AWAIT_IRQ_FINGER_DETECTED:
|
||||
if (irqtype == 0x01) {
|
||||
if (next_state() < 0) {
|
||||
do_exit = 2;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("finger-on-sensor detected in wrong state!\n");
|
||||
}
|
||||
break;
|
||||
case STATE_AWAIT_IRQ_FINGER_REMOVED:
|
||||
if (irqtype == 0x02) {
|
||||
if (next_state() < 0) {
|
||||
do_exit = 2;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("finger-on-sensor detected in wrong state!\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (libusb_submit_transfer(irq_transfer) < 0)
|
||||
do_exit = 2;
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL cb_img(struct libusb_transfer *transfer)
|
||||
{
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "img transfer status %d?\n", transfer->status);
|
||||
do_exit = 2;
|
||||
libusb_free_transfer(transfer);
|
||||
img_transfer = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Image callback\n");
|
||||
save_to_file(imgbuf);
|
||||
if (next_state() < 0) {
|
||||
do_exit = 2;
|
||||
return;
|
||||
}
|
||||
if (libusb_submit_transfer(img_transfer) < 0)
|
||||
do_exit = 2;
|
||||
}
|
||||
|
||||
static int init_capture(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = libusb_submit_transfer(irq_transfer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = libusb_submit_transfer(img_transfer);
|
||||
if (r < 0) {
|
||||
libusb_cancel_transfer(irq_transfer);
|
||||
while (irq_transfer)
|
||||
if (libusb_handle_events(NULL) < 0)
|
||||
break;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* start state machine */
|
||||
state = STATE_AWAIT_IRQ_FINGER_REMOVED;
|
||||
return next_state();
|
||||
}
|
||||
|
||||
static int do_init(void)
|
||||
{
|
||||
unsigned char status;
|
||||
int r;
|
||||
|
||||
r = get_hwstat(&status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!(status & 0x80)) {
|
||||
r = set_hwstat(status | 0x80);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = get_hwstat(&status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
status &= ~0x80;
|
||||
r = set_hwstat(status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_hwstat(&status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sync_intr(0x56);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_transfers(void)
|
||||
{
|
||||
img_transfer = libusb_alloc_transfer(0);
|
||||
if (!img_transfer)
|
||||
return -ENOMEM;
|
||||
|
||||
irq_transfer = libusb_alloc_transfer(0);
|
||||
if (!irq_transfer)
|
||||
return -ENOMEM;
|
||||
|
||||
libusb_fill_bulk_transfer(img_transfer, devh, EP_DATA, imgbuf,
|
||||
sizeof(imgbuf), cb_img, NULL, 0);
|
||||
libusb_fill_interrupt_transfer(irq_transfer, devh, EP_INTR, irqbuf,
|
||||
sizeof(irqbuf), cb_irq, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sighandler(int signum)
|
||||
{
|
||||
(void)signum;
|
||||
|
||||
do_exit = 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
int r;
|
||||
|
||||
r = libusb_init(NULL);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to initialise libusb\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r = find_dpfp_device();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Could not find/open device\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = libusb_claim_interface(devh, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "usb_claim_interface error %d\n", r);
|
||||
goto out;
|
||||
}
|
||||
printf("claimed interface\n");
|
||||
|
||||
r = print_f0_data();
|
||||
if (r < 0)
|
||||
goto out_release;
|
||||
|
||||
r = do_init();
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
|
||||
/* async from here onwards */
|
||||
|
||||
r = alloc_transfers();
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
|
||||
r = init_capture();
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
|
||||
sigact.sa_handler = sighandler;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
sigaction(SIGTERM, &sigact, NULL);
|
||||
sigaction(SIGQUIT, &sigact, NULL);
|
||||
|
||||
while (!do_exit) {
|
||||
r = libusb_handle_events(NULL);
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
printf("shutting down...\n");
|
||||
|
||||
if (irq_transfer) {
|
||||
r = libusb_cancel_transfer(irq_transfer);
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
if (img_transfer) {
|
||||
r = libusb_cancel_transfer(img_transfer);
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
while (irq_transfer || img_transfer)
|
||||
if (libusb_handle_events(NULL) < 0)
|
||||
break;
|
||||
|
||||
if (do_exit == 1)
|
||||
r = 0;
|
||||
else
|
||||
r = 1;
|
||||
|
||||
out_deinit:
|
||||
libusb_free_transfer(img_transfer);
|
||||
libusb_free_transfer(irq_transfer);
|
||||
set_mode(0);
|
||||
set_hwstat(0x80);
|
||||
out_release:
|
||||
libusb_release_interface(devh, 0);
|
||||
out:
|
||||
libusb_close(devh);
|
||||
libusb_exit(NULL);
|
||||
return r >= 0 ? r : -r;
|
||||
}
|
||||
557
externals/libusb/libusb/examples/dpfp_threaded.c
vendored
Executable file
557
externals/libusb/libusb/examples/dpfp_threaded.c
vendored
Executable file
@@ -0,0 +1,557 @@
|
||||
/*
|
||||
* libusb example program to manipulate U.are.U 4000B fingerprint scanner.
|
||||
* Copyright © 2007 Daniel Drake <dsd@gentoo.org>
|
||||
* Copyright © 2016 Nathan Hjelm <hjelmn@mac.com>
|
||||
*
|
||||
* Basic image capture program only, does not consider the powerup quirks or
|
||||
* the fact that image encryption may be enabled. Not expected to work
|
||||
* flawlessly all of the time.
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "libusb.h"
|
||||
|
||||
#define EP_INTR (1 | LIBUSB_ENDPOINT_IN)
|
||||
#define EP_DATA (2 | LIBUSB_ENDPOINT_IN)
|
||||
#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN)
|
||||
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT)
|
||||
#define USB_RQ 0x04
|
||||
#define INTR_LENGTH 64
|
||||
#define SEM_NAME "/org.libusb.example.dpfp_threaded"
|
||||
|
||||
enum {
|
||||
MODE_INIT = 0x00,
|
||||
MODE_AWAIT_FINGER_ON = 0x10,
|
||||
MODE_AWAIT_FINGER_OFF = 0x12,
|
||||
MODE_CAPTURE = 0x20,
|
||||
MODE_SHUT_UP = 0x30,
|
||||
MODE_READY = 0x80,
|
||||
};
|
||||
|
||||
static int next_state(void);
|
||||
|
||||
enum {
|
||||
STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_ON = 1,
|
||||
STATE_AWAIT_IRQ_FINGER_DETECTED,
|
||||
STATE_AWAIT_MODE_CHANGE_CAPTURE,
|
||||
STATE_AWAIT_IMAGE,
|
||||
STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_OFF,
|
||||
STATE_AWAIT_IRQ_FINGER_REMOVED,
|
||||
};
|
||||
|
||||
static int state = 0;
|
||||
static struct libusb_device_handle *devh = NULL;
|
||||
static unsigned char imgbuf[0x1b340];
|
||||
static unsigned char irqbuf[INTR_LENGTH];
|
||||
static struct libusb_transfer *img_transfer = NULL;
|
||||
static struct libusb_transfer *irq_transfer = NULL;
|
||||
static int img_idx = 0;
|
||||
static volatile sig_atomic_t do_exit = 0;
|
||||
|
||||
static pthread_t poll_thread;
|
||||
static sem_t *exit_sem;
|
||||
|
||||
static void request_exit(sig_atomic_t code)
|
||||
{
|
||||
do_exit = code;
|
||||
sem_post(exit_sem);
|
||||
}
|
||||
|
||||
static void *poll_thread_main(void *arg)
|
||||
{
|
||||
int r = 0;
|
||||
printf("poll thread running\n");
|
||||
|
||||
(void)arg;
|
||||
|
||||
while (!do_exit) {
|
||||
struct timeval tv = { 1, 0 };
|
||||
r = libusb_handle_events_timeout(NULL, &tv);
|
||||
if (r < 0) {
|
||||
request_exit(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("poll thread shutting down\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int find_dpfp_device(void)
|
||||
{
|
||||
devh = libusb_open_device_with_vid_pid(NULL, 0x05ba, 0x000a);
|
||||
return devh ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int print_f0_data(void)
|
||||
{
|
||||
unsigned char data[0x10];
|
||||
int r;
|
||||
unsigned int i;
|
||||
|
||||
r = libusb_control_transfer(devh, CTRL_IN, USB_RQ, 0xf0, 0, data,
|
||||
sizeof(data), 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "F0 error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < sizeof(data)) {
|
||||
fprintf(stderr, "short read (%d)\n", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("F0 data:");
|
||||
for (i = 0; i < sizeof(data); i++)
|
||||
printf("%02x ", data[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_hwstat(unsigned char *status)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = libusb_control_transfer(devh, CTRL_IN, USB_RQ, 0x07, 0, status, 1, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "read hwstat error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < 1) {
|
||||
fprintf(stderr, "short read (%d)\n", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("hwstat reads %02x\n", *status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_hwstat(unsigned char data)
|
||||
{
|
||||
int r;
|
||||
|
||||
printf("set hwstat to %02x\n", data);
|
||||
r = libusb_control_transfer(devh, CTRL_OUT, USB_RQ, 0x07, 0, &data, 1, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "set hwstat error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < 1) {
|
||||
fprintf(stderr, "short write (%d)", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_mode(unsigned char data)
|
||||
{
|
||||
int r;
|
||||
printf("set mode %02x\n", data);
|
||||
|
||||
r = libusb_control_transfer(devh, CTRL_OUT, USB_RQ, 0x4e, 0, &data, 1, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "set mode error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if ((unsigned int) r < 1) {
|
||||
fprintf(stderr, "short write (%d)", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL cb_mode_changed(struct libusb_transfer *transfer)
|
||||
{
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "mode change transfer not completed!\n");
|
||||
request_exit(2);
|
||||
}
|
||||
|
||||
printf("async cb_mode_changed length=%d actual_length=%d\n",
|
||||
transfer->length, transfer->actual_length);
|
||||
if (next_state() < 0)
|
||||
request_exit(2);
|
||||
}
|
||||
|
||||
static int set_mode_async(unsigned char data)
|
||||
{
|
||||
unsigned char *buf = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
|
||||
struct libusb_transfer *transfer;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
transfer = libusb_alloc_transfer(0);
|
||||
if (!transfer) {
|
||||
free(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
printf("async set mode %02x\n", data);
|
||||
libusb_fill_control_setup(buf, CTRL_OUT, USB_RQ, 0x4e, 0, 1);
|
||||
buf[LIBUSB_CONTROL_SETUP_SIZE] = data;
|
||||
libusb_fill_control_transfer(transfer, devh, buf, cb_mode_changed, NULL,
|
||||
1000);
|
||||
|
||||
transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK
|
||||
| LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
return libusb_submit_transfer(transfer);
|
||||
}
|
||||
|
||||
static int do_sync_intr(unsigned char *data)
|
||||
{
|
||||
int r;
|
||||
int transferred;
|
||||
|
||||
r = libusb_interrupt_transfer(devh, EP_INTR, data, INTR_LENGTH,
|
||||
&transferred, 1000);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "intr error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
if (transferred < INTR_LENGTH) {
|
||||
fprintf(stderr, "short read (%d)\n", r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("recv interrupt %04x\n", *((uint16_t *) data));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sync_intr(unsigned char type)
|
||||
{
|
||||
int r;
|
||||
unsigned char data[INTR_LENGTH];
|
||||
|
||||
while (1) {
|
||||
r = do_sync_intr(data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (data[0] == type)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int save_to_file(unsigned char *data)
|
||||
{
|
||||
FILE *fd;
|
||||
char filename[64];
|
||||
|
||||
snprintf(filename, sizeof(filename), "finger%d.pgm", img_idx++);
|
||||
fd = fopen(filename, "w");
|
||||
if (!fd)
|
||||
return -1;
|
||||
|
||||
fputs("P5 384 289 255 ", fd);
|
||||
(void) fwrite(data + 64, 1, 384*289, fd);
|
||||
fclose(fd);
|
||||
printf("saved image to %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int next_state(void)
|
||||
{
|
||||
int r = 0;
|
||||
printf("old state: %d\n", state);
|
||||
switch (state) {
|
||||
case STATE_AWAIT_IRQ_FINGER_REMOVED:
|
||||
state = STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_ON;
|
||||
r = set_mode_async(MODE_AWAIT_FINGER_ON);
|
||||
break;
|
||||
case STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_ON:
|
||||
state = STATE_AWAIT_IRQ_FINGER_DETECTED;
|
||||
break;
|
||||
case STATE_AWAIT_IRQ_FINGER_DETECTED:
|
||||
state = STATE_AWAIT_MODE_CHANGE_CAPTURE;
|
||||
r = set_mode_async(MODE_CAPTURE);
|
||||
break;
|
||||
case STATE_AWAIT_MODE_CHANGE_CAPTURE:
|
||||
state = STATE_AWAIT_IMAGE;
|
||||
break;
|
||||
case STATE_AWAIT_IMAGE:
|
||||
state = STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_OFF;
|
||||
r = set_mode_async(MODE_AWAIT_FINGER_OFF);
|
||||
break;
|
||||
case STATE_AWAIT_MODE_CHANGE_AWAIT_FINGER_OFF:
|
||||
state = STATE_AWAIT_IRQ_FINGER_REMOVED;
|
||||
break;
|
||||
default:
|
||||
printf("unrecognised state %d\n", state);
|
||||
}
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "error detected changing state\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("new state: %d\n", state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL cb_irq(struct libusb_transfer *transfer)
|
||||
{
|
||||
unsigned char irqtype = transfer->buffer[0];
|
||||
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "irq transfer status %d?\n", transfer->status);
|
||||
irq_transfer = NULL;
|
||||
request_exit(2);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("IRQ callback %02x\n", irqtype);
|
||||
switch (state) {
|
||||
case STATE_AWAIT_IRQ_FINGER_DETECTED:
|
||||
if (irqtype == 0x01) {
|
||||
if (next_state() < 0) {
|
||||
request_exit(2);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("finger-on-sensor detected in wrong state!\n");
|
||||
}
|
||||
break;
|
||||
case STATE_AWAIT_IRQ_FINGER_REMOVED:
|
||||
if (irqtype == 0x02) {
|
||||
if (next_state() < 0) {
|
||||
request_exit(2);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("finger-on-sensor detected in wrong state!\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (libusb_submit_transfer(irq_transfer) < 0)
|
||||
request_exit(2);
|
||||
}
|
||||
|
||||
static void LIBUSB_CALL cb_img(struct libusb_transfer *transfer)
|
||||
{
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "img transfer status %d?\n", transfer->status);
|
||||
img_transfer = NULL;
|
||||
request_exit(2);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Image callback\n");
|
||||
save_to_file(imgbuf);
|
||||
if (next_state() < 0) {
|
||||
request_exit(2);
|
||||
return;
|
||||
}
|
||||
if (libusb_submit_transfer(img_transfer) < 0)
|
||||
request_exit(2);
|
||||
}
|
||||
|
||||
static int init_capture(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = libusb_submit_transfer(irq_transfer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = libusb_submit_transfer(img_transfer);
|
||||
if (r < 0) {
|
||||
libusb_cancel_transfer(irq_transfer);
|
||||
while (irq_transfer)
|
||||
if (libusb_handle_events(NULL) < 0)
|
||||
break;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* start state machine */
|
||||
state = STATE_AWAIT_IRQ_FINGER_REMOVED;
|
||||
return next_state();
|
||||
}
|
||||
|
||||
static int do_init(void)
|
||||
{
|
||||
unsigned char status;
|
||||
int r;
|
||||
|
||||
r = get_hwstat(&status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!(status & 0x80)) {
|
||||
r = set_hwstat(status | 0x80);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = get_hwstat(&status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
status &= ~0x80;
|
||||
r = set_hwstat(status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_hwstat(&status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sync_intr(0x56);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_transfers(void)
|
||||
{
|
||||
img_transfer = libusb_alloc_transfer(0);
|
||||
if (!img_transfer)
|
||||
return -ENOMEM;
|
||||
|
||||
irq_transfer = libusb_alloc_transfer(0);
|
||||
if (!irq_transfer)
|
||||
return -ENOMEM;
|
||||
|
||||
libusb_fill_bulk_transfer(img_transfer, devh, EP_DATA, imgbuf,
|
||||
sizeof(imgbuf), cb_img, NULL, 0);
|
||||
libusb_fill_interrupt_transfer(irq_transfer, devh, EP_INTR, irqbuf,
|
||||
sizeof(irqbuf), cb_irq, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sighandler(int signum)
|
||||
{
|
||||
(void)signum;
|
||||
|
||||
request_exit(1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
int r = 1;
|
||||
|
||||
exit_sem = sem_open (SEM_NAME, O_CREAT, 0);
|
||||
if (!exit_sem) {
|
||||
fprintf(stderr, "failed to initialise semaphore error %d", errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* only using this semaphore in this process so go ahead and unlink it now */
|
||||
sem_unlink (SEM_NAME);
|
||||
|
||||
r = libusb_init(NULL);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to initialise libusb\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r = find_dpfp_device();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Could not find/open device\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = libusb_claim_interface(devh, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r));
|
||||
goto out;
|
||||
}
|
||||
printf("claimed interface\n");
|
||||
|
||||
r = print_f0_data();
|
||||
if (r < 0)
|
||||
goto out_release;
|
||||
|
||||
r = do_init();
|
||||
if (r < 0)
|
||||
goto out_deinit;
|
||||
|
||||
/* async from here onwards */
|
||||
|
||||
sigact.sa_handler = sighandler;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
sigaction(SIGTERM, &sigact, NULL);
|
||||
sigaction(SIGQUIT, &sigact, NULL);
|
||||
|
||||
r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL);
|
||||
if (r)
|
||||
goto out_deinit;
|
||||
|
||||
r = alloc_transfers();
|
||||
if (r < 0) {
|
||||
request_exit(1);
|
||||
pthread_join(poll_thread, NULL);
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
r = init_capture();
|
||||
if (r < 0) {
|
||||
request_exit(1);
|
||||
pthread_join(poll_thread, NULL);
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
while (!do_exit)
|
||||
sem_wait(exit_sem);
|
||||
|
||||
printf("shutting down...\n");
|
||||
pthread_join(poll_thread, NULL);
|
||||
|
||||
r = libusb_cancel_transfer(irq_transfer);
|
||||
if (r < 0) {
|
||||
request_exit(1);
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
r = libusb_cancel_transfer(img_transfer);
|
||||
if (r < 0) {
|
||||
request_exit(1);
|
||||
goto out_deinit;
|
||||
}
|
||||
|
||||
while (img_transfer || irq_transfer)
|
||||
if (libusb_handle_events(NULL) < 0)
|
||||
break;
|
||||
|
||||
if (do_exit == 1)
|
||||
r = 0;
|
||||
else
|
||||
r = 1;
|
||||
|
||||
out_deinit:
|
||||
libusb_free_transfer(img_transfer);
|
||||
libusb_free_transfer(irq_transfer);
|
||||
set_mode(0);
|
||||
set_hwstat(0x80);
|
||||
out_release:
|
||||
libusb_release_interface(devh, 0);
|
||||
out:
|
||||
libusb_close(devh);
|
||||
libusb_exit(NULL);
|
||||
return r >= 0 ? r : -r;
|
||||
}
|
||||
831
externals/libusb/libusb/examples/ezusb.c
vendored
Executable file
831
externals/libusb/libusb/examples/ezusb.c
vendored
Executable file
@@ -0,0 +1,831 @@
|
||||
/*
|
||||
* Copyright © 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
|
||||
* Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
|
||||
* Copyright © 2012 Pete Batard (pete@akeo.ie)
|
||||
* Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libusb.h"
|
||||
#include "ezusb.h"
|
||||
|
||||
extern void logerror(const char *format, ...)
|
||||
__attribute__ ((format(printf, 1, 2)));
|
||||
|
||||
/*
|
||||
* This file contains functions for uploading firmware into Cypress
|
||||
* EZ-USB microcontrollers. These chips use control endpoint 0 and vendor
|
||||
* specific commands to support writing into the on-chip SRAM. They also
|
||||
* support writing into the CPUCS register, which is how we reset the
|
||||
* processor after loading firmware (including the reset vector).
|
||||
*
|
||||
* These Cypress devices are 8-bit 8051 based microcontrollers with
|
||||
* special support for USB I/O. They come in several packages, and
|
||||
* some can be set up with external memory when device costs allow.
|
||||
* Note that the design was originally by AnchorChips, so you may find
|
||||
* references to that vendor (which was later merged into Cypress).
|
||||
* The Cypress FX parts are largely compatible with the Anchorhip ones.
|
||||
*/
|
||||
|
||||
int verbose = 1;
|
||||
|
||||
/*
|
||||
* return true if [addr,addr+len] includes external RAM
|
||||
* for Anchorchips EZ-USB or Cypress EZ-USB FX
|
||||
*/
|
||||
static bool fx_is_external(uint32_t addr, size_t len)
|
||||
{
|
||||
/* with 8KB RAM, 0x0000-0x1b3f can be written
|
||||
* we can't tell if it's a 4KB device here
|
||||
*/
|
||||
if (addr <= 0x1b3f)
|
||||
return ((addr + len) > 0x1b40);
|
||||
|
||||
/* there may be more RAM; unclear if we can write it.
|
||||
* some bulk buffers may be unused, 0x1b3f-0x1f3f
|
||||
* firmware can set ISODISAB for 2KB at 0x2000-0x27ff
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* return true if [addr,addr+len] includes external RAM
|
||||
* for Cypress EZ-USB FX2
|
||||
*/
|
||||
static bool fx2_is_external(uint32_t addr, size_t len)
|
||||
{
|
||||
/* 1st 8KB for data/code, 0x0000-0x1fff */
|
||||
if (addr <= 0x1fff)
|
||||
return ((addr + len) > 0x2000);
|
||||
|
||||
/* and 512 for data, 0xe000-0xe1ff */
|
||||
else if (addr >= 0xe000 && addr <= 0xe1ff)
|
||||
return ((addr + len) > 0xe200);
|
||||
|
||||
/* otherwise, it's certainly external */
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* return true if [addr,addr+len] includes external RAM
|
||||
* for Cypress EZ-USB FX2LP
|
||||
*/
|
||||
static bool fx2lp_is_external(uint32_t addr, size_t len)
|
||||
{
|
||||
/* 1st 16KB for data/code, 0x0000-0x3fff */
|
||||
if (addr <= 0x3fff)
|
||||
return ((addr + len) > 0x4000);
|
||||
|
||||
/* and 512 for data, 0xe000-0xe1ff */
|
||||
else if (addr >= 0xe000 && addr <= 0xe1ff)
|
||||
return ((addr + len) > 0xe200);
|
||||
|
||||
/* otherwise, it's certainly external */
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* These are the requests (bRequest) that the bootstrap loader is expected
|
||||
* to recognize. The codes are reserved by Cypress, and these values match
|
||||
* what EZ-USB hardware, or "Vend_Ax" firmware (2nd stage loader) uses.
|
||||
* Cypress' "a3load" is nice because it supports both FX and FX2, although
|
||||
* it doesn't have the EEPROM support (subset of "Vend_Ax").
|
||||
*/
|
||||
#define RW_INTERNAL 0xA0 /* hardware implements this one */
|
||||
#define RW_MEMORY 0xA3
|
||||
|
||||
/*
|
||||
* Issues the specified vendor-specific write request.
|
||||
*/
|
||||
static int ezusb_write(libusb_device_handle *device, const char *label,
|
||||
uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (verbose > 1)
|
||||
logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
|
||||
status = libusb_control_transfer(device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||
opcode, addr & 0xFFFF, addr >> 16,
|
||||
(unsigned char*)data, (uint16_t)len, 1000);
|
||||
if (status != (signed)len) {
|
||||
if (status < 0)
|
||||
logerror("%s: %s\n", label, libusb_error_name(status));
|
||||
else
|
||||
logerror("%s ==> %d\n", label, status);
|
||||
}
|
||||
return (status < 0) ? -EIO : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issues the specified vendor-specific read request.
|
||||
*/
|
||||
static int ezusb_read(libusb_device_handle *device, const char *label,
|
||||
uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (verbose > 1)
|
||||
logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
|
||||
status = libusb_control_transfer(device,
|
||||
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||
opcode, addr & 0xFFFF, addr >> 16,
|
||||
(unsigned char*)data, (uint16_t)len, 1000);
|
||||
if (status != (signed)len) {
|
||||
if (status < 0)
|
||||
logerror("%s: %s\n", label, libusb_error_name(status));
|
||||
else
|
||||
logerror("%s ==> %d\n", label, status);
|
||||
}
|
||||
return (status < 0) ? -EIO : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modifies the CPUCS register to stop or reset the CPU.
|
||||
* Returns false on error.
|
||||
*/
|
||||
static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun)
|
||||
{
|
||||
int status;
|
||||
uint8_t data = doRun ? 0x00 : 0x01;
|
||||
|
||||
if (verbose)
|
||||
logerror("%s\n", data ? "stop CPU" : "reset CPU");
|
||||
status = libusb_control_transfer(device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||
RW_INTERNAL, addr & 0xFFFF, addr >> 16,
|
||||
&data, 1, 1000);
|
||||
if ((status != 1) &&
|
||||
/* We may get an I/O error from libusb as the device disappears */
|
||||
((!doRun) || (status != LIBUSB_ERROR_IO)))
|
||||
{
|
||||
const char *mesg = "can't modify CPUCS";
|
||||
if (status < 0)
|
||||
logerror("%s: %s\n", mesg, libusb_error_name(status));
|
||||
else
|
||||
logerror("%s\n", mesg);
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an FX3 jumpt to address command
|
||||
* Returns false on error.
|
||||
*/
|
||||
static bool ezusb_fx3_jump(libusb_device_handle *device, uint32_t addr)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (verbose)
|
||||
logerror("transfer execution to Program Entry at 0x%08x\n", addr);
|
||||
status = libusb_control_transfer(device,
|
||||
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
||||
RW_INTERNAL, addr & 0xFFFF, addr >> 16,
|
||||
NULL, 0, 1000);
|
||||
/* We may get an I/O error from libusb as the device disappears */
|
||||
if ((status != 0) && (status != LIBUSB_ERROR_IO))
|
||||
{
|
||||
const char *mesg = "failed to send jump command";
|
||||
if (status < 0)
|
||||
logerror("%s: %s\n", mesg, libusb_error_name(status));
|
||||
else
|
||||
logerror("%s\n", mesg);
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Parse an Intel HEX image file and invoke the poke() function on the
|
||||
* various segments to implement policies such as writing to RAM (with
|
||||
* a one or two stage loader setup, depending on the firmware) or to
|
||||
* EEPROM (two stages required).
|
||||
*
|
||||
* image - the hex image file
|
||||
* context - for use by poke()
|
||||
* is_external - if non-null, used to check which segments go into
|
||||
* external memory (writable only by software loader)
|
||||
* poke - called with each memory segment; errors indicated
|
||||
* by returning negative values.
|
||||
*
|
||||
* Caller is responsible for halting CPU as needed, such as when
|
||||
* overwriting a second stage loader.
|
||||
*/
|
||||
static int parse_ihex(FILE *image, void *context,
|
||||
bool (*is_external)(uint32_t addr, size_t len),
|
||||
int (*poke) (void *context, uint32_t addr, bool external,
|
||||
const unsigned char *data, size_t len))
|
||||
{
|
||||
unsigned char data[1023];
|
||||
uint32_t data_addr = 0;
|
||||
size_t data_len = 0;
|
||||
int rc;
|
||||
int first_line = 1;
|
||||
bool external = false;
|
||||
|
||||
/* Read the input file as an IHEX file, and report the memory segments
|
||||
* as we go. Each line holds a max of 16 bytes, but uploading is
|
||||
* faster (and EEPROM space smaller) if we merge those lines into larger
|
||||
* chunks. Most hex files keep memory segments together, which makes
|
||||
* such merging all but free. (But it may still be worth sorting the
|
||||
* hex files to make up for undesirable behavior from tools.)
|
||||
*
|
||||
* Note that EEPROM segments max out at 1023 bytes; the upload protocol
|
||||
* allows segments of up to 64 KBytes (more than a loader could handle).
|
||||
*/
|
||||
for (;;) {
|
||||
char buf[512], *cp;
|
||||
char tmp, type;
|
||||
size_t len;
|
||||
unsigned idx, off;
|
||||
|
||||
cp = fgets(buf, sizeof(buf), image);
|
||||
if (cp == NULL) {
|
||||
logerror("EOF without EOF record!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
|
||||
if (buf[0] != ':') {
|
||||
logerror("not an ihex record: %s", buf);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* ignore any newline */
|
||||
cp = strchr(buf, '\n');
|
||||
if (cp)
|
||||
*cp = 0;
|
||||
|
||||
if (verbose >= 3)
|
||||
logerror("** LINE: %s\n", buf);
|
||||
|
||||
/* Read the length field (up to 16 bytes) */
|
||||
tmp = buf[3];
|
||||
buf[3] = 0;
|
||||
len = strtoul(buf+1, NULL, 16);
|
||||
buf[3] = tmp;
|
||||
|
||||
/* Read the target offset (address up to 64KB) */
|
||||
tmp = buf[7];
|
||||
buf[7] = 0;
|
||||
off = (unsigned int)strtoul(buf+3, NULL, 16);
|
||||
buf[7] = tmp;
|
||||
|
||||
/* Initialize data_addr */
|
||||
if (first_line) {
|
||||
data_addr = off;
|
||||
first_line = 0;
|
||||
}
|
||||
|
||||
/* Read the record type */
|
||||
tmp = buf[9];
|
||||
buf[9] = 0;
|
||||
type = (char)strtoul(buf+7, NULL, 16);
|
||||
buf[9] = tmp;
|
||||
|
||||
/* If this is an EOF record, then make it so. */
|
||||
if (type == 1) {
|
||||
if (verbose >= 2)
|
||||
logerror("EOF on hexfile\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (type != 0) {
|
||||
logerror("unsupported record type: %u\n", type);
|
||||
return -3;
|
||||
}
|
||||
|
||||
if ((len * 2) + 11 > strlen(buf)) {
|
||||
logerror("record too short?\n");
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* FIXME check for _physically_ contiguous not just virtually
|
||||
* e.g. on FX2 0x1f00-0x2100 includes both on-chip and external
|
||||
* memory so it's not really contiguous */
|
||||
|
||||
/* flush the saved data if it's not contiguous,
|
||||
* or when we've buffered as much as we can.
|
||||
*/
|
||||
if (data_len != 0
|
||||
&& (off != (data_addr + data_len)
|
||||
/* || !merge */
|
||||
|| (data_len + len) > sizeof(data))) {
|
||||
if (is_external)
|
||||
external = is_external(data_addr, data_len);
|
||||
rc = poke(context, data_addr, external, data, data_len);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
data_addr = off;
|
||||
data_len = 0;
|
||||
}
|
||||
|
||||
/* append to saved data, flush later */
|
||||
for (idx = 0, cp = buf+9 ; idx < len ; idx += 1, cp += 2) {
|
||||
tmp = cp[2];
|
||||
cp[2] = 0;
|
||||
data[data_len + idx] = (uint8_t)strtoul(cp, NULL, 16);
|
||||
cp[2] = tmp;
|
||||
}
|
||||
data_len += len;
|
||||
}
|
||||
|
||||
|
||||
/* flush any data remaining */
|
||||
if (data_len != 0) {
|
||||
if (is_external)
|
||||
external = is_external(data_addr, data_len);
|
||||
rc = poke(context, data_addr, external, data, data_len);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a binary image file and write it as is to the target.
|
||||
* Applies to Cypress BIX images for RAM or Cypress IIC images
|
||||
* for EEPROM.
|
||||
*
|
||||
* image - the BIX image file
|
||||
* context - for use by poke()
|
||||
* is_external - if non-null, used to check which segments go into
|
||||
* external memory (writable only by software loader)
|
||||
* poke - called with each memory segment; errors indicated
|
||||
* by returning negative values.
|
||||
*
|
||||
* Caller is responsible for halting CPU as needed, such as when
|
||||
* overwriting a second stage loader.
|
||||
*/
|
||||
static int parse_bin(FILE *image, void *context,
|
||||
bool (*is_external)(uint32_t addr, size_t len), int (*poke)(void *context,
|
||||
uint32_t addr, bool external, const unsigned char *data, size_t len))
|
||||
{
|
||||
unsigned char data[4096];
|
||||
uint32_t data_addr = 0;
|
||||
size_t data_len = 0;
|
||||
int rc;
|
||||
bool external = false;
|
||||
|
||||
for (;;) {
|
||||
data_len = fread(data, 1, 4096, image);
|
||||
if (data_len == 0)
|
||||
break;
|
||||
if (is_external)
|
||||
external = is_external(data_addr, data_len);
|
||||
rc = poke(context, data_addr, external, data, data_len);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
data_addr += (uint32_t)data_len;
|
||||
}
|
||||
return feof(image)?0:-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a Cypress IIC image file and invoke the poke() function on the
|
||||
* various segments for writing to RAM
|
||||
*
|
||||
* image - the IIC image file
|
||||
* context - for use by poke()
|
||||
* is_external - if non-null, used to check which segments go into
|
||||
* external memory (writable only by software loader)
|
||||
* poke - called with each memory segment; errors indicated
|
||||
* by returning negative values.
|
||||
*
|
||||
* Caller is responsible for halting CPU as needed, such as when
|
||||
* overwriting a second stage loader.
|
||||
*/
|
||||
static int parse_iic(FILE *image, void *context,
|
||||
bool (*is_external)(uint32_t addr, size_t len),
|
||||
int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
|
||||
{
|
||||
unsigned char data[4096];
|
||||
uint32_t data_addr = 0;
|
||||
size_t data_len = 0, read_len;
|
||||
uint8_t block_header[4];
|
||||
int rc;
|
||||
bool external = false;
|
||||
long file_size, initial_pos;
|
||||
|
||||
initial_pos = ftell(image);
|
||||
if (initial_pos < 0)
|
||||
return -1;
|
||||
|
||||
if (fseek(image, 0L, SEEK_END) != 0)
|
||||
return -1;
|
||||
file_size = ftell(image);
|
||||
if (fseek(image, initial_pos, SEEK_SET) != 0)
|
||||
return -1;
|
||||
for (;;) {
|
||||
/* Ignore the trailing reset IIC data (5 bytes) */
|
||||
if (ftell(image) >= (file_size - 5))
|
||||
break;
|
||||
if (fread(&block_header, 1, sizeof(block_header), image) != 4) {
|
||||
logerror("unable to read IIC block header\n");
|
||||
return -1;
|
||||
}
|
||||
data_len = (block_header[0] << 8) + block_header[1];
|
||||
data_addr = (block_header[2] << 8) + block_header[3];
|
||||
if (data_len > sizeof(data)) {
|
||||
/* If this is ever reported as an error, switch to using malloc/realloc */
|
||||
logerror("IIC data block too small - please report this error to libusb.info\n");
|
||||
return -1;
|
||||
}
|
||||
read_len = fread(data, 1, data_len, image);
|
||||
if (read_len != data_len) {
|
||||
logerror("read error\n");
|
||||
return -1;
|
||||
}
|
||||
if (is_external)
|
||||
external = is_external(data_addr, data_len);
|
||||
rc = poke(context, data_addr, external, data, data_len);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the parse call will be selected according to the image type */
|
||||
static int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
|
||||
int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
|
||||
= { parse_ihex, parse_iic, parse_bin };
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* For writing to RAM using a first (hardware) or second (software)
|
||||
* stage loader and 0xA0 or 0xA3 vendor requests
|
||||
*/
|
||||
typedef enum {
|
||||
_undef = 0,
|
||||
internal_only, /* hardware first-stage loader */
|
||||
skip_internal, /* first phase, second-stage loader */
|
||||
skip_external /* second phase, second-stage loader */
|
||||
} ram_mode;
|
||||
|
||||
struct ram_poke_context {
|
||||
libusb_device_handle *device;
|
||||
ram_mode mode;
|
||||
size_t total, count;
|
||||
};
|
||||
|
||||
#define RETRY_LIMIT 5
|
||||
|
||||
static int ram_poke(void *context, uint32_t addr, bool external,
|
||||
const unsigned char *data, size_t len)
|
||||
{
|
||||
struct ram_poke_context *ctx = (struct ram_poke_context*)context;
|
||||
int rc;
|
||||
unsigned retry = 0;
|
||||
|
||||
switch (ctx->mode) {
|
||||
case internal_only: /* CPU should be stopped */
|
||||
if (external) {
|
||||
logerror("can't write %u bytes external memory at 0x%08x\n",
|
||||
(unsigned)len, addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case skip_internal: /* CPU must be running */
|
||||
if (!external) {
|
||||
if (verbose >= 2) {
|
||||
logerror("SKIP on-chip RAM, %u bytes at 0x%08x\n",
|
||||
(unsigned)len, addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case skip_external: /* CPU should be stopped */
|
||||
if (external) {
|
||||
if (verbose >= 2) {
|
||||
logerror("SKIP external RAM, %u bytes at 0x%08x\n",
|
||||
(unsigned)len, addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case _undef:
|
||||
default:
|
||||
logerror("bug\n");
|
||||
return -EDOM;
|
||||
}
|
||||
|
||||
ctx->total += len;
|
||||
ctx->count++;
|
||||
|
||||
/* Retry this till we get a real error. Control messages are not
|
||||
* NAKed (just dropped) so time out means is a real problem.
|
||||
*/
|
||||
while ((rc = ezusb_write(ctx->device,
|
||||
external ? "write external" : "write on-chip",
|
||||
external ? RW_MEMORY : RW_INTERNAL,
|
||||
addr, data, len)) < 0
|
||||
&& retry < RETRY_LIMIT) {
|
||||
if (rc != LIBUSB_ERROR_TIMEOUT)
|
||||
break;
|
||||
retry += 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load a Cypress Image file into target RAM.
|
||||
* See http://www.cypress.com/?docID=41351 (AN76405 PDF) for more info.
|
||||
*/
|
||||
static int fx3_load_ram(libusb_device_handle *device, const char *path)
|
||||
{
|
||||
uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength;
|
||||
uint32_t* dImageBuf;
|
||||
unsigned char *bBuf, hBuf[4], blBuf[4], rBuf[4096];
|
||||
FILE *image;
|
||||
int ret = 0;
|
||||
|
||||
image = fopen(path, "rb");
|
||||
if (image == NULL) {
|
||||
logerror("unable to open '%s' for input\n", path);
|
||||
return -2;
|
||||
} else if (verbose)
|
||||
logerror("open firmware image %s for RAM upload\n", path);
|
||||
|
||||
// Read header
|
||||
if (fread(hBuf, sizeof(char), sizeof(hBuf), image) != sizeof(hBuf)) {
|
||||
logerror("could not read image header");
|
||||
ret = -3;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// check "CY" signature byte and format
|
||||
if ((hBuf[0] != 'C') || (hBuf[1] != 'Y')) {
|
||||
logerror("image doesn't have a CYpress signature\n");
|
||||
ret = -3;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Check bImageType
|
||||
switch(hBuf[3]) {
|
||||
case 0xB0:
|
||||
if (verbose)
|
||||
logerror("normal FW binary %s image with checksum\n", (hBuf[2]&0x01)?"data":"executable");
|
||||
break;
|
||||
case 0xB1:
|
||||
logerror("security binary image is not currently supported\n");
|
||||
ret = -3;
|
||||
goto exit;
|
||||
case 0xB2:
|
||||
logerror("VID:PID image is not currently supported\n");
|
||||
ret = -3;
|
||||
goto exit;
|
||||
default:
|
||||
logerror("invalid image type 0x%02X\n", hBuf[3]);
|
||||
ret = -3;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Read the bootloader version
|
||||
if (verbose) {
|
||||
if ((ezusb_read(device, "read bootloader version", RW_INTERNAL, 0xFFFF0020, blBuf, 4) < 0)) {
|
||||
logerror("Could not read bootloader version\n");
|
||||
ret = -8;
|
||||
goto exit;
|
||||
}
|
||||
logerror("FX3 bootloader version: 0x%02X%02X%02X%02X\n", blBuf[3], blBuf[2], blBuf[1], blBuf[0]);
|
||||
}
|
||||
|
||||
dCheckSum = 0;
|
||||
if (verbose)
|
||||
logerror("writing image...\n");
|
||||
while (1) {
|
||||
if ((fread(&dLength, sizeof(uint32_t), 1, image) != 1) || // read dLength
|
||||
(fread(&dAddress, sizeof(uint32_t), 1, image) != 1)) { // read dAddress
|
||||
logerror("could not read image");
|
||||
ret = -3;
|
||||
goto exit;
|
||||
}
|
||||
if (dLength == 0)
|
||||
break; // done
|
||||
|
||||
// coverity[tainted_data]
|
||||
dImageBuf = (uint32_t*)calloc(dLength, sizeof(uint32_t));
|
||||
if (dImageBuf == NULL) {
|
||||
logerror("could not allocate buffer for image chunk\n");
|
||||
ret = -4;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// read sections
|
||||
if (fread(dImageBuf, sizeof(uint32_t), dLength, image) != dLength) {
|
||||
logerror("could not read image");
|
||||
free(dImageBuf);
|
||||
ret = -3;
|
||||
goto exit;
|
||||
}
|
||||
for (i = 0; i < dLength; i++)
|
||||
dCheckSum += dImageBuf[i];
|
||||
dLength <<= 2; // convert to Byte length
|
||||
bBuf = (unsigned char*) dImageBuf;
|
||||
|
||||
while (dLength > 0) {
|
||||
dLen = 4096; // 4K max
|
||||
if (dLen > dLength)
|
||||
dLen = dLength;
|
||||
if ((ezusb_write(device, "write firmware", RW_INTERNAL, dAddress, bBuf, dLen) < 0) ||
|
||||
(ezusb_read(device, "read firmware", RW_INTERNAL, dAddress, rBuf, dLen) < 0)) {
|
||||
logerror("R/W error\n");
|
||||
free(dImageBuf);
|
||||
ret = -5;
|
||||
goto exit;
|
||||
}
|
||||
// Verify data: rBuf with bBuf
|
||||
for (i = 0; i < dLen; i++) {
|
||||
if (rBuf[i] != bBuf[i]) {
|
||||
logerror("verify error");
|
||||
free(dImageBuf);
|
||||
ret = -6;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
dLength -= dLen;
|
||||
bBuf += dLen;
|
||||
dAddress += dLen;
|
||||
}
|
||||
free(dImageBuf);
|
||||
}
|
||||
|
||||
// read pre-computed checksum data
|
||||
if ((fread(&dExpectedCheckSum, sizeof(uint32_t), 1, image) != 1) ||
|
||||
(dCheckSum != dExpectedCheckSum)) {
|
||||
logerror("checksum error\n");
|
||||
ret = -7;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// transfer execution to Program Entry
|
||||
if (!ezusb_fx3_jump(device, dAddress)) {
|
||||
ret = -6;
|
||||
}
|
||||
|
||||
exit:
|
||||
fclose(image);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load a firmware file into target RAM. device is the open libusb
|
||||
* device, and the path is the name of the source file. Open the file,
|
||||
* parse the bytes, and write them in one or two phases.
|
||||
*
|
||||
* If stage == 0, this uses the first stage loader, built into EZ-USB
|
||||
* hardware but limited to writing on-chip memory or CPUCS. Everything
|
||||
* is written during one stage, unless there's an error such as the image
|
||||
* holding data that needs to be written to external memory.
|
||||
*
|
||||
* Otherwise, things are written in two stages. First the external
|
||||
* memory is written, expecting a second stage loader to have already
|
||||
* been loaded. Then file is re-parsed and on-chip memory is written.
|
||||
*/
|
||||
int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type, int img_type, int stage)
|
||||
{
|
||||
FILE *image;
|
||||
uint32_t cpucs_addr;
|
||||
bool (*is_external)(uint32_t off, size_t len);
|
||||
struct ram_poke_context ctx;
|
||||
int status;
|
||||
uint8_t iic_header[8] = { 0 };
|
||||
int ret = 0;
|
||||
|
||||
if (fx_type == FX_TYPE_FX3)
|
||||
return fx3_load_ram(device, path);
|
||||
|
||||
image = fopen(path, "rb");
|
||||
if (image == NULL) {
|
||||
logerror("%s: unable to open for input.\n", path);
|
||||
return -2;
|
||||
} else if (verbose > 1)
|
||||
logerror("open firmware image %s for RAM upload\n", path);
|
||||
|
||||
if (img_type == IMG_TYPE_IIC) {
|
||||
if ( (fread(iic_header, 1, sizeof(iic_header), image) != sizeof(iic_header))
|
||||
|| (((fx_type == FX_TYPE_FX2LP) || (fx_type == FX_TYPE_FX2)) && (iic_header[0] != 0xC2))
|
||||
|| ((fx_type == FX_TYPE_AN21) && (iic_header[0] != 0xB2))
|
||||
|| ((fx_type == FX_TYPE_FX1) && (iic_header[0] != 0xB6)) ) {
|
||||
logerror("IIC image does not contain executable code - cannot load to RAM.\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* EZ-USB original/FX and FX2 devices differ, apart from the 8051 core */
|
||||
switch(fx_type) {
|
||||
case FX_TYPE_FX2LP:
|
||||
cpucs_addr = 0xe600;
|
||||
is_external = fx2lp_is_external;
|
||||
break;
|
||||
case FX_TYPE_FX2:
|
||||
cpucs_addr = 0xe600;
|
||||
is_external = fx2_is_external;
|
||||
break;
|
||||
default:
|
||||
cpucs_addr = 0x7f92;
|
||||
is_external = fx_is_external;
|
||||
break;
|
||||
}
|
||||
|
||||
/* use only first stage loader? */
|
||||
if (stage == 0) {
|
||||
ctx.mode = internal_only;
|
||||
|
||||
/* if required, halt the CPU while we overwrite its code/data */
|
||||
if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
|
||||
{
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 2nd stage, first part? loader was already uploaded */
|
||||
} else {
|
||||
ctx.mode = skip_internal;
|
||||
|
||||
/* let CPU run; overwrite the 2nd stage loader later */
|
||||
if (verbose)
|
||||
logerror("2nd stage: write external memory\n");
|
||||
}
|
||||
|
||||
/* scan the image, first (maybe only) time */
|
||||
ctx.device = device;
|
||||
ctx.total = ctx.count = 0;
|
||||
status = parse[img_type](image, &ctx, is_external, ram_poke);
|
||||
if (status < 0) {
|
||||
logerror("unable to upload %s\n", path);
|
||||
ret = status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* second part of 2nd stage: rescan */
|
||||
// TODO: what should we do for non HEX images there?
|
||||
if (stage) {
|
||||
ctx.mode = skip_external;
|
||||
|
||||
/* if needed, halt the CPU while we overwrite the 1st stage loader */
|
||||
if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
|
||||
{
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* at least write the interrupt vectors (at 0x0000) for reset! */
|
||||
rewind(image);
|
||||
if (verbose)
|
||||
logerror("2nd stage: write on-chip memory\n");
|
||||
status = parse_ihex(image, &ctx, is_external, ram_poke);
|
||||
if (status < 0) {
|
||||
logerror("unable to completely upload %s\n", path);
|
||||
ret = status;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose && (ctx.count != 0)) {
|
||||
logerror("... WROTE: %d bytes, %d segments, avg %d\n",
|
||||
(int)ctx.total, (int)ctx.count, (int)(ctx.total/ctx.count));
|
||||
}
|
||||
|
||||
/* if required, reset the CPU so it runs what we just uploaded */
|
||||
if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, true))
|
||||
ret = -1;
|
||||
|
||||
exit:
|
||||
fclose(image);
|
||||
return ret;
|
||||
}
|
||||
120
externals/libusb/libusb/examples/ezusb.h
vendored
Executable file
120
externals/libusb/libusb/examples/ezusb.h
vendored
Executable file
@@ -0,0 +1,120 @@
|
||||
#ifndef ezusb_H
|
||||
#define ezusb_H
|
||||
/*
|
||||
* Copyright © 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright © 2002 David Brownell (dbrownell@users.sourceforge.net)
|
||||
* Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(_MSC_VER)
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#define __attribute__(x)
|
||||
#if !defined(bool)
|
||||
#define bool int
|
||||
#endif
|
||||
#if !defined(true)
|
||||
#define true (1 == 1)
|
||||
#endif
|
||||
#if !defined(false)
|
||||
#define false (!true)
|
||||
#endif
|
||||
#if defined(_PREFAST_)
|
||||
#pragma warning(disable:28193)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FX_TYPE_UNDEFINED -1
|
||||
#define FX_TYPE_AN21 0 /* Original AnchorChips parts */
|
||||
#define FX_TYPE_FX1 1 /* Updated Cypress versions */
|
||||
#define FX_TYPE_FX2 2 /* USB 2.0 versions */
|
||||
#define FX_TYPE_FX2LP 3 /* Updated FX2 */
|
||||
#define FX_TYPE_FX3 4 /* USB 3.0 versions */
|
||||
#define FX_TYPE_MAX 5
|
||||
#define FX_TYPE_NAMES { "an21", "fx", "fx2", "fx2lp", "fx3" }
|
||||
|
||||
#define IMG_TYPE_UNDEFINED -1
|
||||
#define IMG_TYPE_HEX 0 /* Intel HEX */
|
||||
#define IMG_TYPE_IIC 1 /* Cypress 8051 IIC */
|
||||
#define IMG_TYPE_BIX 2 /* Cypress 8051 BIX */
|
||||
#define IMG_TYPE_IMG 3 /* Cypress IMG format */
|
||||
#define IMG_TYPE_MAX 4
|
||||
#define IMG_TYPE_NAMES { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX", "Cypress IMG format" }
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Automatically identified devices (VID, PID, type, designation).
|
||||
* TODO: Could use some validation. Also where's the FX2?
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
int type;
|
||||
const char* designation;
|
||||
} fx_known_device;
|
||||
|
||||
#define FX_KNOWN_DEVICES { \
|
||||
{ 0x0547, 0x2122, FX_TYPE_AN21, "Cypress EZ-USB (2122S)" },\
|
||||
{ 0x0547, 0x2125, FX_TYPE_AN21, "Cypress EZ-USB (2121S/2125S)" },\
|
||||
{ 0x0547, 0x2126, FX_TYPE_AN21, "Cypress EZ-USB (2126S)" },\
|
||||
{ 0x0547, 0x2131, FX_TYPE_AN21, "Cypress EZ-USB (2131Q/2131S/2135S)" },\
|
||||
{ 0x0547, 0x2136, FX_TYPE_AN21, "Cypress EZ-USB (2136S)" },\
|
||||
{ 0x0547, 0x2225, FX_TYPE_AN21, "Cypress EZ-USB (2225)" },\
|
||||
{ 0x0547, 0x2226, FX_TYPE_AN21, "Cypress EZ-USB (2226)" },\
|
||||
{ 0x0547, 0x2235, FX_TYPE_AN21, "Cypress EZ-USB (2235)" },\
|
||||
{ 0x0547, 0x2236, FX_TYPE_AN21, "Cypress EZ-USB (2236)" },\
|
||||
{ 0x04b4, 0x6473, FX_TYPE_FX1, "Cypress EZ-USB FX1" },\
|
||||
{ 0x04b4, 0x8613, FX_TYPE_FX2LP, "Cypress EZ-USB FX2LP (68013A/68014A/68015A/68016A)" }, \
|
||||
{ 0x04b4, 0x00f3, FX_TYPE_FX3, "Cypress FX3" },\
|
||||
}
|
||||
|
||||
/*
|
||||
* This function uploads the firmware from the given file into RAM.
|
||||
* Stage == 0 means this is a single stage load (or the first of
|
||||
* two stages). Otherwise it's the second of two stages; the
|
||||
* caller having preloaded the second stage loader.
|
||||
*
|
||||
* The target processor is reset at the end of this upload.
|
||||
*/
|
||||
extern int ezusb_load_ram(libusb_device_handle *device,
|
||||
const char *path, int fx_type, int img_type, int stage);
|
||||
|
||||
/*
|
||||
* This function uploads the firmware from the given file into EEPROM.
|
||||
* This uses the right CPUCS address to terminate the EEPROM load with
|
||||
* a reset command where FX parts behave differently than FX2 ones.
|
||||
* The configuration byte is as provided here (zero for an21xx parts)
|
||||
* and the EEPROM type is set so that the microcontroller will boot
|
||||
* from it.
|
||||
*
|
||||
* The caller must have preloaded a second stage loader that knows
|
||||
* how to respond to the EEPROM write request.
|
||||
*/
|
||||
extern int ezusb_load_eeprom(libusb_device_handle *device,
|
||||
const char *path, int fx_type, int img_type, int config);
|
||||
|
||||
/* Verbosity level (default 1). Can be increased or decreased with options v/q */
|
||||
extern int verbose;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
309
externals/libusb/libusb/examples/fxload.c
vendored
Executable file
309
externals/libusb/libusb/examples/fxload.c
vendored
Executable file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright © 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
|
||||
* Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
|
||||
* Copyright © 2012 Pete Batard (pete@akeo.ie)
|
||||
* Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "libusb.h"
|
||||
#include "ezusb.h"
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__ )
|
||||
#include <syslog.h>
|
||||
static bool dosyslog = false;
|
||||
#include <strings.h>
|
||||
#define _stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
#ifndef FXLOAD_VERSION
|
||||
#define FXLOAD_VERSION (__DATE__ " (libusb)")
|
||||
#endif
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
void logerror(const char *format, ...)
|
||||
__attribute__ ((format (__printf__, 1, 2)));
|
||||
|
||||
void logerror(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__ )
|
||||
if (dosyslog)
|
||||
vsyslog(LOG_ERR, format, ap);
|
||||
else
|
||||
#endif
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static int print_usage(int error_code) {
|
||||
fprintf(stderr, "\nUsage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p bus,addr] [-s loader] -i firmware\n");
|
||||
fprintf(stderr, " -i <path> -- Firmware to upload\n");
|
||||
fprintf(stderr, " -s <path> -- Second stage loader\n");
|
||||
fprintf(stderr, " -t <type> -- Target type: an21, fx, fx2, fx2lp, fx3\n");
|
||||
fprintf(stderr, " -d <vid:pid> -- Target device, as an USB VID:PID\n");
|
||||
fprintf(stderr, " -p <bus,addr> -- Target device, as a libusb bus number and device address path\n");
|
||||
fprintf(stderr, " -v -- Increase verbosity\n");
|
||||
fprintf(stderr, " -q -- Decrease verbosity (silent mode)\n");
|
||||
fprintf(stderr, " -V -- Print program version\n");
|
||||
return error_code;
|
||||
}
|
||||
|
||||
#define FIRMWARE 0
|
||||
#define LOADER 1
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
fx_known_device known_device[] = FX_KNOWN_DEVICES;
|
||||
const char *path[] = { NULL, NULL };
|
||||
const char *device_id = NULL;
|
||||
const char *device_path = getenv("DEVICE");
|
||||
const char *type = NULL;
|
||||
const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
|
||||
const char *ext, *img_name[] = IMG_TYPE_NAMES;
|
||||
int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
|
||||
int opt, status;
|
||||
unsigned int i, j;
|
||||
unsigned vid = 0, pid = 0;
|
||||
unsigned busnum = 0, devaddr = 0, _busnum, _devaddr;
|
||||
libusb_device *dev, **devs;
|
||||
libusb_device_handle *device = NULL;
|
||||
struct libusb_device_descriptor desc;
|
||||
|
||||
while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:s:S:t:")) != EOF)
|
||||
switch (opt) {
|
||||
|
||||
case 'd':
|
||||
device_id = optarg;
|
||||
if (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 ) {
|
||||
fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
device_path = optarg;
|
||||
if (sscanf(device_path, "%u,%u", &busnum, &devaddr) != 2 ) {
|
||||
fputs ("please specify bus number & device number as \"bus,dev\" in decimal format\n", stderr);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'I':
|
||||
path[FIRMWARE] = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
path[LOADER] = optarg;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
puts(FXLOAD_VERSION);
|
||||
return 0;
|
||||
|
||||
case 't':
|
||||
type = optarg;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
verbose--;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
return print_usage(-1);
|
||||
|
||||
}
|
||||
|
||||
if (path[FIRMWARE] == NULL) {
|
||||
logerror("no firmware specified!\n");
|
||||
return print_usage(-1);
|
||||
}
|
||||
if ((device_id != NULL) && (device_path != NULL)) {
|
||||
logerror("only one of -d or -p can be specified\n");
|
||||
return print_usage(-1);
|
||||
}
|
||||
|
||||
/* determine the target type */
|
||||
if (type != NULL) {
|
||||
for (i=0; i<FX_TYPE_MAX; i++) {
|
||||
if (strcmp(type, fx_name[i]) == 0) {
|
||||
fx_type = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= FX_TYPE_MAX) {
|
||||
logerror("illegal microcontroller type: %s\n", type);
|
||||
return print_usage(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* open the device using libusb */
|
||||
status = libusb_init(NULL);
|
||||
if (status < 0) {
|
||||
logerror("libusb_init() failed: %s\n", libusb_error_name(status));
|
||||
return -1;
|
||||
}
|
||||
libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, verbose);
|
||||
|
||||
/* try to pick up missing parameters from known devices */
|
||||
if ((type == NULL) || (device_id == NULL) || (device_path != NULL)) {
|
||||
if (libusb_get_device_list(NULL, &devs) < 0) {
|
||||
logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status));
|
||||
goto err;
|
||||
}
|
||||
for (i=0; (dev=devs[i]) != NULL; i++) {
|
||||
_busnum = libusb_get_bus_number(dev);
|
||||
_devaddr = libusb_get_device_address(dev);
|
||||
if ((type != NULL) && (device_path != NULL)) {
|
||||
// if both a type and bus,addr were specified, we just need to find our match
|
||||
if ((libusb_get_bus_number(dev) == busnum) && (libusb_get_device_address(dev) == devaddr))
|
||||
break;
|
||||
} else {
|
||||
status = libusb_get_device_descriptor(dev, &desc);
|
||||
if (status >= 0) {
|
||||
if (verbose >= 3) {
|
||||
logerror("examining %04x:%04x (%d,%d)\n",
|
||||
desc.idVendor, desc.idProduct, _busnum, _devaddr);
|
||||
}
|
||||
for (j=0; j<ARRAYSIZE(known_device); j++) {
|
||||
if ((desc.idVendor == known_device[j].vid)
|
||||
&& (desc.idProduct == known_device[j].pid)) {
|
||||
if (// nothing was specified
|
||||
((type == NULL) && (device_id == NULL) && (device_path == NULL)) ||
|
||||
// vid:pid was specified and we have a match
|
||||
((type == NULL) && (device_id != NULL) && (vid == desc.idVendor) && (pid == desc.idProduct)) ||
|
||||
// bus,addr was specified and we have a match
|
||||
((type == NULL) && (device_path != NULL) && (busnum == _busnum) && (devaddr == _devaddr)) ||
|
||||
// type was specified and we have a match
|
||||
((type != NULL) && (device_id == NULL) && (device_path == NULL) && (fx_type == known_device[j].type)) ) {
|
||||
fx_type = known_device[j].type;
|
||||
vid = desc.idVendor;
|
||||
pid = desc.idProduct;
|
||||
busnum = _busnum;
|
||||
devaddr = _devaddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j < ARRAYSIZE(known_device)) {
|
||||
if (verbose)
|
||||
logerror("found device '%s' [%04x:%04x] (%d,%d)\n",
|
||||
known_device[j].designation, vid, pid, busnum, devaddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev == NULL) {
|
||||
libusb_free_device_list(devs, 1);
|
||||
libusb_exit(NULL);
|
||||
logerror("could not find a known device - please specify type and/or vid:pid and/or bus,dev\n");
|
||||
return print_usage(-1);
|
||||
}
|
||||
status = libusb_open(dev, &device);
|
||||
libusb_free_device_list(devs, 1);
|
||||
if (status < 0) {
|
||||
logerror("libusb_open() failed: %s\n", libusb_error_name(status));
|
||||
goto err;
|
||||
}
|
||||
} else if (device_id != NULL) {
|
||||
device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid);
|
||||
if (device == NULL) {
|
||||
logerror("libusb_open() failed\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to claim the first interface */
|
||||
libusb_set_auto_detach_kernel_driver(device, 1);
|
||||
status = libusb_claim_interface(device, 0);
|
||||
if (status != LIBUSB_SUCCESS) {
|
||||
libusb_close(device);
|
||||
logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
logerror("microcontroller type: %s\n", fx_name[fx_type]);
|
||||
|
||||
for (i=0; i<ARRAYSIZE(path); i++) {
|
||||
if (path[i] != NULL) {
|
||||
ext = path[i] + strlen(path[i]) - 4;
|
||||
if ((_stricmp(ext, ".hex") == 0) || (strcmp(ext, ".ihx") == 0))
|
||||
img_type[i] = IMG_TYPE_HEX;
|
||||
else if (_stricmp(ext, ".iic") == 0)
|
||||
img_type[i] = IMG_TYPE_IIC;
|
||||
else if (_stricmp(ext, ".bix") == 0)
|
||||
img_type[i] = IMG_TYPE_BIX;
|
||||
else if (_stricmp(ext, ".img") == 0)
|
||||
img_type[i] = IMG_TYPE_IMG;
|
||||
else {
|
||||
logerror("%s is not a recognized image type\n", path[i]);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (verbose && path[i] != NULL)
|
||||
logerror("%s: type %s\n", path[i], img_name[img_type[i]]);
|
||||
}
|
||||
|
||||
if (path[LOADER] == NULL) {
|
||||
/* single stage, put into internal memory */
|
||||
if (verbose > 1)
|
||||
logerror("single stage: load on-chip memory\n");
|
||||
status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);
|
||||
} else {
|
||||
/* two-stage, put loader into internal memory */
|
||||
if (verbose > 1)
|
||||
logerror("1st stage: load 2nd stage loader\n");
|
||||
status = ezusb_load_ram(device, path[LOADER], fx_type, img_type[LOADER], 0);
|
||||
if (status == 0) {
|
||||
/* two-stage, put firmware into internal memory */
|
||||
if (verbose > 1)
|
||||
logerror("2nd state: load on-chip memory\n");
|
||||
status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 1);
|
||||
}
|
||||
}
|
||||
|
||||
libusb_release_interface(device, 0);
|
||||
libusb_close(device);
|
||||
libusb_exit(NULL);
|
||||
return status;
|
||||
err:
|
||||
libusb_exit(NULL);
|
||||
return -1;
|
||||
}
|
||||
1060
externals/libusb/libusb/examples/getopt/getopt.c
vendored
Executable file
1060
externals/libusb/libusb/examples/getopt/getopt.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
180
externals/libusb/libusb/examples/getopt/getopt.h
vendored
Executable file
180
externals/libusb/libusb/examples/getopt/getopt.h
vendored
Executable file
@@ -0,0 +1,180 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C 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.
|
||||
|
||||
The GNU C 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 the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
|
||||
#ifndef __need_getopt
|
||||
# define _GETOPT_H 1
|
||||
#endif
|
||||
|
||||
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
||||
standalone, or this is the first header included in the source file.
|
||||
If we are being used with glibc, we need to include <features.h>, but
|
||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
||||
not defined, include <ctype.h>, which will pull in <features.h> for us
|
||||
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
||||
doesn't flood the namespace with stuff the way some other headers do.) */
|
||||
#if !defined __GNU_LIBRARY__
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
#ifndef __need_getopt
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
const char *name;
|
||||
# else
|
||||
char *name;
|
||||
# endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
#endif /* need getopt */
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`getopt'. */
|
||||
|
||||
#if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# ifdef __GNU_LIBRARY__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
|
||||
# else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
# endif /* __GNU_LIBRARY__ */
|
||||
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
extern int getopt_long_only (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
int __long_only);
|
||||
# endif
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
# endif
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure we later can get all the definitions and declarations. */
|
||||
#undef __need_getopt
|
||||
|
||||
#endif /* getopt.h */
|
||||
188
externals/libusb/libusb/examples/getopt/getopt1.c
vendored
Executable file
188
externals/libusb/libusb/examples/getopt/getopt1.c
vendored
Executable file
@@ -0,0 +1,188 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C 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.
|
||||
|
||||
The GNU C 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 the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
132
externals/libusb/libusb/examples/hotplugtest.c
vendored
Executable file
132
externals/libusb/libusb/examples/hotplugtest.c
vendored
Executable file
@@ -0,0 +1,132 @@
|
||||
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
||||
/*
|
||||
* libusb example program for hotplug API
|
||||
* Copyright © 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libusb.h"
|
||||
|
||||
int done = 0;
|
||||
libusb_device_handle *handle = NULL;
|
||||
|
||||
static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
int rc;
|
||||
|
||||
(void)ctx;
|
||||
(void)dev;
|
||||
(void)event;
|
||||
(void)user_data;
|
||||
|
||||
rc = libusb_get_device_descriptor(dev, &desc);
|
||||
if (LIBUSB_SUCCESS != rc) {
|
||||
fprintf (stderr, "Error getting device descriptor\n");
|
||||
}
|
||||
|
||||
printf ("Device attached: %04x:%04x\n", desc.idVendor, desc.idProduct);
|
||||
|
||||
if (handle) {
|
||||
libusb_close (handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
rc = libusb_open (dev, &handle);
|
||||
if (LIBUSB_SUCCESS != rc) {
|
||||
fprintf (stderr, "Error opening device\n");
|
||||
}
|
||||
|
||||
done++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int LIBUSB_CALL hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)dev;
|
||||
(void)event;
|
||||
(void)user_data;
|
||||
|
||||
printf ("Device detached\n");
|
||||
|
||||
if (handle) {
|
||||
libusb_close (handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
done++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
libusb_hotplug_callback_handle hp[2];
|
||||
int product_id, vendor_id, class_id;
|
||||
int rc;
|
||||
|
||||
vendor_id = (argc > 1) ? (int)strtol (argv[1], NULL, 0) : 0x045a;
|
||||
product_id = (argc > 2) ? (int)strtol (argv[2], NULL, 0) : 0x5005;
|
||||
class_id = (argc > 3) ? (int)strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY;
|
||||
|
||||
rc = libusb_init (NULL);
|
||||
if (rc < 0)
|
||||
{
|
||||
printf("failed to initialise libusb: %s\n", libusb_error_name(rc));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
|
||||
printf ("Hotplug capabilites are not supported on this platform\n");
|
||||
libusb_exit (NULL);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id,
|
||||
product_id, class_id, hotplug_callback, NULL, &hp[0]);
|
||||
if (LIBUSB_SUCCESS != rc) {
|
||||
fprintf (stderr, "Error registering callback 0\n");
|
||||
libusb_exit (NULL);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id,
|
||||
product_id,class_id, hotplug_callback_detach, NULL, &hp[1]);
|
||||
if (LIBUSB_SUCCESS != rc) {
|
||||
fprintf (stderr, "Error registering callback 1\n");
|
||||
libusb_exit (NULL);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while (done < 2) {
|
||||
rc = libusb_handle_events (NULL);
|
||||
if (rc < 0)
|
||||
printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc));
|
||||
}
|
||||
|
||||
if (handle) {
|
||||
libusb_close (handle);
|
||||
}
|
||||
|
||||
libusb_exit (NULL);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
73
externals/libusb/libusb/examples/listdevs.c
vendored
Executable file
73
externals/libusb/libusb/examples/listdevs.c
vendored
Executable file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* libusb example program to list devices on the bus
|
||||
* Copyright © 2007 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 <stdio.h>
|
||||
|
||||
#include "libusb.h"
|
||||
|
||||
static void print_devs(libusb_device **devs)
|
||||
{
|
||||
libusb_device *dev;
|
||||
int i = 0, j = 0;
|
||||
uint8_t path[8];
|
||||
|
||||
while ((dev = devs[i++]) != NULL) {
|
||||
struct libusb_device_descriptor desc;
|
||||
int r = libusb_get_device_descriptor(dev, &desc);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get device descriptor");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%04x:%04x (bus %d, device %d)",
|
||||
desc.idVendor, desc.idProduct,
|
||||
libusb_get_bus_number(dev), libusb_get_device_address(dev));
|
||||
|
||||
r = libusb_get_port_numbers(dev, path, sizeof(path));
|
||||
if (r > 0) {
|
||||
printf(" path: %d", path[0]);
|
||||
for (j = 1; j < r; j++)
|
||||
printf(".%d", path[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
libusb_device **devs;
|
||||
int r;
|
||||
ssize_t cnt;
|
||||
|
||||
r = libusb_init(NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cnt = libusb_get_device_list(NULL, &devs);
|
||||
if (cnt < 0){
|
||||
libusb_exit(NULL);
|
||||
return (int) cnt;
|
||||
}
|
||||
|
||||
print_devs(devs);
|
||||
libusb_free_device_list(devs, 1);
|
||||
|
||||
libusb_exit(NULL);
|
||||
return 0;
|
||||
}
|
||||
193
externals/libusb/libusb/examples/sam3u_benchmark.c
vendored
Executable file
193
externals/libusb/libusb/examples/sam3u_benchmark.c
vendored
Executable file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* libusb example program to measure Atmel SAM3U isochronous performance
|
||||
* Copyright (C) 2012 Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* Copied with the author's permission under LGPL-2.1 from
|
||||
* http://git.gnumonks.org/cgi-bin/gitweb.cgi?p=sam3u-tests.git;a=blob;f=usb-benchmark-project/host/benchmark.c;h=74959f7ee88f1597286cd435f312a8ff52c56b7e
|
||||
*
|
||||
* An Atmel SAM3U test firmware is also available in the above repository.
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
|
||||
#define EP_DATA_IN 0x82
|
||||
#define EP_ISO_IN 0x86
|
||||
|
||||
static int do_exit = 0;
|
||||
static struct libusb_device_handle *devh = NULL;
|
||||
|
||||
static unsigned long num_bytes = 0, num_xfer = 0;
|
||||
static struct timeval tv_start;
|
||||
|
||||
static void LIBUSB_CALL cb_xfr(struct libusb_transfer *xfr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (xfr->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "transfer status %d\n", xfr->status);
|
||||
libusb_free_transfer(xfr);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if (xfr->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
|
||||
for (i = 0; i < xfr->num_iso_packets; i++) {
|
||||
struct libusb_iso_packet_descriptor *pack = &xfr->iso_packet_desc[i];
|
||||
|
||||
if (pack->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
fprintf(stderr, "Error: pack %d status %d\n", i, pack->status);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
printf("pack%d length:%u, actual_length:%u\n", i, pack->length, pack->actual_length);
|
||||
}
|
||||
}
|
||||
|
||||
printf("length:%u, actual_length:%u\n", xfr->length, xfr->actual_length);
|
||||
for (i = 0; i < xfr->actual_length; i++) {
|
||||
printf("%02x", xfr->buffer[i]);
|
||||
if (i % 16)
|
||||
printf("\n");
|
||||
else if (i % 8)
|
||||
printf(" ");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
num_bytes += xfr->actual_length;
|
||||
num_xfer++;
|
||||
|
||||
if (libusb_submit_transfer(xfr) < 0) {
|
||||
fprintf(stderr, "error re-submitting URB\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int benchmark_in(uint8_t ep)
|
||||
{
|
||||
static uint8_t buf[2048];
|
||||
static struct libusb_transfer *xfr;
|
||||
int num_iso_pack = 0;
|
||||
|
||||
if (ep == EP_ISO_IN)
|
||||
num_iso_pack = 16;
|
||||
|
||||
xfr = libusb_alloc_transfer(num_iso_pack);
|
||||
if (!xfr)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ep == EP_ISO_IN) {
|
||||
libusb_fill_iso_transfer(xfr, devh, ep, buf,
|
||||
sizeof(buf), num_iso_pack, cb_xfr, NULL, 0);
|
||||
libusb_set_iso_packet_lengths(xfr, sizeof(buf)/num_iso_pack);
|
||||
} else
|
||||
libusb_fill_bulk_transfer(xfr, devh, ep, buf,
|
||||
sizeof(buf), cb_xfr, NULL, 0);
|
||||
|
||||
gettimeofday(&tv_start, NULL);
|
||||
|
||||
/* NOTE: To reach maximum possible performance the program must
|
||||
* submit *multiple* transfers here, not just one.
|
||||
*
|
||||
* When only one transfer is submitted there is a gap in the bus
|
||||
* schedule from when the transfer completes until a new transfer
|
||||
* is submitted by the callback. This causes some jitter for
|
||||
* isochronous transfers and loss of throughput for bulk transfers.
|
||||
*
|
||||
* This is avoided by queueing multiple transfers in advance, so
|
||||
* that the host controller is always kept busy, and will schedule
|
||||
* more transfers on the bus while the callback is running for
|
||||
* transfers which have completed on the bus.
|
||||
*/
|
||||
|
||||
return libusb_submit_transfer(xfr);
|
||||
}
|
||||
|
||||
static void measure(void)
|
||||
{
|
||||
struct timeval tv_stop;
|
||||
unsigned int diff_msec;
|
||||
|
||||
gettimeofday(&tv_stop, NULL);
|
||||
|
||||
diff_msec = (tv_stop.tv_sec - tv_start.tv_sec)*1000;
|
||||
diff_msec += (tv_stop.tv_usec - tv_start.tv_usec)/1000;
|
||||
|
||||
printf("%lu transfers (total %lu bytes) in %u miliseconds => %lu bytes/sec\n",
|
||||
num_xfer, num_bytes, diff_msec, (num_bytes*1000)/diff_msec);
|
||||
}
|
||||
|
||||
static void sig_hdlr(int signum)
|
||||
{
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
measure();
|
||||
do_exit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
struct sigaction sigact;
|
||||
|
||||
sigact.sa_handler = sig_hdlr;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
|
||||
rc = libusb_init(NULL);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error initializing libusb: %s\n", libusb_error_name(rc));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
devh = libusb_open_device_with_vid_pid(NULL, 0x16c0, 0x0763);
|
||||
if (!devh) {
|
||||
fprintf(stderr, "Error finding USB device\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = libusb_claim_interface(devh, 2);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error claiming interface: %s\n", libusb_error_name(rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
benchmark_in(EP_ISO_IN);
|
||||
|
||||
while (!do_exit) {
|
||||
rc = libusb_handle_events(NULL);
|
||||
if (rc != LIBUSB_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Measurement has already been done by the signal handler. */
|
||||
|
||||
libusb_release_interface(devh, 0);
|
||||
out:
|
||||
if (devh)
|
||||
libusb_close(devh);
|
||||
libusb_exit(NULL);
|
||||
return rc;
|
||||
}
|
||||
277
externals/libusb/libusb/examples/testlibusb.c
vendored
Executable file
277
externals/libusb/libusb/examples/testlibusb.c
vendored
Executable file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Test suite program based of libusb-0.1-compat testlibusb
|
||||
* Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.ccom>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include "libusb.h"
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
static void print_endpoint_comp(const struct libusb_ss_endpoint_companion_descriptor *ep_comp)
|
||||
{
|
||||
printf(" USB 3.0 Endpoint Companion:\n");
|
||||
printf(" bMaxBurst: %d\n", ep_comp->bMaxBurst);
|
||||
printf(" bmAttributes: 0x%02x\n", ep_comp->bmAttributes);
|
||||
printf(" wBytesPerInterval: %d\n", ep_comp->wBytesPerInterval);
|
||||
}
|
||||
|
||||
static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
printf(" Endpoint:\n");
|
||||
printf(" bEndpointAddress: %02xh\n", endpoint->bEndpointAddress);
|
||||
printf(" bmAttributes: %02xh\n", endpoint->bmAttributes);
|
||||
printf(" wMaxPacketSize: %d\n", endpoint->wMaxPacketSize);
|
||||
printf(" bInterval: %d\n", endpoint->bInterval);
|
||||
printf(" bRefresh: %d\n", endpoint->bRefresh);
|
||||
printf(" bSynchAddress: %d\n", endpoint->bSynchAddress);
|
||||
|
||||
for (i = 0; i < endpoint->extra_length;) {
|
||||
if (LIBUSB_DT_SS_ENDPOINT_COMPANION == endpoint->extra[i + 1]) {
|
||||
struct libusb_ss_endpoint_companion_descriptor *ep_comp;
|
||||
|
||||
ret = libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
|
||||
if (LIBUSB_SUCCESS != ret) {
|
||||
continue;
|
||||
}
|
||||
|
||||
print_endpoint_comp(ep_comp);
|
||||
|
||||
libusb_free_ss_endpoint_companion_descriptor(ep_comp);
|
||||
}
|
||||
|
||||
i += endpoint->extra[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void print_altsetting(const struct libusb_interface_descriptor *interface)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
printf(" Interface:\n");
|
||||
printf(" bInterfaceNumber: %d\n", interface->bInterfaceNumber);
|
||||
printf(" bAlternateSetting: %d\n", interface->bAlternateSetting);
|
||||
printf(" bNumEndpoints: %d\n", interface->bNumEndpoints);
|
||||
printf(" bInterfaceClass: %d\n", interface->bInterfaceClass);
|
||||
printf(" bInterfaceSubClass: %d\n", interface->bInterfaceSubClass);
|
||||
printf(" bInterfaceProtocol: %d\n", interface->bInterfaceProtocol);
|
||||
printf(" iInterface: %d\n", interface->iInterface);
|
||||
|
||||
for (i = 0; i < interface->bNumEndpoints; i++)
|
||||
print_endpoint(&interface->endpoint[i]);
|
||||
}
|
||||
|
||||
static void print_2_0_ext_cap(struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext_cap)
|
||||
{
|
||||
printf(" USB 2.0 Extension Capabilities:\n");
|
||||
printf(" bDevCapabilityType: %d\n", usb_2_0_ext_cap->bDevCapabilityType);
|
||||
printf(" bmAttributes: 0x%x\n", usb_2_0_ext_cap->bmAttributes);
|
||||
}
|
||||
|
||||
static void print_ss_usb_cap(struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap)
|
||||
{
|
||||
printf(" USB 3.0 Capabilities:\n");
|
||||
printf(" bDevCapabilityType: %d\n", ss_usb_cap->bDevCapabilityType);
|
||||
printf(" bmAttributes: 0x%x\n", ss_usb_cap->bmAttributes);
|
||||
printf(" wSpeedSupported: 0x%x\n", ss_usb_cap->wSpeedSupported);
|
||||
printf(" bFunctionalitySupport: %d\n", ss_usb_cap->bFunctionalitySupport);
|
||||
printf(" bU1devExitLat: %d\n", ss_usb_cap->bU1DevExitLat);
|
||||
printf(" bU2devExitLat: %d\n", ss_usb_cap->bU2DevExitLat);
|
||||
}
|
||||
|
||||
static void print_bos(libusb_device_handle *handle)
|
||||
{
|
||||
struct libusb_bos_descriptor *bos;
|
||||
int ret;
|
||||
|
||||
ret = libusb_get_bos_descriptor(handle, &bos);
|
||||
if (0 > ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" Binary Object Store (BOS):\n");
|
||||
printf(" wTotalLength: %d\n", bos->wTotalLength);
|
||||
printf(" bNumDeviceCaps: %d\n", bos->bNumDeviceCaps);
|
||||
|
||||
if(bos->dev_capability[0]->bDevCapabilityType == LIBUSB_BT_USB_2_0_EXTENSION) {
|
||||
|
||||
struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension;
|
||||
ret = libusb_get_usb_2_0_extension_descriptor(NULL, bos->dev_capability[0],&usb_2_0_extension);
|
||||
if (0 > ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_2_0_ext_cap(usb_2_0_extension);
|
||||
libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension);
|
||||
}
|
||||
|
||||
if(bos->dev_capability[0]->bDevCapabilityType == LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
|
||||
|
||||
struct libusb_ss_usb_device_capability_descriptor *dev_cap;
|
||||
ret = libusb_get_ss_usb_device_capability_descriptor(NULL, bos->dev_capability[0],&dev_cap);
|
||||
if (0 > ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_ss_usb_cap(dev_cap);
|
||||
libusb_free_ss_usb_device_capability_descriptor(dev_cap);
|
||||
}
|
||||
|
||||
libusb_free_bos_descriptor(bos);
|
||||
}
|
||||
|
||||
static void print_interface(const struct libusb_interface *interface)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < interface->num_altsetting; i++)
|
||||
print_altsetting(&interface->altsetting[i]);
|
||||
}
|
||||
|
||||
static void print_configuration(struct libusb_config_descriptor *config)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
printf(" Configuration:\n");
|
||||
printf(" wTotalLength: %d\n", config->wTotalLength);
|
||||
printf(" bNumInterfaces: %d\n", config->bNumInterfaces);
|
||||
printf(" bConfigurationValue: %d\n", config->bConfigurationValue);
|
||||
printf(" iConfiguration: %d\n", config->iConfiguration);
|
||||
printf(" bmAttributes: %02xh\n", config->bmAttributes);
|
||||
printf(" MaxPower: %d\n", config->MaxPower);
|
||||
|
||||
for (i = 0; i < config->bNumInterfaces; i++)
|
||||
print_interface(&config->interface[i]);
|
||||
}
|
||||
|
||||
static int print_device(libusb_device *dev, int level)
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_device_handle *handle = NULL;
|
||||
char description[260];
|
||||
char string[256];
|
||||
int ret;
|
||||
uint8_t i;
|
||||
|
||||
ret = libusb_get_device_descriptor(dev, &desc);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to get device descriptor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = libusb_open(dev, &handle);
|
||||
if (LIBUSB_SUCCESS == ret) {
|
||||
if (desc.iManufacturer) {
|
||||
ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string));
|
||||
if (ret > 0)
|
||||
snprintf(description, sizeof(description), "%s - ", string);
|
||||
else
|
||||
snprintf(description, sizeof(description), "%04X - ",
|
||||
desc.idVendor);
|
||||
}
|
||||
else
|
||||
snprintf(description, sizeof(description), "%04X - ",
|
||||
desc.idVendor);
|
||||
|
||||
if (desc.iProduct) {
|
||||
ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string));
|
||||
if (ret > 0)
|
||||
snprintf(description + strlen(description), sizeof(description) -
|
||||
strlen(description), "%s", string);
|
||||
else
|
||||
snprintf(description + strlen(description), sizeof(description) -
|
||||
strlen(description), "%04X", desc.idProduct);
|
||||
}
|
||||
else
|
||||
snprintf(description + strlen(description), sizeof(description) -
|
||||
strlen(description), "%04X", desc.idProduct);
|
||||
}
|
||||
else {
|
||||
snprintf(description, sizeof(description), "%04X - %04X",
|
||||
desc.idVendor, desc.idProduct);
|
||||
}
|
||||
|
||||
printf("%.*sDev (bus %d, device %d): %s\n", level * 2, " ",
|
||||
libusb_get_bus_number(dev), libusb_get_device_address(dev), description);
|
||||
|
||||
if (handle && verbose) {
|
||||
if (desc.iSerialNumber) {
|
||||
ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string));
|
||||
if (ret > 0)
|
||||
printf("%.*s - Serial Number: %s\n", level * 2,
|
||||
" ", string);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
for (i = 0; i < desc.bNumConfigurations; i++) {
|
||||
struct libusb_config_descriptor *config;
|
||||
ret = libusb_get_config_descriptor(dev, i, &config);
|
||||
if (LIBUSB_SUCCESS != ret) {
|
||||
printf(" Couldn't retrieve descriptors\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
print_configuration(config);
|
||||
|
||||
libusb_free_config_descriptor(config);
|
||||
}
|
||||
|
||||
if (handle && desc.bcdUSB >= 0x0201) {
|
||||
print_bos(handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (handle)
|
||||
libusb_close(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
libusb_device **devs;
|
||||
ssize_t cnt;
|
||||
int r, i;
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], "-v"))
|
||||
verbose = 1;
|
||||
|
||||
r = libusb_init(NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cnt = libusb_get_device_list(NULL, &devs);
|
||||
if (cnt < 0)
|
||||
return (int)cnt;
|
||||
|
||||
for (i = 0; devs[i]; ++i) {
|
||||
print_device(devs[i], 0);
|
||||
}
|
||||
|
||||
libusb_free_device_list(devs, 1);
|
||||
|
||||
libusb_exit(NULL);
|
||||
return 0;
|
||||
}
|
||||
1135
externals/libusb/libusb/examples/xusb.c
vendored
Executable file
1135
externals/libusb/libusb/examples/xusb.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
11
externals/libusb/libusb/libusb-1.0.pc.in
vendored
Executable file
11
externals/libusb/libusb/libusb-1.0.pc.in
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libusb-1.0
|
||||
Description: C API for USB device access from Linux, Mac OS X, Windows, OpenBSD/NetBSD and Solaris userspace
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lusb-1.0
|
||||
Libs.private: @LIBS@
|
||||
Cflags: -I${includedir}/libusb-1.0
|
||||
101
externals/libusb/libusb/libusb/Makefile.am
vendored
Executable file
101
externals/libusb/libusb/libusb/Makefile.am
vendored
Executable file
@@ -0,0 +1,101 @@
|
||||
all: libusb-1.0.la libusb-1.0.dll
|
||||
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
lib_LTLIBRARIES = libusb-1.0.la
|
||||
|
||||
POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
|
||||
POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
|
||||
WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
|
||||
WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
|
||||
LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
|
||||
DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
|
||||
OPENBSD_USB_SRC = os/openbsd_usb.c
|
||||
NETBSD_USB_SRC = os/netbsd_usb.c
|
||||
SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
|
||||
WINDOWS_USB_SRC = libusb-1.0.def libusb-1.0.rc \
|
||||
os/windows_common.h \
|
||||
os/windows_nt_common.h os/windows_nt_common.c \
|
||||
os/windows_nt_shared_types.h \
|
||||
os/windows_usbdk.h os/windows_usbdk.c \
|
||||
os/windows_winusb.h os/windows_winusb.c
|
||||
WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
|
||||
HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
|
||||
os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
|
||||
|
||||
EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
|
||||
$(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
|
||||
$(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
|
||||
$(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
|
||||
$(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
|
||||
$(HAIKU_USB_SRC) \
|
||||
os/linux_udev.c os/linux_netlink.c
|
||||
|
||||
if OS_LINUX
|
||||
|
||||
if USE_UDEV
|
||||
OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
|
||||
else
|
||||
OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if OS_DARWIN
|
||||
OS_SRC = $(DARWIN_USB_SRC)
|
||||
AM_CFLAGS_EXT = -no-cpp-precomp
|
||||
endif
|
||||
|
||||
if OS_OPENBSD
|
||||
OS_SRC = $(OPENBSD_USB_SRC)
|
||||
endif
|
||||
|
||||
if OS_NETBSD
|
||||
OS_SRC = $(NETBSD_USB_SRC)
|
||||
endif
|
||||
|
||||
if OS_SUNOS
|
||||
OS_SRC = $(SUNOS_USB_SRC)
|
||||
endif
|
||||
|
||||
if OS_HAIKU
|
||||
noinst_LTLIBRARIES = libusb_haiku.la
|
||||
libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
|
||||
libusb_1_0_la_LIBADD = libusb_haiku.la
|
||||
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 libusb-1.0.la
|
||||
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 OS_WINDOWS
|
||||
POLL_SRC = $(WINDOWS_POLL_SRC)
|
||||
else
|
||||
POLL_SRC = $(POSIX_POLL_SRC)
|
||||
endif
|
||||
|
||||
if THREADS_POSIX
|
||||
THREADS_SRC = $(POSIX_THREADS_SRC)
|
||||
else
|
||||
THREADS_SRC = $(WINDOWS_THREADS_SRC)
|
||||
endif
|
||||
|
||||
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
|
||||
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
|
||||
libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
|
||||
core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
|
||||
$(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
|
||||
|
||||
hdrdir = $(includedir)/libusb-1.0
|
||||
hdr_HEADERS = libusb.h
|
||||
2740
externals/libusb/libusb/libusb/core.c
vendored
Executable file
2740
externals/libusb/libusb/libusb/core.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1193
externals/libusb/libusb/libusb/descriptor.c
vendored
Executable file
1193
externals/libusb/libusb/libusb/descriptor.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
373
externals/libusb/libusb/libusb/hotplug.c
vendored
Executable file
373
externals/libusb/libusb/libusb/hotplug.c
vendored
Executable file
@@ -0,0 +1,373 @@
|
||||
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
||||
/*
|
||||
* Hotplug functions for libusb
|
||||
* 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 libusb_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 libusb_hotplug Device hotplug event notification
|
||||
*
|
||||
* \section hotplug_intro Introduction
|
||||
*
|
||||
* Version 1.0.16, \ref LIBUSB_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 callback 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. Note that when callbacks are called from
|
||||
* libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE
|
||||
* flag, the callback return value is ignored, iow you cannot cause a callback
|
||||
* to be deregistered by returning 1 when it is called from
|
||||
* libusb_hotplug_register_callback().
|
||||
*
|
||||
* 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 device 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 libusb function that takes a libusb_device. It also safe to
|
||||
* open a device and submit asynchronous transfers. However, most other functions
|
||||
* that take a libusb_device_handle are <b>not</b> safe to call. Examples of such
|
||||
* functions are any of the \ref libusb_syncio "synchronous API" functions or the blocking
|
||||
* functions that retrieve various \ref libusb_desc "USB descriptors". These functions must
|
||||
* be used outside of the context of the hotplug callback.
|
||||
*
|
||||
* 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
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <libusb.h>
|
||||
|
||||
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 *dev_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, &dev_handle);
|
||||
if (LIBUSB_SUCCESS != rc) {
|
||||
printf("Could not open USB device\n");
|
||||
}
|
||||
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
|
||||
if (dev_handle) {
|
||||
libusb_close(dev_handle);
|
||||
dev_handle = NULL;
|
||||
}
|
||||
} else {
|
||||
printf("Unhandled event %d\n", event);
|
||||
}
|
||||
count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void) {
|
||||
libusb_hotplug_callback_handle callback_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,
|
||||
&callback_handle);
|
||||
if (LIBUSB_SUCCESS != rc) {
|
||||
printf("Error creating a hotplug callback\n");
|
||||
libusb_exit(NULL);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while (count < 2) {
|
||||
libusb_handle_events_completed(NULL, NULL);
|
||||
nanosleep(&(struct timespec){0, 10000000UL}, NULL);
|
||||
}
|
||||
|
||||
libusb_hotplug_deregister_callback(NULL, 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)
|
||||
{
|
||||
if (!(hotplug_cb->flags & event)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((hotplug_cb->flags & USBI_HOTPLUG_VENDOR_ID_VALID) &&
|
||||
hotplug_cb->vendor_id != dev->device_descriptor.idVendor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((hotplug_cb->flags & USBI_HOTPLUG_PRODUCT_ID_VALID) &&
|
||||
hotplug_cb->product_id != dev->device_descriptor.idProduct) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((hotplug_cb->flags & USBI_HOTPLUG_DEV_CLASS_VALID) &&
|
||||
hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hotplug_cb->cb(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) {
|
||||
if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
|
||||
/* process deregistration in usbi_hotplug_deregister() */
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
|
||||
libusb_hotplug_event event)
|
||||
{
|
||||
int pending_events;
|
||||
struct libusb_hotplug_message *message = calloc(1, sizeof(*message));
|
||||
|
||||
if (!message) {
|
||||
usbi_err(ctx, "error allocating hotplug message");
|
||||
return;
|
||||
}
|
||||
|
||||
message->event = event;
|
||||
message->device = dev;
|
||||
|
||||
/* Take the event data lock and add this message to the list.
|
||||
* Only signal an event if there are no prior pending events. */
|
||||
usbi_mutex_lock(&ctx->event_data_lock);
|
||||
pending_events = usbi_pending_events(ctx);
|
||||
list_add_tail(&message->list, &ctx->hotplug_msgs);
|
||||
if (!pending_events)
|
||||
usbi_signal_event(ctx);
|
||||
usbi_mutex_unlock(&ctx->event_data_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 *callback_handle)
|
||||
{
|
||||
struct libusb_hotplug_callback *new_callback;
|
||||
|
||||
/* check for sane values */
|
||||
if ((!events || (~(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) & events)) ||
|
||||
(flags && (~LIBUSB_HOTPLUG_ENUMERATE & flags)) ||
|
||||
(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;
|
||||
}
|
||||
|
||||
/* check for hotplug support */
|
||||
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
USBI_GET_CONTEXT(ctx);
|
||||
|
||||
new_callback = calloc(1, sizeof(*new_callback));
|
||||
if (!new_callback) {
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
new_callback->flags = (uint8_t)events;
|
||||
if (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id) {
|
||||
new_callback->flags |= USBI_HOTPLUG_VENDOR_ID_VALID;
|
||||
new_callback->vendor_id = (uint16_t)vendor_id;
|
||||
}
|
||||
if (LIBUSB_HOTPLUG_MATCH_ANY != product_id) {
|
||||
new_callback->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID;
|
||||
new_callback->product_id = (uint16_t)product_id;
|
||||
}
|
||||
if (LIBUSB_HOTPLUG_MATCH_ANY != dev_class) {
|
||||
new_callback->flags |= USBI_HOTPLUG_DEV_CLASS_VALID;
|
||||
new_callback->dev_class = (uint8_t)dev_class;
|
||||
}
|
||||
new_callback->cb = cb_fn;
|
||||
new_callback->user_data = user_data;
|
||||
|
||||
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
||||
|
||||
/* protect the handle by the context hotplug lock */
|
||||
new_callback->handle = ctx->next_hotplug_cb_handle++;
|
||||
|
||||
/* handle the unlikely case of overflow */
|
||||
if (ctx->next_hotplug_cb_handle < 0)
|
||||
ctx->next_hotplug_cb_handle = 1;
|
||||
|
||||
list_add(&new_callback->list, &ctx->hotplug_cbs);
|
||||
|
||||
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
||||
|
||||
usbi_dbg("new hotplug cb %p with handle %d", new_callback, new_callback->handle);
|
||||
|
||||
if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
|
||||
ssize_t i, len;
|
||||
struct libusb_device **devs;
|
||||
|
||||
len = libusb_get_device_list(ctx, &devs);
|
||||
if (len < 0) {
|
||||
libusb_hotplug_deregister_callback(ctx,
|
||||
new_callback->handle);
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
usbi_hotplug_match_cb(ctx, devs[i],
|
||||
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
|
||||
new_callback);
|
||||
}
|
||||
|
||||
libusb_free_device_list(devs, 1);
|
||||
}
|
||||
|
||||
|
||||
if (callback_handle)
|
||||
*callback_handle = new_callback->handle;
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
void API_EXPORTED libusb_hotplug_deregister_callback(struct libusb_context *ctx,
|
||||
libusb_hotplug_callback_handle callback_handle)
|
||||
{
|
||||
struct libusb_hotplug_callback *hotplug_cb;
|
||||
int deregistered = 0;
|
||||
|
||||
/* check for hotplug support */
|
||||
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
||||
return;
|
||||
}
|
||||
|
||||
USBI_GET_CONTEXT(ctx);
|
||||
|
||||
usbi_dbg("deregister hotplug cb %d", callback_handle);
|
||||
|
||||
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
||||
list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
|
||||
if (callback_handle == hotplug_cb->handle) {
|
||||
/* Mark this callback for deregistration */
|
||||
hotplug_cb->flags |= USBI_HOTPLUG_NEEDS_FREE;
|
||||
deregistered = 1;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
||||
|
||||
if (deregistered) {
|
||||
int pending_events;
|
||||
|
||||
usbi_mutex_lock(&ctx->event_data_lock);
|
||||
pending_events = usbi_pending_events(ctx);
|
||||
ctx->event_flags |= USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
|
||||
if (!pending_events)
|
||||
usbi_signal_event(ctx);
|
||||
usbi_mutex_unlock(&ctx->event_data_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void usbi_hotplug_deregister(struct libusb_context *ctx, int forced)
|
||||
{
|
||||
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) {
|
||||
if (forced || (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)) {
|
||||
usbi_dbg("freeing hotplug cb %p with handle %d", hotplug_cb,
|
||||
hotplug_cb->handle);
|
||||
list_del(&hotplug_cb->list);
|
||||
free(hotplug_cb);
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
||||
}
|
||||
99
externals/libusb/libusb/libusb/hotplug.h
vendored
Executable file
99
externals/libusb/libusb/libusb/hotplug.h
vendored
Executable file
@@ -0,0 +1,99 @@
|
||||
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
||||
/*
|
||||
* Hotplug support for libusb
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef USBI_HOTPLUG_H
|
||||
#define USBI_HOTPLUG_H
|
||||
|
||||
#include "libusbi.h"
|
||||
|
||||
enum usbi_hotplug_flags {
|
||||
/* This callback is interested in device arrivals */
|
||||
USBI_HOTPLUG_DEVICE_ARRIVED = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
|
||||
|
||||
/* This callback is interested in device removals */
|
||||
USBI_HOTPLUG_DEVICE_LEFT = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
|
||||
|
||||
/* IMPORTANT: The values for the below entries must start *after*
|
||||
* the highest value of the above entries!!!
|
||||
*/
|
||||
|
||||
/* The vendor_id field is valid for matching */
|
||||
USBI_HOTPLUG_VENDOR_ID_VALID = (1U << 3),
|
||||
|
||||
/* The product_id field is valid for matching */
|
||||
USBI_HOTPLUG_PRODUCT_ID_VALID = (1U << 4),
|
||||
|
||||
/* The dev_class field is valid for matching */
|
||||
USBI_HOTPLUG_DEV_CLASS_VALID = (1U << 5),
|
||||
|
||||
/* This callback has been unregistered and needs to be freed */
|
||||
USBI_HOTPLUG_NEEDS_FREE = (1U << 6),
|
||||
};
|
||||
|
||||
/** \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 {
|
||||
/** Flags that control how this callback behaves */
|
||||
uint8_t flags;
|
||||
|
||||
/** Vendor ID to match (if flags says this is valid) */
|
||||
uint16_t vendor_id;
|
||||
|
||||
/** Product ID to match (if flags says this is valid) */
|
||||
uint16_t product_id;
|
||||
|
||||
/** Device class to match (if flags says this is valid) */
|
||||
uint8_t dev_class;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** List this callback is registered in (ctx->hotplug_cbs) */
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct libusb_hotplug_message {
|
||||
/** The hotplug event that occurred */
|
||||
libusb_hotplug_event event;
|
||||
|
||||
/** The device for which this hotplug event occurred */
|
||||
struct libusb_device *device;
|
||||
|
||||
/** List this message is contained in (ctx->hotplug_msgs) */
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
void usbi_hotplug_deregister(struct libusb_context *ctx, int forced);
|
||||
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
||||
libusb_hotplug_event event);
|
||||
void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
|
||||
libusb_hotplug_event event);
|
||||
|
||||
#endif
|
||||
2866
externals/libusb/libusb/libusb/io.c
vendored
Executable file
2866
externals/libusb/libusb/libusb/io.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
178
externals/libusb/libusb/libusb/libusb-1.0.def
vendored
Executable file
178
externals/libusb/libusb/libusb/libusb-1.0.def
vendored
Executable file
@@ -0,0 +1,178 @@
|
||||
LIBRARY "libusb-1.0.dll"
|
||||
EXPORTS
|
||||
libusb_alloc_streams
|
||||
libusb_alloc_streams@16 = libusb_alloc_streams
|
||||
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_dev_mem_alloc
|
||||
libusb_dev_mem_alloc@8 = libusb_dev_mem_alloc
|
||||
libusb_dev_mem_free
|
||||
libusb_dev_mem_free@12 = libusb_dev_mem_free
|
||||
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_pollfds
|
||||
libusb_free_pollfds@4 = libusb_free_pollfds
|
||||
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_streams
|
||||
libusb_free_streams@12 = libusb_free_streams
|
||||
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_event_handler
|
||||
libusb_interrupt_event_handler@4 = libusb_interrupt_event_handler
|
||||
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_log_cb
|
||||
libusb_set_log_cb@12 = libusb_set_log_cb
|
||||
libusb_set_interface_alt_setting
|
||||
libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
|
||||
libusb_set_option
|
||||
_libusb_set_option = libusb_set_option
|
||||
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_transfer_get_stream_id
|
||||
libusb_transfer_get_stream_id@4 = libusb_transfer_get_stream_id
|
||||
libusb_transfer_set_stream_id
|
||||
libusb_transfer_set_stream_id@8 = libusb_transfer_set_stream_id
|
||||
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/libusb/libusb/libusb/libusb-1.0.rc
vendored
Executable file
61
externals/libusb/libusb/libusb/libusb-1.0.rc
vendored
Executable 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", "libusb.info\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
|
||||
2066
externals/libusb/libusb/libusb/libusb.h
vendored
Executable file
2066
externals/libusb/libusb/libusb/libusb.h
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1210
externals/libusb/libusb/libusb/libusbi.h
vendored
Executable file
1210
externals/libusb/libusb/libusb/libusbi.h
vendored
Executable file
File diff suppressed because it is too large
Load Diff
2294
externals/libusb/libusb/libusb/os/darwin_usb.c
vendored
Executable file
2294
externals/libusb/libusb/libusb/os/darwin_usb.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
203
externals/libusb/libusb/libusb/os/darwin_usb.h
vendored
Executable file
203
externals/libusb/libusb/libusb/os/darwin_usb.h
vendored
Executable file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* darwin backend for libusb 1.0
|
||||
* Copyright © 2008-2019 Nathan Hjelm <hjelmn@users.sourceforge.net>
|
||||
* Copyright © 2019 Google LLC. All rights reserved.
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
|
||||
#include <IOKit/IOTypes.h>
|
||||
#include <IOKit/IOCFBundle.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
|
||||
/* IOUSBInterfaceInferface */
|
||||
|
||||
/* New in OS 10.12.0. */
|
||||
#if defined (kIOUSBInterfaceInterfaceID800) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface800
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID800
|
||||
#define InterfaceVersion 800
|
||||
|
||||
/* New in OS 10.10.0. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID700) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface700
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID700
|
||||
#define InterfaceVersion 700
|
||||
|
||||
/* New in OS 10.9.0. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID650) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface650
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID650
|
||||
#define InterfaceVersion 650
|
||||
|
||||
/* New in OS 10.8.2 but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID550) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface550
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550
|
||||
#define InterfaceVersion 550
|
||||
|
||||
/* New in OS 10.7.3 but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID500) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface500
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID500
|
||||
#define InterfaceVersion 500
|
||||
|
||||
/* New in OS 10.5.0. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID300) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface300
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300
|
||||
#define InterfaceVersion 300
|
||||
|
||||
/* New in OS 10.4.5 (or 10.4.6?) but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID245) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface245
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245
|
||||
#define InterfaceVersion 245
|
||||
|
||||
/* New in OS 10.4.0. */
|
||||
#elif defined (kIOUSBInterfaceInterfaceID220) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040)
|
||||
|
||||
#define usb_interface_t IOUSBInterfaceInterface220
|
||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
|
||||
#define InterfaceVersion 220
|
||||
|
||||
#else
|
||||
|
||||
#error "IOUSBFamily is too old. Please upgrade your SDK and/or deployment target"
|
||||
|
||||
#endif
|
||||
|
||||
/* IOUSBDeviceInterface */
|
||||
|
||||
/* New in OS 10.9.0. */
|
||||
#if defined (kIOUSBDeviceInterfaceID650) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1090)
|
||||
|
||||
#define usb_device_t IOUSBDeviceInterface650
|
||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID650
|
||||
#define DeviceVersion 650
|
||||
|
||||
/* New in OS 10.7.3 but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBDeviceInterfaceID500) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1080)
|
||||
|
||||
#define usb_device_t IOUSBDeviceInterface500
|
||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID500
|
||||
#define DeviceVersion 500
|
||||
|
||||
/* New in OS 10.5.4 but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBDeviceInterfaceID320) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
|
||||
|
||||
#define usb_device_t IOUSBDeviceInterface320
|
||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID320
|
||||
#define DeviceVersion 320
|
||||
|
||||
/* New in OS 10.5.0. */
|
||||
#elif defined (kIOUSBDeviceInterfaceID300) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
|
||||
|
||||
#define usb_device_t IOUSBDeviceInterface300
|
||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID300
|
||||
#define DeviceVersion 300
|
||||
|
||||
/* New in OS 10.4.5 (or 10.4.6?) but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBDeviceInterfaceID245) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
|
||||
|
||||
#define usb_device_t IOUSBDeviceInterface245
|
||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID245
|
||||
#define DeviceVersion 245
|
||||
|
||||
/* New in OS 10.2.3 but can't test deployment target to that granularity, so round up. */
|
||||
#elif defined (kIOUSBDeviceInterfaceID197) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1030)
|
||||
|
||||
#define usb_device_t IOUSBDeviceInterface197
|
||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
|
||||
#define DeviceVersion 197
|
||||
|
||||
#else
|
||||
|
||||
#error "IOUSBFamily is too old. Please upgrade your SDK and/or deployment target"
|
||||
|
||||
#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;
|
||||
USBDeviceAddress address;
|
||||
char sys_path[21];
|
||||
usb_device_t **device;
|
||||
int open_count;
|
||||
UInt8 first_config, active_config, port;
|
||||
int can_enumerate;
|
||||
int refcount;
|
||||
bool in_reenumerate;
|
||||
};
|
||||
|
||||
struct darwin_device_priv {
|
||||
struct darwin_cached_device *dev;
|
||||
};
|
||||
|
||||
struct darwin_device_handle_priv {
|
||||
bool is_open;
|
||||
CFRunLoopSourceRef cfSource;
|
||||
|
||||
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 */
|
||||
|
||||
/* Completion status */
|
||||
IOReturn result;
|
||||
UInt32 size;
|
||||
};
|
||||
|
||||
#endif
|
||||
367
externals/libusb/libusb/libusb/os/haiku_pollfs.cpp
vendored
Executable file
367
externals/libusb/libusb/libusb/os/haiku_pollfs.cpp
vendored
Executable file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright 2007-2008, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Lotz <mmlr@mlotz.ch>
|
||||
*/
|
||||
|
||||
#include "haiku_usb.h"
|
||||
#include <cstdio>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <Looper.h>
|
||||
#include <Messenger.h>
|
||||
#include <Node.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Path.h>
|
||||
#include <cstring>
|
||||
|
||||
class WatchedEntry {
|
||||
public:
|
||||
WatchedEntry(BMessenger *, entry_ref *);
|
||||
~WatchedEntry();
|
||||
bool EntryCreated(entry_ref *ref);
|
||||
bool EntryRemoved(ino_t node);
|
||||
bool InitCheck();
|
||||
|
||||
private:
|
||||
BMessenger* fMessenger;
|
||||
node_ref fNode;
|
||||
bool fIsDirectory;
|
||||
USBDevice* fDevice;
|
||||
WatchedEntry* fEntries;
|
||||
WatchedEntry* fLink;
|
||||
bool fInitCheck;
|
||||
};
|
||||
|
||||
|
||||
class RosterLooper : public BLooper {
|
||||
public:
|
||||
RosterLooper(USBRoster *);
|
||||
void Stop();
|
||||
virtual void MessageReceived(BMessage *);
|
||||
bool InitCheck();
|
||||
|
||||
private:
|
||||
USBRoster* fRoster;
|
||||
WatchedEntry* fRoot;
|
||||
BMessenger* fMessenger;
|
||||
bool fInitCheck;
|
||||
};
|
||||
|
||||
|
||||
WatchedEntry::WatchedEntry(BMessenger *messenger, entry_ref *ref)
|
||||
: fMessenger(messenger),
|
||||
fIsDirectory(false),
|
||||
fDevice(NULL),
|
||||
fEntries(NULL),
|
||||
fLink(NULL),
|
||||
fInitCheck(false)
|
||||
{
|
||||
BEntry entry(ref);
|
||||
entry.GetNodeRef(&fNode);
|
||||
|
||||
BDirectory directory;
|
||||
if (entry.IsDirectory() && directory.SetTo(ref) >= B_OK) {
|
||||
fIsDirectory = true;
|
||||
|
||||
while (directory.GetNextEntry(&entry) >= B_OK) {
|
||||
if (entry.GetRef(ref) < B_OK)
|
||||
continue;
|
||||
|
||||
WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref);
|
||||
if (child == NULL)
|
||||
continue;
|
||||
if (child->InitCheck() == false) {
|
||||
delete child;
|
||||
continue;
|
||||
}
|
||||
|
||||
child->fLink = fEntries;
|
||||
fEntries = child;
|
||||
}
|
||||
|
||||
watch_node(&fNode, B_WATCH_DIRECTORY, *fMessenger);
|
||||
}
|
||||
else {
|
||||
if (strncmp(ref->name, "raw", 3) == 0)
|
||||
return;
|
||||
|
||||
BPath path, parent_path;
|
||||
entry.GetPath(&path);
|
||||
fDevice = new(std::nothrow) USBDevice(path.Path());
|
||||
if (fDevice != NULL && fDevice->InitCheck() == true) {
|
||||
// Add this new device to each active context's device list
|
||||
struct libusb_context *ctx;
|
||||
unsigned long session_id = (unsigned long)&fDevice;
|
||||
|
||||
usbi_mutex_lock(&active_contexts_lock);
|
||||
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
|
||||
struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id);
|
||||
if (dev) {
|
||||
usbi_dbg("using previously allocated device with location %lu", session_id);
|
||||
libusb_unref_device(dev);
|
||||
continue;
|
||||
}
|
||||
usbi_dbg("allocating new device with location %lu", session_id);
|
||||
dev = usbi_alloc_device(ctx, session_id);
|
||||
if (!dev) {
|
||||
usbi_dbg("device allocation failed");
|
||||
continue;
|
||||
}
|
||||
*((USBDevice **)dev->os_priv) = fDevice;
|
||||
|
||||
// Calculate pseudo-device-address
|
||||
int addr, tmp;
|
||||
if (strcmp(path.Leaf(), "hub") == 0)
|
||||
tmp = 100; //Random Number
|
||||
else
|
||||
sscanf(path.Leaf(), "%d", &tmp);
|
||||
addr = tmp + 1;
|
||||
path.GetParent(&parent_path);
|
||||
while (strcmp(parent_path.Leaf(), "usb") != 0) {
|
||||
sscanf(parent_path.Leaf(), "%d", &tmp);
|
||||
addr += tmp + 1;
|
||||
parent_path.GetParent(&parent_path);
|
||||
}
|
||||
sscanf(path.Path(), "/dev/bus/usb/%d", &dev->bus_number);
|
||||
dev->device_address = addr - (dev->bus_number + 1);
|
||||
|
||||
if (usbi_sanitize_device(dev) < 0) {
|
||||
usbi_dbg("device sanitization failed");
|
||||
libusb_unref_device(dev);
|
||||
continue;
|
||||
}
|
||||
usbi_connect_device(dev);
|
||||
}
|
||||
usbi_mutex_unlock(&active_contexts_lock);
|
||||
}
|
||||
else if (fDevice) {
|
||||
delete fDevice;
|
||||
fDevice = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fInitCheck = true;
|
||||
}
|
||||
|
||||
|
||||
WatchedEntry::~WatchedEntry()
|
||||
{
|
||||
if (fIsDirectory) {
|
||||
watch_node(&fNode, B_STOP_WATCHING, *fMessenger);
|
||||
|
||||
WatchedEntry *child = fEntries;
|
||||
while (child) {
|
||||
WatchedEntry *next = child->fLink;
|
||||
delete child;
|
||||
child = next;
|
||||
}
|
||||
}
|
||||
|
||||
if (fDevice) {
|
||||
// Remove this device from each active context's device list
|
||||
struct libusb_context *ctx;
|
||||
struct libusb_device *dev;
|
||||
unsigned long session_id = (unsigned long)&fDevice;
|
||||
|
||||
usbi_mutex_lock(&active_contexts_lock);
|
||||
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
|
||||
dev = usbi_get_device_by_session_id(ctx, session_id);
|
||||
if (dev != NULL) {
|
||||
usbi_disconnect_device(dev);
|
||||
libusb_unref_device(dev);
|
||||
} else {
|
||||
usbi_dbg("device with location %lu not found", session_id);
|
||||
}
|
||||
}
|
||||
usbi_mutex_static_unlock(&active_contexts_lock);
|
||||
delete fDevice;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WatchedEntry::EntryCreated(entry_ref *ref)
|
||||
{
|
||||
if (!fIsDirectory)
|
||||
return false;
|
||||
|
||||
if (ref->directory != fNode.node) {
|
||||
WatchedEntry *child = fEntries;
|
||||
while (child) {
|
||||
if (child->EntryCreated(ref))
|
||||
return true;
|
||||
child = child->fLink;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref);
|
||||
if (child == NULL)
|
||||
return false;
|
||||
child->fLink = fEntries;
|
||||
fEntries = child;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WatchedEntry::EntryRemoved(ino_t node)
|
||||
{
|
||||
if (!fIsDirectory)
|
||||
return false;
|
||||
|
||||
WatchedEntry *child = fEntries;
|
||||
WatchedEntry *lastChild = NULL;
|
||||
while (child) {
|
||||
if (child->fNode.node == node) {
|
||||
if (lastChild)
|
||||
lastChild->fLink = child->fLink;
|
||||
else
|
||||
fEntries = child->fLink;
|
||||
delete child;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (child->EntryRemoved(node))
|
||||
return true;
|
||||
|
||||
lastChild = child;
|
||||
child = child->fLink;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WatchedEntry::InitCheck()
|
||||
{
|
||||
return fInitCheck;
|
||||
}
|
||||
|
||||
|
||||
RosterLooper::RosterLooper(USBRoster *roster)
|
||||
: BLooper("LibusbRoster Looper"),
|
||||
fRoster(roster),
|
||||
fRoot(NULL),
|
||||
fMessenger(NULL),
|
||||
fInitCheck(false)
|
||||
{
|
||||
BEntry entry("/dev/bus/usb");
|
||||
if (!entry.Exists()) {
|
||||
usbi_err(NULL, "usb_raw not published");
|
||||
return;
|
||||
}
|
||||
|
||||
Run();
|
||||
fMessenger = new(std::nothrow) BMessenger(this);
|
||||
if (fMessenger == NULL) {
|
||||
usbi_err(NULL, "error creating BMessenger object");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Lock()) {
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
fRoot = new(std::nothrow) WatchedEntry(fMessenger, &ref);
|
||||
Unlock();
|
||||
if (fRoot == NULL)
|
||||
return;
|
||||
if (fRoot->InitCheck() == false) {
|
||||
delete fRoot;
|
||||
fRoot = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fInitCheck = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterLooper::Stop()
|
||||
{
|
||||
Lock();
|
||||
delete fRoot;
|
||||
delete fMessenger;
|
||||
Quit();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterLooper::MessageReceived(BMessage *message)
|
||||
{
|
||||
int32 opcode;
|
||||
if (message->FindInt32("opcode", &opcode) < B_OK)
|
||||
return;
|
||||
|
||||
switch (opcode) {
|
||||
case B_ENTRY_CREATED:
|
||||
{
|
||||
dev_t device;
|
||||
ino_t directory;
|
||||
const char *name;
|
||||
if (message->FindInt32("device", &device) < B_OK ||
|
||||
message->FindInt64("directory", &directory) < B_OK ||
|
||||
message->FindString("name", &name) < B_OK)
|
||||
break;
|
||||
|
||||
entry_ref ref(device, directory, name);
|
||||
fRoot->EntryCreated(&ref);
|
||||
break;
|
||||
}
|
||||
case B_ENTRY_REMOVED:
|
||||
{
|
||||
ino_t node;
|
||||
if (message->FindInt64("node", &node) < B_OK)
|
||||
break;
|
||||
fRoot->EntryRemoved(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RosterLooper::InitCheck()
|
||||
{
|
||||
return fInitCheck;
|
||||
}
|
||||
|
||||
|
||||
USBRoster::USBRoster()
|
||||
: fLooper(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
USBRoster::~USBRoster()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
USBRoster::Start()
|
||||
{
|
||||
if (fLooper == NULL) {
|
||||
fLooper = new(std::nothrow) RosterLooper(this);
|
||||
if (fLooper == NULL || ((RosterLooper *)fLooper)->InitCheck() == false) {
|
||||
if (fLooper)
|
||||
fLooper = NULL;
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
}
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
USBRoster::Stop()
|
||||
{
|
||||
if (fLooper) {
|
||||
((RosterLooper *)fLooper)->Stop();
|
||||
fLooper = NULL;
|
||||
}
|
||||
}
|
||||
113
externals/libusb/libusb/libusb/os/haiku_usb.h
vendored
Executable file
113
externals/libusb/libusb/libusb/os/haiku_usb.h
vendored
Executable file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Haiku Backend for libusb
|
||||
* Copyright © 2014 Akshay Jaggi <akshay1994.leo@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 <List.h>
|
||||
#include <Locker.h>
|
||||
#include <Autolock.h>
|
||||
#include <USBKit.h>
|
||||
#include <map>
|
||||
#include "libusbi.h"
|
||||
#include "haiku_usb_raw.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class USBDevice;
|
||||
class USBDeviceHandle;
|
||||
class USBTransfer;
|
||||
|
||||
class USBDevice {
|
||||
public:
|
||||
USBDevice(const char *);
|
||||
virtual ~USBDevice();
|
||||
const char* Location() const;
|
||||
uint8 CountConfigurations() const;
|
||||
const usb_device_descriptor* Descriptor() const;
|
||||
const usb_configuration_descriptor* ConfigurationDescriptor(uint32) const;
|
||||
const usb_configuration_descriptor* ActiveConfiguration() const;
|
||||
uint8 EndpointToIndex(uint8) const;
|
||||
uint8 EndpointToInterface(uint8) const;
|
||||
int ClaimInterface(int);
|
||||
int ReleaseInterface(int);
|
||||
int CheckInterfacesFree(int);
|
||||
int SetActiveConfiguration(int);
|
||||
int ActiveConfigurationIndex() const;
|
||||
bool InitCheck();
|
||||
private:
|
||||
int Initialise();
|
||||
unsigned int fClaimedInterfaces; // Max Interfaces can be 32. Using a bitmask
|
||||
usb_device_descriptor fDeviceDescriptor;
|
||||
unsigned char** fConfigurationDescriptors;
|
||||
int fActiveConfiguration;
|
||||
char* fPath;
|
||||
map<uint8,uint8> fConfigToIndex;
|
||||
map<uint8,uint8>* fEndpointToIndex;
|
||||
map<uint8,uint8>* fEndpointToInterface;
|
||||
bool fInitCheck;
|
||||
};
|
||||
|
||||
class USBDeviceHandle {
|
||||
public:
|
||||
USBDeviceHandle(USBDevice *dev);
|
||||
virtual ~USBDeviceHandle();
|
||||
int ClaimInterface(int);
|
||||
int ReleaseInterface(int);
|
||||
int SetConfiguration(int);
|
||||
int SetAltSetting(int, int);
|
||||
int ClearHalt(int);
|
||||
status_t SubmitTransfer(struct usbi_transfer *);
|
||||
status_t CancelTransfer(USBTransfer *);
|
||||
bool InitCheck();
|
||||
private:
|
||||
int fRawFD;
|
||||
static status_t TransfersThread(void *);
|
||||
void TransfersWorker();
|
||||
USBDevice* fUSBDevice;
|
||||
unsigned int fClaimedInterfaces;
|
||||
BList fTransfers;
|
||||
BLocker fTransfersLock;
|
||||
sem_id fTransfersSem;
|
||||
thread_id fTransfersThread;
|
||||
bool fInitCheck;
|
||||
};
|
||||
|
||||
class USBTransfer {
|
||||
public:
|
||||
USBTransfer(struct usbi_transfer *, USBDevice *);
|
||||
virtual ~USBTransfer();
|
||||
void Do(int);
|
||||
struct usbi_transfer* UsbiTransfer();
|
||||
void SetCancelled();
|
||||
bool IsCancelled();
|
||||
private:
|
||||
struct usbi_transfer* fUsbiTransfer;
|
||||
struct libusb_transfer* fLibusbTransfer;
|
||||
USBDevice* fUSBDevice;
|
||||
BLocker fStatusLock;
|
||||
bool fCancelled;
|
||||
};
|
||||
|
||||
class USBRoster {
|
||||
public:
|
||||
USBRoster();
|
||||
virtual ~USBRoster();
|
||||
int Start();
|
||||
void Stop();
|
||||
private:
|
||||
void* fLooper;
|
||||
};
|
||||
533
externals/libusb/libusb/libusb/os/haiku_usb_backend.cpp
vendored
Executable file
533
externals/libusb/libusb/libusb/os/haiku_usb_backend.cpp
vendored
Executable file
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Haiku Backend for libusb
|
||||
* Copyright © 2014 Akshay Jaggi <akshay1994.leo@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 <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
|
||||
#include "haiku_usb.h"
|
||||
|
||||
int _errno_to_libusb(int status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
USBTransfer::USBTransfer(struct usbi_transfer *itransfer, USBDevice *device)
|
||||
{
|
||||
fUsbiTransfer = itransfer;
|
||||
fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
fUSBDevice = device;
|
||||
fCancelled = false;
|
||||
}
|
||||
|
||||
USBTransfer::~USBTransfer()
|
||||
{
|
||||
}
|
||||
|
||||
struct usbi_transfer *
|
||||
USBTransfer::UsbiTransfer()
|
||||
{
|
||||
return fUsbiTransfer;
|
||||
}
|
||||
|
||||
void
|
||||
USBTransfer::SetCancelled()
|
||||
{
|
||||
fCancelled = true;
|
||||
}
|
||||
|
||||
bool
|
||||
USBTransfer::IsCancelled()
|
||||
{
|
||||
return fCancelled;
|
||||
}
|
||||
|
||||
void
|
||||
USBTransfer::Do(int fRawFD)
|
||||
{
|
||||
switch (fLibusbTransfer->type) {
|
||||
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
||||
{
|
||||
struct libusb_control_setup *setup = (struct libusb_control_setup *)fLibusbTransfer->buffer;
|
||||
usb_raw_command command;
|
||||
command.control.request_type = setup->bmRequestType;
|
||||
command.control.request = setup->bRequest;
|
||||
command.control.value = setup->wValue;
|
||||
command.control.index = setup->wIndex;
|
||||
command.control.length = setup->wLength;
|
||||
command.control.data = fLibusbTransfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
|
||||
if (fCancelled)
|
||||
break;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) ||
|
||||
command.control.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
fUsbiTransfer->transferred = -1;
|
||||
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed control transfer");
|
||||
break;
|
||||
}
|
||||
fUsbiTransfer->transferred = command.control.length;
|
||||
}
|
||||
break;
|
||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||
{
|
||||
usb_raw_command command;
|
||||
command.transfer.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
|
||||
command.transfer.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
|
||||
command.transfer.data = fLibusbTransfer->buffer;
|
||||
command.transfer.length = fLibusbTransfer->length;
|
||||
if (fCancelled)
|
||||
break;
|
||||
if (fLibusbTransfer->type == LIBUSB_TRANSFER_TYPE_BULK) {
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_BULK_TRANSFER, &command, sizeof(command)) ||
|
||||
command.transfer.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
fUsbiTransfer->transferred = -1;
|
||||
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed bulk transfer");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, &command, sizeof(command)) ||
|
||||
command.transfer.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
fUsbiTransfer->transferred = -1;
|
||||
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed interrupt transfer");
|
||||
break;
|
||||
}
|
||||
}
|
||||
fUsbiTransfer->transferred = command.transfer.length;
|
||||
}
|
||||
break;
|
||||
// IsochronousTransfers not tested
|
||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||
{
|
||||
usb_raw_command command;
|
||||
command.isochronous.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
|
||||
command.isochronous.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
|
||||
command.isochronous.data = fLibusbTransfer->buffer;
|
||||
command.isochronous.length = fLibusbTransfer->length;
|
||||
command.isochronous.packet_count = fLibusbTransfer->num_iso_packets;
|
||||
int i;
|
||||
usb_iso_packet_descriptor *packetDescriptors = new usb_iso_packet_descriptor[fLibusbTransfer->num_iso_packets];
|
||||
for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) {
|
||||
if ((int16)(fLibusbTransfer->iso_packet_desc[i]).length != (fLibusbTransfer->iso_packet_desc[i]).length) {
|
||||
fUsbiTransfer->transferred = -1;
|
||||
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer");
|
||||
break;
|
||||
}
|
||||
packetDescriptors[i].request_length = (int16)(fLibusbTransfer->iso_packet_desc[i]).length;
|
||||
}
|
||||
if (i < fLibusbTransfer->num_iso_packets)
|
||||
break; // TODO Handle this error
|
||||
command.isochronous.packet_descriptors = packetDescriptors;
|
||||
if (fCancelled)
|
||||
break;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER, &command, sizeof(command)) ||
|
||||
command.isochronous.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
fUsbiTransfer->transferred = -1;
|
||||
usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer");
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) {
|
||||
(fLibusbTransfer->iso_packet_desc[i]).actual_length = packetDescriptors[i].actual_length;
|
||||
switch (packetDescriptors[i].status) {
|
||||
case B_OK:
|
||||
(fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_COMPLETED;
|
||||
break;
|
||||
default:
|
||||
(fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete[] packetDescriptors;
|
||||
// Do we put the length of transfer here, for isochronous transfers?
|
||||
fUsbiTransfer->transferred = command.transfer.length;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usbi_err(TRANSFER_CTX(fLibusbTransfer), "Unknown type of transfer");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
USBDeviceHandle::InitCheck()
|
||||
{
|
||||
return fInitCheck;
|
||||
}
|
||||
|
||||
status_t
|
||||
USBDeviceHandle::TransfersThread(void *self)
|
||||
{
|
||||
USBDeviceHandle *handle = (USBDeviceHandle *)self;
|
||||
handle->TransfersWorker();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
USBDeviceHandle::TransfersWorker()
|
||||
{
|
||||
while (true) {
|
||||
status_t status = acquire_sem(fTransfersSem);
|
||||
if (status == B_BAD_SEM_ID)
|
||||
break;
|
||||
if (status == B_INTERRUPTED)
|
||||
continue;
|
||||
fTransfersLock.Lock();
|
||||
USBTransfer *fPendingTransfer = (USBTransfer *) fTransfers.RemoveItem((int32)0);
|
||||
fTransfersLock.Unlock();
|
||||
fPendingTransfer->Do(fRawFD);
|
||||
usbi_signal_transfer_completion(fPendingTransfer->UsbiTransfer());
|
||||
}
|
||||
}
|
||||
|
||||
status_t
|
||||
USBDeviceHandle::SubmitTransfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
USBTransfer *transfer = new USBTransfer(itransfer, fUSBDevice);
|
||||
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = transfer;
|
||||
BAutolock locker(fTransfersLock);
|
||||
fTransfers.AddItem(transfer);
|
||||
release_sem(fTransfersSem);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
status_t
|
||||
USBDeviceHandle::CancelTransfer(USBTransfer *transfer)
|
||||
{
|
||||
transfer->SetCancelled();
|
||||
fTransfersLock.Lock();
|
||||
bool removed = fTransfers.RemoveItem(transfer);
|
||||
fTransfersLock.Unlock();
|
||||
if(removed)
|
||||
usbi_signal_transfer_completion(transfer->UsbiTransfer());
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
USBDeviceHandle::USBDeviceHandle(USBDevice *dev)
|
||||
:
|
||||
fTransfersThread(-1),
|
||||
fUSBDevice(dev),
|
||||
fClaimedInterfaces(0),
|
||||
fInitCheck(false)
|
||||
{
|
||||
fRawFD = open(dev->Location(), O_RDWR | O_CLOEXEC);
|
||||
if (fRawFD < 0) {
|
||||
usbi_err(NULL,"failed to open device");
|
||||
return;
|
||||
}
|
||||
fTransfersSem = create_sem(0, "Transfers Queue Sem");
|
||||
fTransfersThread = spawn_thread(TransfersThread, "Transfer Worker", B_NORMAL_PRIORITY, this);
|
||||
resume_thread(fTransfersThread);
|
||||
fInitCheck = true;
|
||||
}
|
||||
|
||||
USBDeviceHandle::~USBDeviceHandle()
|
||||
{
|
||||
if (fRawFD > 0)
|
||||
close(fRawFD);
|
||||
for(int i = 0; i < 32; i++) {
|
||||
if (fClaimedInterfaces & (1U << i))
|
||||
ReleaseInterface(i);
|
||||
}
|
||||
delete_sem(fTransfersSem);
|
||||
if (fTransfersThread > 0)
|
||||
wait_for_thread(fTransfersThread, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
USBDeviceHandle::ClaimInterface(int inumber)
|
||||
{
|
||||
int status = fUSBDevice->ClaimInterface(inumber);
|
||||
if (status == LIBUSB_SUCCESS)
|
||||
fClaimedInterfaces |= (1U << inumber);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
USBDeviceHandle::ReleaseInterface(int inumber)
|
||||
{
|
||||
fUSBDevice->ReleaseInterface(inumber);
|
||||
fClaimedInterfaces &= ~(1U << inumber);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
USBDeviceHandle::SetConfiguration(int config)
|
||||
{
|
||||
int config_index = fUSBDevice->CheckInterfacesFree(config);
|
||||
if(config_index == LIBUSB_ERROR_BUSY || config_index == LIBUSB_ERROR_NOT_FOUND)
|
||||
return config_index;
|
||||
usb_raw_command command;
|
||||
command.config.config_index = config_index;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_CONFIGURATION, &command, sizeof(command)) ||
|
||||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
return _errno_to_libusb(command.config.status);
|
||||
}
|
||||
fUSBDevice->SetActiveConfiguration(config_index);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
USBDeviceHandle::SetAltSetting(int inumber, int alt)
|
||||
{
|
||||
usb_raw_command command;
|
||||
command.alternate.config_index = fUSBDevice->ActiveConfigurationIndex();
|
||||
command.alternate.interface_index = inumber;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command, sizeof(command)) ||
|
||||
command.alternate.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
usbi_err(NULL, "Error retrieving active alternate interface");
|
||||
return _errno_to_libusb(command.alternate.status);
|
||||
}
|
||||
if (command.alternate.alternate_info == alt) {
|
||||
usbi_dbg("Setting alternate interface successful");
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
command.alternate.alternate_info = alt;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command, sizeof(command)) ||
|
||||
command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY
|
||||
usbi_err(NULL, "Error setting alternate interface");
|
||||
return _errno_to_libusb(command.alternate.status);
|
||||
}
|
||||
usbi_dbg("Setting alternate interface successful");
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
USBDevice::ClearHalt(int endpoint)
|
||||
{
|
||||
usb_raw_command command;
|
||||
command.control.request_type = USB_REQTYPE_ENDPOINT_OUT;
|
||||
command.control.request = USB_REQUEST_CLEAR_FEATURE;
|
||||
command.control.value = USB_FEATURE_ENDPOINT_HALT;
|
||||
command.control.index = endpoint;
|
||||
command.control.length = 0;
|
||||
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) ||
|
||||
command.control.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
return _errno_to_libusb(command.control.status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
USBDevice::USBDevice(const char *path)
|
||||
:
|
||||
fPath(NULL),
|
||||
fActiveConfiguration(0), //0?
|
||||
fConfigurationDescriptors(NULL),
|
||||
fClaimedInterfaces(0),
|
||||
fEndpointToIndex(NULL),
|
||||
fEndpointToInterface(NULL),
|
||||
fInitCheck(false)
|
||||
{
|
||||
fPath=strdup(path);
|
||||
Initialise();
|
||||
}
|
||||
|
||||
USBDevice::~USBDevice()
|
||||
{
|
||||
free(fPath);
|
||||
if (fConfigurationDescriptors) {
|
||||
for(int i = 0; i < fDeviceDescriptor.num_configurations; i++) {
|
||||
if (fConfigurationDescriptors[i])
|
||||
delete fConfigurationDescriptors[i];
|
||||
}
|
||||
delete[] fConfigurationDescriptors;
|
||||
}
|
||||
if (fEndpointToIndex)
|
||||
delete[] fEndpointToIndex;
|
||||
if (fEndpointToInterface)
|
||||
delete[] fEndpointToInterface;
|
||||
}
|
||||
|
||||
bool
|
||||
USBDevice::InitCheck()
|
||||
{
|
||||
return fInitCheck;
|
||||
}
|
||||
|
||||
const char *
|
||||
USBDevice::Location() const
|
||||
{
|
||||
return fPath;
|
||||
}
|
||||
|
||||
uint8
|
||||
USBDevice::CountConfigurations() const
|
||||
{
|
||||
return fDeviceDescriptor.num_configurations;
|
||||
}
|
||||
|
||||
const usb_device_descriptor *
|
||||
USBDevice::Descriptor() const
|
||||
{
|
||||
return &fDeviceDescriptor;
|
||||
}
|
||||
|
||||
const usb_configuration_descriptor *
|
||||
USBDevice::ConfigurationDescriptor(uint32 index) const
|
||||
{
|
||||
if (index > CountConfigurations())
|
||||
return NULL;
|
||||
return (usb_configuration_descriptor *) fConfigurationDescriptors[index];
|
||||
}
|
||||
|
||||
const usb_configuration_descriptor *
|
||||
USBDevice::ActiveConfiguration() const
|
||||
{
|
||||
return (usb_configuration_descriptor *) fConfigurationDescriptors[fActiveConfiguration];
|
||||
}
|
||||
|
||||
int
|
||||
USBDevice::ActiveConfigurationIndex() const
|
||||
{
|
||||
return fActiveConfiguration;
|
||||
}
|
||||
|
||||
int USBDevice::ClaimInterface(int interface)
|
||||
{
|
||||
if (interface > ActiveConfiguration()->number_interfaces)
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
if (fClaimedInterfaces & (1U << interface))
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
fClaimedInterfaces |= (1U << interface);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
int USBDevice::ReleaseInterface(int interface)
|
||||
{
|
||||
fClaimedInterfaces &= ~(1U << interface);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
USBDevice::CheckInterfacesFree(int config)
|
||||
{
|
||||
if (fConfigToIndex.count(config) == 0)
|
||||
return LIBUSB_ERROR_NOT_FOUND;
|
||||
if (fClaimedInterfaces == 0)
|
||||
return fConfigToIndex[(uint8)config];
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
}
|
||||
|
||||
int
|
||||
USBDevice::SetActiveConfiguration(int config_index)
|
||||
{
|
||||
fActiveConfiguration = config_index;
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
uint8
|
||||
USBDevice::EndpointToIndex(uint8 address) const
|
||||
{
|
||||
return fEndpointToIndex[fActiveConfiguration][address];
|
||||
}
|
||||
|
||||
uint8
|
||||
USBDevice::EndpointToInterface(uint8 address) const
|
||||
{
|
||||
return fEndpointToInterface[fActiveConfiguration][address];
|
||||
}
|
||||
|
||||
int
|
||||
USBDevice::Initialise() //Do we need more error checking, etc? How to report?
|
||||
{
|
||||
int fRawFD = open(fPath, O_RDWR | O_CLOEXEC);
|
||||
if (fRawFD < 0)
|
||||
return B_ERROR;
|
||||
usb_raw_command command;
|
||||
command.device.descriptor = &fDeviceDescriptor;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR, &command, sizeof(command)) ||
|
||||
command.device.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
close(fRawFD);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fConfigurationDescriptors = new(std::nothrow) unsigned char *[fDeviceDescriptor.num_configurations];
|
||||
fEndpointToIndex = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
|
||||
fEndpointToInterface = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
|
||||
for (int i = 0; i < fDeviceDescriptor.num_configurations; i++) {
|
||||
usb_configuration_descriptor tmp_config;
|
||||
command.config.descriptor = &tmp_config;
|
||||
command.config.config_index = i;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command, sizeof(command)) ||
|
||||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
usbi_err(NULL, "failed retrieving configuration descriptor");
|
||||
close(fRawFD);
|
||||
return B_ERROR;
|
||||
}
|
||||
fConfigToIndex[tmp_config.configuration_value] = i;
|
||||
fConfigurationDescriptors[i] = new(std::nothrow) unsigned char[tmp_config.total_length];
|
||||
|
||||
command.config_etc.descriptor = (usb_configuration_descriptor*)fConfigurationDescriptors[i];
|
||||
command.config_etc.length = tmp_config.total_length;
|
||||
command.config_etc.config_index = i;
|
||||
if (ioctl(fRawFD, B_USB_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC, &command, sizeof(command)) ||
|
||||
command.config_etc.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
usbi_err(NULL, "failed retrieving full configuration descriptor");
|
||||
close(fRawFD);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
for (int j = 0; j < tmp_config.number_interfaces; j++) {
|
||||
command.alternate.config_index = i;
|
||||
command.alternate.interface_index = j;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command, sizeof(command)) ||
|
||||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
usbi_err(NULL, "failed retrieving number of alternate interfaces");
|
||||
close(fRawFD);
|
||||
return B_ERROR;
|
||||
}
|
||||
int num_alternate = command.alternate.alternate_info;
|
||||
for (int k = 0; k < num_alternate; k++) {
|
||||
usb_interface_descriptor tmp_interface;
|
||||
command.interface_etc.config_index = i;
|
||||
command.interface_etc.interface_index = j;
|
||||
command.interface_etc.alternate_index = k;
|
||||
command.interface_etc.descriptor = &tmp_interface;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command, sizeof(command)) ||
|
||||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
usbi_err(NULL, "failed retrieving interface descriptor");
|
||||
close(fRawFD);
|
||||
return B_ERROR;
|
||||
}
|
||||
for (int l = 0; l < tmp_interface.num_endpoints; l++) {
|
||||
usb_endpoint_descriptor tmp_endpoint;
|
||||
command.endpoint_etc.config_index = i;
|
||||
command.endpoint_etc.interface_index = j;
|
||||
command.endpoint_etc.alternate_index = k;
|
||||
command.endpoint_etc.endpoint_index = l;
|
||||
command.endpoint_etc.descriptor = &tmp_endpoint;
|
||||
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command, sizeof(command)) ||
|
||||
command.config.status != B_USB_RAW_STATUS_SUCCESS) {
|
||||
usbi_err(NULL, "failed retrieving endpoint descriptor");
|
||||
close(fRawFD);
|
||||
return B_ERROR;
|
||||
}
|
||||
fEndpointToIndex[i][tmp_endpoint.endpoint_address] = l;
|
||||
fEndpointToInterface[i][tmp_endpoint.endpoint_address] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fRawFD);
|
||||
fInitCheck = true;
|
||||
return B_OK;
|
||||
}
|
||||
267
externals/libusb/libusb/libusb/os/haiku_usb_raw.cpp
vendored
Executable file
267
externals/libusb/libusb/libusb/os/haiku_usb_raw.cpp
vendored
Executable file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Haiku Backend for libusb
|
||||
* Copyright © 2014 Akshay Jaggi <akshay1994.leo@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 <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
|
||||
#include "haiku_usb.h"
|
||||
|
||||
USBRoster gUsbRoster;
|
||||
int32 gInitCount = 0;
|
||||
|
||||
static int haiku_get_config_descriptor(struct libusb_device *, uint8_t,
|
||||
unsigned char *, size_t, int *);
|
||||
|
||||
static int
|
||||
haiku_init(struct libusb_context *ctx)
|
||||
{
|
||||
if (atomic_add(&gInitCount, 1) == 0)
|
||||
return gUsbRoster.Start();
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
haiku_exit(struct libusb_context *ctx)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
if (atomic_add(&gInitCount, -1) == 1)
|
||||
gUsbRoster.Stop();
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_open(struct libusb_device_handle *dev_handle)
|
||||
{
|
||||
USBDevice *dev = *((USBDevice **)dev_handle->dev->os_priv);
|
||||
USBDeviceHandle *handle = new(std::nothrow) USBDeviceHandle(dev);
|
||||
if (handle == NULL)
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
if (handle->InitCheck() == false) {
|
||||
delete handle;
|
||||
return LIBUSB_ERROR_NO_DEVICE;
|
||||
}
|
||||
*((USBDeviceHandle **)dev_handle->os_priv) = handle;
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
haiku_close(struct libusb_device_handle *dev_handle)
|
||||
{
|
||||
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
|
||||
if (handle == NULL)
|
||||
return;
|
||||
delete handle;
|
||||
*((USBDeviceHandle **)dev_handle->os_priv) = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_get_device_descriptor(struct libusb_device *device, unsigned char *buffer, int *host_endian)
|
||||
{
|
||||
USBDevice *dev = *((USBDevice **)device->os_priv);
|
||||
memcpy(buffer, dev->Descriptor(), DEVICE_DESC_LENGTH);
|
||||
*host_endian = 0;
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_get_active_config_descriptor(struct libusb_device *device, unsigned char *buffer, size_t len, int *host_endian)
|
||||
{
|
||||
USBDevice *dev = *((USBDevice **)device->os_priv);
|
||||
return haiku_get_config_descriptor(device, dev->ActiveConfigurationIndex(), buffer, len, host_endian);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
|
||||
{
|
||||
USBDevice *dev = *((USBDevice **)device->os_priv);
|
||||
const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index);
|
||||
if (config == NULL) {
|
||||
usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor");
|
||||
return LIBUSB_ERROR_INVALID_PARAM;
|
||||
}
|
||||
if (len > config->total_length) {
|
||||
len = config->total_length;
|
||||
}
|
||||
memcpy(buffer, config, len);
|
||||
*host_endian = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_set_configuration(struct libusb_device_handle *dev_handle, int config)
|
||||
{
|
||||
USBDeviceHandle *handle= *((USBDeviceHandle **)dev_handle->os_priv);
|
||||
return handle->SetConfiguration(config);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
|
||||
{
|
||||
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
|
||||
return handle->ClaimInterface(interface_number);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_set_altsetting(struct libusb_device_handle *dev_handle, int interface_number, int altsetting)
|
||||
{
|
||||
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
|
||||
return handle->SetAltSetting(interface_number, altsetting);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
|
||||
{
|
||||
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
|
||||
return handle->ClearHalt(endpoint);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_reset_device(struct libusb_device_handle *dev_handle)
|
||||
{
|
||||
/* TODO */
|
||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
|
||||
{
|
||||
USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
|
||||
haiku_set_altsetting(dev_handle,interface_number, 0);
|
||||
return handle->ReleaseInterface(interface_number);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_submit_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
|
||||
return fDeviceHandle->SubmitTransfer(itransfer);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_cancel_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
|
||||
return fDeviceHandle->CancelTransfer(*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)));
|
||||
}
|
||||
|
||||
static void
|
||||
haiku_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||
{
|
||||
USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
|
||||
delete transfer;
|
||||
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_handle_transfer_completion(struct usbi_transfer *itransfer)
|
||||
{
|
||||
USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
|
||||
|
||||
usbi_mutex_lock(&itransfer->lock);
|
||||
if (transfer->IsCancelled()) {
|
||||
delete transfer;
|
||||
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
|
||||
usbi_mutex_unlock(&itransfer->lock);
|
||||
if (itransfer->transferred < 0)
|
||||
itransfer->transferred = 0;
|
||||
return usbi_handle_transfer_cancellation(itransfer);
|
||||
}
|
||||
libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED;
|
||||
if (itransfer->transferred < 0) {
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "error in transfer");
|
||||
status = LIBUSB_TRANSFER_ERROR;
|
||||
itransfer->transferred = 0;
|
||||
}
|
||||
delete transfer;
|
||||
*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
|
||||
usbi_mutex_unlock(&itransfer->lock);
|
||||
return usbi_handle_transfer_completion(itransfer, status);
|
||||
}
|
||||
|
||||
static int
|
||||
haiku_clock_gettime(int clkid, struct timespec *tp)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
const struct usbi_os_backend usbi_backend = {
|
||||
.name = "Haiku usbfs",
|
||||
.caps = 0,
|
||||
.init = haiku_init,
|
||||
.exit = haiku_exit,
|
||||
.set_option = NULL,
|
||||
.get_device_list = NULL,
|
||||
.hotplug_poll = NULL,
|
||||
.wrap_sys_device = NULL,
|
||||
.open = haiku_open,
|
||||
.close = haiku_close,
|
||||
.get_device_descriptor = haiku_get_device_descriptor,
|
||||
.get_active_config_descriptor = haiku_get_active_config_descriptor,
|
||||
.get_config_descriptor = haiku_get_config_descriptor,
|
||||
.get_config_descriptor_by_value = NULL,
|
||||
|
||||
|
||||
.get_configuration = NULL,
|
||||
.set_configuration = haiku_set_configuration,
|
||||
.claim_interface = haiku_claim_interface,
|
||||
.release_interface = haiku_release_interface,
|
||||
|
||||
.set_interface_altsetting = haiku_set_altsetting,
|
||||
.clear_halt = haiku_clear_halt,
|
||||
.reset_device = haiku_reset_device,
|
||||
|
||||
.alloc_streams = NULL,
|
||||
.free_streams = NULL,
|
||||
|
||||
.dev_mem_alloc = NULL,
|
||||
.dev_mem_free = NULL,
|
||||
|
||||
.kernel_driver_active = NULL,
|
||||
.detach_kernel_driver = NULL,
|
||||
.attach_kernel_driver = NULL,
|
||||
|
||||
.destroy_device = NULL,
|
||||
|
||||
.submit_transfer = haiku_submit_transfer,
|
||||
.cancel_transfer = haiku_cancel_transfer,
|
||||
.clear_transfer_priv = haiku_clear_transfer_priv,
|
||||
|
||||
.handle_events = NULL,
|
||||
.handle_transfer_completion = haiku_handle_transfer_completion,
|
||||
|
||||
.clock_gettime = haiku_clock_gettime,
|
||||
|
||||
#ifdef USBI_TIMERFD_AVAILABLE
|
||||
.get_timerfd_clockid = NULL,
|
||||
#endif
|
||||
|
||||
.context_priv_size = 0,
|
||||
.device_priv_size = sizeof(USBDevice *),
|
||||
.device_handle_priv_size = sizeof(USBDeviceHandle *),
|
||||
.transfer_priv_size = sizeof(USBTransfer *),
|
||||
};
|
||||
188
externals/libusb/libusb/libusb/os/haiku_usb_raw.h
vendored
Executable file
188
externals/libusb/libusb/libusb/os/haiku_usb_raw.h
vendored
Executable file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2006-2008, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _USB_RAW_H_
|
||||
#define _USB_RAW_H_
|
||||
|
||||
#include <USB3.h>
|
||||
|
||||
#define B_USB_RAW_PROTOCOL_VERSION 0x0015
|
||||
#define B_USB_RAW_ACTIVE_ALTERNATE 0xffffffff
|
||||
|
||||
typedef enum {
|
||||
B_USB_RAW_COMMAND_GET_VERSION = 0x1000,
|
||||
|
||||
B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR = 0x2000,
|
||||
B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR,
|
||||
B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR,
|
||||
B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR,
|
||||
B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR,
|
||||
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR,
|
||||
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT,
|
||||
B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX,
|
||||
B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC,
|
||||
B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC,
|
||||
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC,
|
||||
B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC,
|
||||
|
||||
B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000,
|
||||
B_USB_RAW_COMMAND_SET_FEATURE,
|
||||
B_USB_RAW_COMMAND_CLEAR_FEATURE,
|
||||
B_USB_RAW_COMMAND_GET_STATUS,
|
||||
B_USB_RAW_COMMAND_GET_DESCRIPTOR,
|
||||
B_USB_RAW_COMMAND_SET_ALT_INTERFACE,
|
||||
|
||||
B_USB_RAW_COMMAND_CONTROL_TRANSFER = 0x4000,
|
||||
B_USB_RAW_COMMAND_INTERRUPT_TRANSFER,
|
||||
B_USB_RAW_COMMAND_BULK_TRANSFER,
|
||||
B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER
|
||||
} usb_raw_command_id;
|
||||
|
||||
|
||||
typedef enum {
|
||||
B_USB_RAW_STATUS_SUCCESS = 0,
|
||||
|
||||
B_USB_RAW_STATUS_FAILED,
|
||||
B_USB_RAW_STATUS_ABORTED,
|
||||
B_USB_RAW_STATUS_STALLED,
|
||||
B_USB_RAW_STATUS_CRC_ERROR,
|
||||
B_USB_RAW_STATUS_TIMEOUT,
|
||||
|
||||
B_USB_RAW_STATUS_INVALID_CONFIGURATION,
|
||||
B_USB_RAW_STATUS_INVALID_INTERFACE,
|
||||
B_USB_RAW_STATUS_INVALID_ENDPOINT,
|
||||
B_USB_RAW_STATUS_INVALID_STRING,
|
||||
|
||||
B_USB_RAW_STATUS_NO_MEMORY
|
||||
} usb_raw_command_status;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
status_t status;
|
||||
} version;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_device_descriptor *descriptor;
|
||||
} device;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_configuration_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
} config;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_configuration_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
size_t length;
|
||||
} config_etc;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
uint32 alternate_info;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
} alternate;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_interface_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
} interface;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_interface_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
uint32 alternate_index;
|
||||
} interface_etc;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_endpoint_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
uint32 endpoint_index;
|
||||
} endpoint;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_endpoint_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
uint32 alternate_index;
|
||||
uint32 endpoint_index;
|
||||
} endpoint_etc;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
uint32 generic_index;
|
||||
size_t length;
|
||||
} generic;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_descriptor *descriptor;
|
||||
uint32 config_index;
|
||||
uint32 interface_index;
|
||||
uint32 alternate_index;
|
||||
uint32 generic_index;
|
||||
size_t length;
|
||||
} generic_etc;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
usb_string_descriptor *descriptor;
|
||||
uint32 string_index;
|
||||
size_t length;
|
||||
} string;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
uint8 type;
|
||||
uint8 index;
|
||||
uint16 language_id;
|
||||
void *data;
|
||||
size_t length;
|
||||
} descriptor;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
uint8 request_type;
|
||||
uint8 request;
|
||||
uint16 value;
|
||||
uint16 index;
|
||||
uint16 length;
|
||||
void *data;
|
||||
} control;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
uint32 interface;
|
||||
uint32 endpoint;
|
||||
void *data;
|
||||
size_t length;
|
||||
} transfer;
|
||||
|
||||
struct {
|
||||
status_t status;
|
||||
uint32 interface;
|
||||
uint32 endpoint;
|
||||
void *data;
|
||||
size_t length;
|
||||
usb_iso_packet_descriptor *packet_descriptors;
|
||||
uint32 packet_count;
|
||||
} isochronous;
|
||||
} usb_raw_command;
|
||||
|
||||
#endif // _USB_RAW_H_
|
||||
409
externals/libusb/libusb/libusb/os/linux_netlink.c
vendored
Executable file
409
externals/libusb/libusb/libusb/os/linux_netlink.c
vendored
Executable file
@@ -0,0 +1,409 @@
|
||||
/* -*- 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>
|
||||
* Copyright (c) 2016 Chris Dickens <christopher.a.dickens@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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_ASM_TYPES_H
|
||||
#include <asm/types.h>
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
#include "linux_usbfs.h"
|
||||
|
||||
#define NL_GROUP_KERNEL 1
|
||||
|
||||
#ifndef SOCK_CLOEXEC
|
||||
#define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
#ifndef SOCK_NONBLOCK
|
||||
#define SOCK_NONBLOCK 0
|
||||
#endif
|
||||
|
||||
static int linux_netlink_socket = -1;
|
||||
static int netlink_control_pipe[2] = { -1, -1 };
|
||||
static pthread_t libusb_linux_event_thread;
|
||||
|
||||
static void *linux_netlink_event_thread_main(void *arg);
|
||||
|
||||
static int set_fd_cloexec_nb(int fd, int socktype)
|
||||
{
|
||||
int flags;
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
/* Make sure the netlink socket file descriptor is marked as CLOEXEC */
|
||||
if (!(socktype & SOCK_CLOEXEC)) {
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1) {
|
||||
usbi_err(NULL, "failed to get netlink fd flags (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
|
||||
usbi_err(NULL, "failed to set netlink fd flags (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure the netlink socket is non-blocking */
|
||||
if (!(socktype & SOCK_NONBLOCK)) {
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
if (flags == -1) {
|
||||
usbi_err(NULL, "failed to get netlink fd status flags (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||
usbi_err(NULL, "failed to set netlink fd status flags (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linux_netlink_start_event_monitor(void)
|
||||
{
|
||||
struct sockaddr_nl sa_nl = { .nl_family = AF_NETLINK, .nl_groups = NL_GROUP_KERNEL };
|
||||
int socktype = SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC;
|
||||
int opt = 1;
|
||||
int ret;
|
||||
|
||||
linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
|
||||
if (linux_netlink_socket == -1 && errno == EINVAL) {
|
||||
usbi_dbg("failed to create netlink socket of type %d, attempting SOCK_RAW", socktype);
|
||||
socktype = SOCK_RAW;
|
||||
linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
|
||||
}
|
||||
|
||||
if (linux_netlink_socket == -1) {
|
||||
usbi_err(NULL, "failed to create netlink socket (%d)", errno);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = set_fd_cloexec_nb(linux_netlink_socket, socktype);
|
||||
if (ret == -1)
|
||||
goto err_close_socket;
|
||||
|
||||
ret = bind(linux_netlink_socket, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to bind netlink socket (%d)", errno);
|
||||
goto err_close_socket;
|
||||
}
|
||||
|
||||
ret = setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to set netlink socket SO_PASSCRED option (%d)", errno);
|
||||
goto err_close_socket;
|
||||
}
|
||||
|
||||
ret = usbi_pipe(netlink_control_pipe);
|
||||
if (ret) {
|
||||
usbi_err(NULL, "failed to create netlink control pipe");
|
||||
goto err_close_socket;
|
||||
}
|
||||
|
||||
ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL);
|
||||
if (ret != 0) {
|
||||
usbi_err(NULL, "failed to create netlink event thread (%d)", ret);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
|
||||
err_close_pipe:
|
||||
close(netlink_control_pipe[0]);
|
||||
close(netlink_control_pipe[1]);
|
||||
netlink_control_pipe[0] = -1;
|
||||
netlink_control_pipe[1] = -1;
|
||||
err_close_socket:
|
||||
close(linux_netlink_socket);
|
||||
linux_netlink_socket = -1;
|
||||
err:
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
|
||||
int linux_netlink_stop_event_monitor(void)
|
||||
{
|
||||
char dummy = 1;
|
||||
ssize_t r;
|
||||
|
||||
assert(linux_netlink_socket != -1);
|
||||
|
||||
/* Write some dummy data to the control pipe and
|
||||
* wait for the thread to exit */
|
||||
r = write(netlink_control_pipe[1], &dummy, sizeof(dummy));
|
||||
if (r <= 0)
|
||||
usbi_warn(NULL, "netlink control pipe signal failed");
|
||||
|
||||
pthread_join(libusb_linux_event_thread, NULL);
|
||||
|
||||
close(linux_netlink_socket);
|
||||
linux_netlink_socket = -1;
|
||||
|
||||
/* close and reset control pipe */
|
||||
close(netlink_control_pipe[0]);
|
||||
close(netlink_control_pipe[1]);
|
||||
netlink_control_pipe[0] = -1;
|
||||
netlink_control_pipe[1] = -1;
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static const char *netlink_message_parse(const char *buffer, size_t len, const char *key)
|
||||
{
|
||||
const char *end = buffer + len;
|
||||
size_t keylen = strlen(key);
|
||||
|
||||
while (buffer < end && *buffer) {
|
||||
if (strncmp(buffer, key, keylen) == 0 && buffer[keylen] == '=')
|
||||
return buffer + keylen + 1;
|
||||
buffer += strlen(buffer) + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* parse parts of netlink message common to both libudev and the kernel */
|
||||
static int linux_netlink_parse(const char *buffer, size_t len, int *detached,
|
||||
const char **sys_name, uint8_t *busnum, uint8_t *devaddr)
|
||||
{
|
||||
const char *tmp, *slash;
|
||||
|
||||
errno = 0;
|
||||
|
||||
*sys_name = NULL;
|
||||
*detached = 0;
|
||||
*busnum = 0;
|
||||
*devaddr = 0;
|
||||
|
||||
tmp = netlink_message_parse(buffer, len, "ACTION");
|
||||
if (!tmp) {
|
||||
return -1;
|
||||
} else if (strcmp(tmp, "remove") == 0) {
|
||||
*detached = 1;
|
||||
} else if (strcmp(tmp, "add") != 0) {
|
||||
usbi_dbg("unknown device action %s", tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check that this is a usb message */
|
||||
tmp = netlink_message_parse(buffer, len, "SUBSYSTEM");
|
||||
if (!tmp || strcmp(tmp, "usb") != 0) {
|
||||
/* not usb. ignore */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check that this is an actual usb device */
|
||||
tmp = netlink_message_parse(buffer, len, "DEVTYPE");
|
||||
if (!tmp || strcmp(tmp, "usb_device") != 0) {
|
||||
/* not usb. ignore */
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp = netlink_message_parse(buffer, len, "BUSNUM");
|
||||
if (tmp) {
|
||||
*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;
|
||||
}
|
||||
} else {
|
||||
/* no bus number. try "DEVICE" */
|
||||
tmp = netlink_message_parse(buffer, len, "DEVICE");
|
||||
if (!tmp) {
|
||||
/* not usb. ignore */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse a device path such as /dev/bus/usb/003/004 */
|
||||
slash = strrchr(tmp, '/');
|
||||
if (!slash)
|
||||
return -1;
|
||||
|
||||
*busnum = (uint8_t)(strtoul(slash - 3, NULL, 10) & 0xff);
|
||||
if (errno) {
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*devaddr = (uint8_t)(strtoul(slash + 1, NULL, 10) & 0xff);
|
||||
if (errno) {
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = netlink_message_parse(buffer, len, "DEVPATH");
|
||||
if (!tmp)
|
||||
return -1;
|
||||
|
||||
slash = strrchr(tmp, '/');
|
||||
if (slash)
|
||||
*sys_name = slash + 1;
|
||||
|
||||
/* found a usb device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linux_netlink_read_message(void)
|
||||
{
|
||||
char cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
|
||||
char msg_buffer[2048];
|
||||
const char *sys_name = NULL;
|
||||
uint8_t busnum, devaddr;
|
||||
int detached, r;
|
||||
ssize_t len;
|
||||
struct cmsghdr *cmsg;
|
||||
struct ucred *cred;
|
||||
struct sockaddr_nl sa_nl;
|
||||
struct iovec iov = { .iov_base = msg_buffer, .iov_len = sizeof(msg_buffer) };
|
||||
struct msghdr msg = {
|
||||
.msg_iov = &iov, .msg_iovlen = 1,
|
||||
.msg_control = cred_buffer, .msg_controllen = sizeof(cred_buffer),
|
||||
.msg_name = &sa_nl, .msg_namelen = sizeof(sa_nl)
|
||||
};
|
||||
|
||||
/* read netlink message */
|
||||
len = recvmsg(linux_netlink_socket, &msg, 0);
|
||||
if (len == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
usbi_err(NULL, "error receiving message from netlink (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < 32 || (msg.msg_flags & MSG_TRUNC)) {
|
||||
usbi_err(NULL, "invalid netlink message length");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sa_nl.nl_groups != NL_GROUP_KERNEL || sa_nl.nl_pid != 0) {
|
||||
usbi_dbg("ignoring netlink message from unknown group/PID (%u/%u)",
|
||||
(unsigned int)sa_nl.nl_groups, (unsigned int)sa_nl.nl_pid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) {
|
||||
usbi_dbg("ignoring netlink message with no sender credentials");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cred = (struct ucred *)CMSG_DATA(cmsg);
|
||||
if (cred->uid != 0) {
|
||||
usbi_dbg("ignoring netlink message with non-zero sender UID %u", (unsigned int)cred->uid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = linux_netlink_parse(msg_buffer, (size_t)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_device_disconnected(busnum, devaddr);
|
||||
else
|
||||
linux_hotplug_enumerate(busnum, devaddr, sys_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *linux_netlink_event_thread_main(void *arg)
|
||||
{
|
||||
char dummy;
|
||||
int r;
|
||||
ssize_t nb;
|
||||
struct pollfd fds[] = {
|
||||
{ .fd = netlink_control_pipe[0],
|
||||
.events = POLLIN },
|
||||
{ .fd = linux_netlink_socket,
|
||||
.events = POLLIN },
|
||||
};
|
||||
|
||||
UNUSED(arg);
|
||||
|
||||
usbi_dbg("netlink event thread entering");
|
||||
|
||||
while ((r = poll(fds, 2, -1)) >= 0 || errno == EINTR) {
|
||||
if (r < 0) {
|
||||
/* temporary failure */
|
||||
continue;
|
||||
}
|
||||
if (fds[0].revents & POLLIN) {
|
||||
/* activity on control pipe, read the byte and exit */
|
||||
nb = read(netlink_control_pipe[0], &dummy, sizeof(dummy));
|
||||
if (nb <= 0)
|
||||
usbi_warn(NULL, "netlink control pipe read failed");
|
||||
break;
|
||||
}
|
||||
if (fds[1].revents & POLLIN) {
|
||||
usbi_mutex_static_lock(&linux_hotplug_lock);
|
||||
linux_netlink_read_message();
|
||||
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
||||
}
|
||||
}
|
||||
|
||||
usbi_dbg("netlink event thread exiting");
|
||||
|
||||
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);
|
||||
}
|
||||
329
externals/libusb/libusb/libusb/os/linux_udev.c
vendored
Executable file
329
externals/libusb/libusb/libusb/os/linux_udev.c
vendored
Executable file
@@ -0,0 +1,329 @@
|
||||
/* -*- 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 "libusbi.h"
|
||||
#include "linux_usbfs.h"
|
||||
|
||||
/* udev context */
|
||||
static struct udev *udev_ctx = NULL;
|
||||
static int udev_monitor_fd = -1;
|
||||
static int udev_control_pipe[2] = {-1, -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");
|
||||
goto err;
|
||||
}
|
||||
|
||||
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", "usb_device");
|
||||
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);
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
/* Make sure the udev file descriptor is marked as CLOEXEC */
|
||||
r = fcntl(udev_monitor_fd, F_GETFD);
|
||||
if (r == -1) {
|
||||
usbi_err(NULL, "geting udev monitor fd flags (%d)", errno);
|
||||
goto err_free_monitor;
|
||||
}
|
||||
if (!(r & FD_CLOEXEC)) {
|
||||
if (fcntl(udev_monitor_fd, F_SETFD, r | FD_CLOEXEC) == -1) {
|
||||
usbi_err(NULL, "setting udev monitor fd flags (%d)", errno);
|
||||
goto err_free_monitor;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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 status flags (%d)", errno);
|
||||
goto err_free_monitor;
|
||||
}
|
||||
if (!(r & O_NONBLOCK)) {
|
||||
if (fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK) == -1) {
|
||||
usbi_err(NULL, "setting udev monitor fd status flags (%d)", errno);
|
||||
goto err_free_monitor;
|
||||
}
|
||||
}
|
||||
|
||||
r = usbi_pipe(udev_control_pipe);
|
||||
if (r) {
|
||||
usbi_err(NULL, "could not create udev control pipe");
|
||||
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_close_pipe;
|
||||
}
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
|
||||
err_close_pipe:
|
||||
close(udev_control_pipe[0]);
|
||||
close(udev_control_pipe[1]);
|
||||
err_free_monitor:
|
||||
udev_monitor_unref(udev_monitor);
|
||||
udev_monitor = NULL;
|
||||
udev_monitor_fd = -1;
|
||||
err_free_ctx:
|
||||
udev_unref(udev_ctx);
|
||||
err:
|
||||
udev_ctx = NULL;
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
|
||||
int linux_udev_stop_event_monitor(void)
|
||||
{
|
||||
char dummy = 1;
|
||||
int r;
|
||||
|
||||
assert(udev_ctx != NULL);
|
||||
assert(udev_monitor != NULL);
|
||||
assert(udev_monitor_fd != -1);
|
||||
|
||||
/* Write some dummy data to the control pipe and
|
||||
* wait for the thread to exit */
|
||||
r = write(udev_control_pipe[1], &dummy, sizeof(dummy));
|
||||
if (r <= 0) {
|
||||
usbi_warn(NULL, "udev control pipe signal failed");
|
||||
}
|
||||
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;
|
||||
|
||||
/* close and reset control pipe */
|
||||
close(udev_control_pipe[0]);
|
||||
close(udev_control_pipe[1]);
|
||||
udev_control_pipe[0] = -1;
|
||||
udev_control_pipe[1] = -1;
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static void *linux_udev_event_thread_main(void *arg)
|
||||
{
|
||||
char dummy;
|
||||
int r;
|
||||
ssize_t nb;
|
||||
struct udev_device* udev_dev;
|
||||
struct pollfd fds[] = {
|
||||
{.fd = udev_control_pipe[0],
|
||||
.events = POLLIN},
|
||||
{.fd = udev_monitor_fd,
|
||||
.events = POLLIN},
|
||||
};
|
||||
|
||||
usbi_dbg("udev event thread entering.");
|
||||
|
||||
while ((r = poll(fds, 2, -1)) >= 0 || errno == EINTR) {
|
||||
if (r < 0) {
|
||||
/* temporary failure */
|
||||
continue;
|
||||
}
|
||||
if (fds[0].revents & POLLIN) {
|
||||
/* activity on control pipe, read the byte and exit */
|
||||
nb = read(udev_control_pipe[0], &dummy, sizeof(dummy));
|
||||
if (nb <= 0) {
|
||||
usbi_warn(NULL, "udev control pipe read failed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fds[1].revents & POLLIN) {
|
||||
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, -1);
|
||||
}
|
||||
|
||||
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_device_disconnected(busnum, devaddr);
|
||||
} 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_add_match_property(enumerator, "DEVTYPE", "usb_device");
|
||||
udev_enumerate_scan_devices(enumerator);
|
||||
devices = udev_enumerate_get_list_entry(enumerator);
|
||||
|
||||
entry = NULL;
|
||||
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);
|
||||
}
|
||||
2896
externals/libusb/libusb/libusb/os/linux_usbfs.c
vendored
Executable file
2896
externals/libusb/libusb/libusb/os/linux_usbfs.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
194
externals/libusb/libusb/libusb/os/linux_usbfs.h
vendored
Executable file
194
externals/libusb/libusb/libusb/os/linux_usbfs.h
vendored
Executable file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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_BULK_BUFFER_LENGTH 16384
|
||||
#define MAX_CTRL_BUFFER_LENGTH 4096
|
||||
|
||||
#define MAX_ISO_PACKETS_PER_URB 128
|
||||
|
||||
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;
|
||||
union {
|
||||
int number_of_packets; /* Only used for isoc urbs */
|
||||
unsigned int stream_id; /* Only used with bulk streams */
|
||||
};
|
||||
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_CAP_REAP_AFTER_DISCONNECT 0x10
|
||||
|
||||
#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];
|
||||
};
|
||||
|
||||
struct usbfs_streams {
|
||||
unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */
|
||||
unsigned int num_eps;
|
||||
unsigned char eps[0];
|
||||
};
|
||||
|
||||
#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)
|
||||
#define IOCTL_USBFS_ALLOC_STREAMS _IOR('U', 28, struct usbfs_streams)
|
||||
#define IOCTL_USBFS_FREE_STREAMS _IOR('U', 29, struct usbfs_streams)
|
||||
|
||||
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_device_disconnected(uint8_t busnum, uint8_t devaddr);
|
||||
|
||||
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 fd);
|
||||
int linux_enumerate_device(struct libusb_context *ctx,
|
||||
uint8_t busnum, uint8_t devaddr, const char *sysfs_dir);
|
||||
|
||||
#endif
|
||||
682
externals/libusb/libusb/libusb/os/netbsd_usb.c
vendored
Executable file
682
externals/libusb/libusb/libusb/os/netbsd_usb.c
vendored
Executable file
@@ -0,0 +1,682 @@
|
||||
/*
|
||||
* 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 <config.h>
|
||||
|
||||
#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 "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 endpoints[USB_MAX_ENDPOINTS];
|
||||
};
|
||||
|
||||
/*
|
||||
* Backend functions
|
||||
*/
|
||||
static int netbsd_get_device_list(struct libusb_context *,
|
||||
struct discovered_devs **);
|
||||
static int netbsd_open(struct libusb_device_handle *);
|
||||
static void netbsd_close(struct libusb_device_handle *);
|
||||
|
||||
static int netbsd_get_device_descriptor(struct libusb_device *, unsigned char *,
|
||||
int *);
|
||||
static int netbsd_get_active_config_descriptor(struct libusb_device *,
|
||||
unsigned char *, size_t, int *);
|
||||
static int netbsd_get_config_descriptor(struct libusb_device *, uint8_t,
|
||||
unsigned char *, size_t, int *);
|
||||
|
||||
static int netbsd_get_configuration(struct libusb_device_handle *, int *);
|
||||
static int netbsd_set_configuration(struct libusb_device_handle *, int);
|
||||
|
||||
static int netbsd_claim_interface(struct libusb_device_handle *, int);
|
||||
static int netbsd_release_interface(struct libusb_device_handle *, int);
|
||||
|
||||
static int netbsd_set_interface_altsetting(struct libusb_device_handle *, int,
|
||||
int);
|
||||
static int netbsd_clear_halt(struct libusb_device_handle *, unsigned char);
|
||||
static int netbsd_reset_device(struct libusb_device_handle *);
|
||||
static void netbsd_destroy_device(struct libusb_device *);
|
||||
|
||||
static int netbsd_submit_transfer(struct usbi_transfer *);
|
||||
static int netbsd_cancel_transfer(struct usbi_transfer *);
|
||||
static void netbsd_clear_transfer_priv(struct usbi_transfer *);
|
||||
static int netbsd_handle_transfer_completion(struct usbi_transfer *);
|
||||
static int netbsd_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 usbi_backend = {
|
||||
"Synchronous NetBSD backend",
|
||||
0,
|
||||
NULL, /* init() */
|
||||
NULL, /* exit() */
|
||||
NULL, /* set_option() */
|
||||
netbsd_get_device_list,
|
||||
NULL, /* hotplug_poll */
|
||||
netbsd_open,
|
||||
netbsd_close,
|
||||
|
||||
netbsd_get_device_descriptor,
|
||||
netbsd_get_active_config_descriptor,
|
||||
netbsd_get_config_descriptor,
|
||||
NULL, /* get_config_descriptor_by_value() */
|
||||
|
||||
netbsd_get_configuration,
|
||||
netbsd_set_configuration,
|
||||
|
||||
netbsd_claim_interface,
|
||||
netbsd_release_interface,
|
||||
|
||||
netbsd_set_interface_altsetting,
|
||||
netbsd_clear_halt,
|
||||
netbsd_reset_device,
|
||||
|
||||
NULL, /* alloc_streams */
|
||||
NULL, /* free_streams */
|
||||
|
||||
NULL, /* dev_mem_alloc() */
|
||||
NULL, /* dev_mem_free() */
|
||||
|
||||
NULL, /* kernel_driver_active() */
|
||||
NULL, /* detach_kernel_driver() */
|
||||
NULL, /* attach_kernel_driver() */
|
||||
|
||||
netbsd_destroy_device,
|
||||
|
||||
netbsd_submit_transfer,
|
||||
netbsd_cancel_transfer,
|
||||
netbsd_clear_transfer_priv,
|
||||
|
||||
NULL, /* handle_events() */
|
||||
netbsd_handle_transfer_completion,
|
||||
|
||||
netbsd_clock_gettime,
|
||||
0, /* context_priv_size */
|
||||
sizeof(struct device_priv),
|
||||
sizeof(struct handle_priv),
|
||||
0, /* transfer_priv_size */
|
||||
};
|
||||
|
||||
int
|
||||
netbsd_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 == NULL) {
|
||||
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
|
||||
netbsd_open(struct libusb_device_handle *handle)
|
||||
{
|
||||
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
|
||||
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
|
||||
int i;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
|
||||
hpriv->endpoints[i] = -1;
|
||||
|
||||
usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
|
||||
|
||||
return (LIBUSB_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
netbsd_close(struct libusb_device_handle *handle)
|
||||
{
|
||||
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
|
||||
|
||||
usbi_dbg("close: fd %d", dpriv->fd);
|
||||
|
||||
close(dpriv->fd);
|
||||
dpriv->fd = -1;
|
||||
}
|
||||
|
||||
int
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_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
|
||||
netbsd_reset_device(struct libusb_device_handle *handle)
|
||||
{
|
||||
usbi_dbg("");
|
||||
|
||||
return (LIBUSB_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
void
|
||||
netbsd_destroy_device(struct libusb_device *dev)
|
||||
{
|
||||
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
|
||||
|
||||
usbi_dbg("");
|
||||
|
||||
free(dpriv->cdesc);
|
||||
}
|
||||
|
||||
int
|
||||
netbsd_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;
|
||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||
err = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
usbi_signal_transfer_completion(itransfer);
|
||||
|
||||
return (LIBUSB_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
netbsd_cancel_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
usbi_dbg("");
|
||||
|
||||
return (LIBUSB_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
void
|
||||
netbsd_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||
{
|
||||
usbi_dbg("");
|
||||
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
int
|
||||
netbsd_handle_transfer_completion(struct usbi_transfer *itransfer)
|
||||
{
|
||||
return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
|
||||
}
|
||||
|
||||
int
|
||||
netbsd_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, libusb 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);
|
||||
}
|
||||
749
externals/libusb/libusb/libusb/os/openbsd_usb.c
vendored
Executable file
749
externals/libusb/libusb/libusb/os/openbsd_usb.c
vendored
Executable file
@@ -0,0 +1,749 @@
|
||||
/*
|
||||
* Copyright © 2011-2013 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 <config.h>
|
||||
|
||||
#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 "libusbi.h"
|
||||
|
||||
struct device_priv {
|
||||
char *devname; /* name of the ugen(4) node */
|
||||
int fd; /* device file descriptor */
|
||||
|
||||
unsigned char *cdesc; /* active config descriptor */
|
||||
usb_device_descriptor_t ddesc; /* usb device descriptor */
|
||||
};
|
||||
|
||||
struct handle_priv {
|
||||
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_transfer_completion(struct usbi_transfer *);
|
||||
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 *);
|
||||
static int _sync_control_transfer(struct usbi_transfer *);
|
||||
static int _sync_gen_transfer(struct usbi_transfer *);
|
||||
static int _access_endpoint(struct libusb_transfer *);
|
||||
|
||||
static int _bus_open(int);
|
||||
|
||||
|
||||
const struct usbi_os_backend usbi_backend = {
|
||||
.name = "Synchronous OpenBSD backend",
|
||||
.get_device_list = obsd_get_device_list,
|
||||
.open = obsd_open,
|
||||
.close = obsd_close,
|
||||
|
||||
.get_device_descriptor = obsd_get_device_descriptor,
|
||||
.get_active_config_descriptor = obsd_get_active_config_descriptor,
|
||||
.get_config_descriptor = obsd_get_config_descriptor,
|
||||
|
||||
.get_configuration = obsd_get_configuration,
|
||||
.set_configuration = obsd_set_configuration,
|
||||
|
||||
.claim_interface = obsd_claim_interface,
|
||||
.release_interface = obsd_release_interface,
|
||||
|
||||
.set_interface_altsetting = obsd_set_interface_altsetting,
|
||||
.clear_halt = obsd_clear_halt,
|
||||
.reset_device = obsd_reset_device,
|
||||
.destroy_device = obsd_destroy_device,
|
||||
|
||||
.submit_transfer = obsd_submit_transfer,
|
||||
.cancel_transfer = obsd_cancel_transfer,
|
||||
.clear_transfer_priv = obsd_clear_transfer_priv,
|
||||
|
||||
.handle_transfer_completion = obsd_handle_transfer_completion,
|
||||
|
||||
.clock_gettime = obsd_clock_gettime,
|
||||
.device_priv_size = sizeof(struct device_priv),
|
||||
.device_handle_priv_size = sizeof(struct handle_priv),
|
||||
};
|
||||
|
||||
#define DEVPATH "/dev/"
|
||||
#define USBDEV DEVPATH "usb"
|
||||
|
||||
int
|
||||
obsd_get_device_list(struct libusb_context * ctx,
|
||||
struct discovered_devs **discdevs)
|
||||
{
|
||||
struct discovered_devs *ddd;
|
||||
struct libusb_device *dev;
|
||||
struct device_priv *dpriv;
|
||||
struct usb_device_info di;
|
||||
struct usb_device_ddesc dd;
|
||||
unsigned long session_id;
|
||||
char devices[USB_MAX_DEVICES];
|
||||
char busnode[16];
|
||||
char *udevname;
|
||||
int fd, addr, i, j;
|
||||
|
||||
usbi_dbg("");
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
snprintf(busnode, sizeof(busnode), USBDEV "%d", i);
|
||||
|
||||
if ((fd = open(busnode, O_RDWR)) < 0) {
|
||||
if (errno != ENOENT && errno != ENXIO)
|
||||
usbi_err(ctx, "could not open %s", busnode);
|
||||
continue;
|
||||
}
|
||||
|
||||
bzero(devices, sizeof(devices));
|
||||
for (addr = 1; addr < USB_MAX_DEVICES; addr++) {
|
||||
if (devices[addr])
|
||||
continue;
|
||||
|
||||
di.udi_addr = addr;
|
||||
if (ioctl(fd, USB_DEVICEINFO, &di) < 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* XXX If ugen(4) is attached to the USB device
|
||||
* it will be used.
|
||||
*/
|
||||
udevname = NULL;
|
||||
for (j = 0; j < USB_MAX_DEVNAMES; j++)
|
||||
if (!strncmp("ugen", di.udi_devnames[j], 4)) {
|
||||
udevname = strdup(di.udi_devnames[j]);
|
||||
break;
|
||||
}
|
||||
|
||||
session_id = (di.udi_bus << 8 | di.udi_addr);
|
||||
dev = usbi_get_device_by_session_id(ctx, session_id);
|
||||
|
||||
if (dev == NULL) {
|
||||
dev = usbi_alloc_device(ctx, session_id);
|
||||
if (dev == NULL) {
|
||||
close(fd);
|
||||
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;
|
||||
dpriv->fd = -1;
|
||||
dpriv->cdesc = NULL;
|
||||
dpriv->devname = udevname;
|
||||
|
||||
dd.udd_bus = di.udi_bus;
|
||||
dd.udd_addr = di.udi_addr;
|
||||
if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) {
|
||||
libusb_unref_device(dev);
|
||||
continue;
|
||||
}
|
||||
dpriv->ddesc = dd.udd_desc;
|
||||
|
||||
if (_cache_active_config_descriptor(dev)) {
|
||||
libusb_unref_device(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (usbi_sanitize_device(dev)) {
|
||||
libusb_unref_device(dev);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ddd = discovered_devs_append(*discdevs, dev);
|
||||
if (ddd == NULL) {
|
||||
close(fd);
|
||||
return (LIBUSB_ERROR_NO_MEM);
|
||||
}
|
||||
libusb_unref_device(dev);
|
||||
|
||||
*discdevs = ddd;
|
||||
devices[addr] = 1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return (LIBUSB_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
obsd_open(struct libusb_device_handle *handle)
|
||||
{
|
||||
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
|
||||
char devnode[16];
|
||||
|
||||
if (dpriv->devname) {
|
||||
/*
|
||||
* Only open ugen(4) attached devices read-write, all
|
||||
* read-only operations are done through the bus node.
|
||||
*/
|
||||
snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
|
||||
dpriv->devname);
|
||||
dpriv->fd = open(devnode, O_RDWR);
|
||||
if (dpriv->fd < 0)
|
||||
return _errno_to_libusb(errno);
|
||||
|
||||
usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
|
||||
}
|
||||
|
||||
return (LIBUSB_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
obsd_close(struct libusb_device_handle *handle)
|
||||
{
|
||||
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
|
||||
|
||||
if (dpriv->devname) {
|
||||
usbi_dbg("close: fd %d", dpriv->fd);
|
||||
|
||||
close(dpriv->fd);
|
||||
dpriv->fd = -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 = (usb_config_descriptor_t *)dpriv->cdesc;
|
||||
|
||||
len = MIN(len, UGETW(ucd->wTotalLength));
|
||||
|
||||
usbi_dbg("len %zu", 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 usb_device_fdesc udf;
|
||||
int fd, err;
|
||||
|
||||
if ((fd = _bus_open(dev->bus_number)) < 0)
|
||||
return _errno_to_libusb(errno);
|
||||
|
||||
udf.udf_bus = dev->bus_number;
|
||||
udf.udf_addr = dev->device_address;
|
||||
udf.udf_config_index = idx;
|
||||
udf.udf_size = len;
|
||||
udf.udf_data = buf;
|
||||
|
||||
usbi_dbg("index %d, len %zu", udf.udf_config_index, len);
|
||||
|
||||
if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
return _errno_to_libusb(err);
|
||||
}
|
||||
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;
|
||||
usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
|
||||
|
||||
*config = ucd->bConfigurationValue;
|
||||
|
||||
usbi_dbg("bConfigurationValue %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;
|
||||
|
||||
if (dpriv->devname == NULL)
|
||||
return (LIBUSB_ERROR_NOT_SUPPORTED);
|
||||
|
||||
usbi_dbg("bConfigurationValue %d", config);
|
||||
|
||||
if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
|
||||
return _errno_to_libusb(errno);
|
||||
|
||||
return _cache_active_config_descriptor(handle->dev);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (dpriv->devname == NULL)
|
||||
return (LIBUSB_ERROR_NOT_SUPPORTED);
|
||||
|
||||
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 usb_ctl_request req;
|
||||
int fd, err;
|
||||
|
||||
if ((fd = _bus_open(handle->dev->bus_number)) < 0)
|
||||
return _errno_to_libusb(errno);
|
||||
|
||||
usbi_dbg("");
|
||||
|
||||
req.ucr_addr = handle->dev->device_address;
|
||||
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(fd, USB_REQUEST, &req) < 0) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
return _errno_to_libusb(err);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
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);
|
||||
free(dpriv->devname);
|
||||
}
|
||||
|
||||
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;
|
||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||
err = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
usbi_signal_transfer_completion(itransfer);
|
||||
|
||||
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_transfer_completion(struct usbi_transfer *itransfer)
|
||||
{
|
||||
return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
|
||||
}
|
||||
|
||||
int
|
||||
obsd_clock_gettime(int clkid, struct timespec *tp)
|
||||
{
|
||||
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)
|
||||
{
|
||||
usbi_dbg("error: %s (%d)", strerror(err), 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);
|
||||
case ETIMEDOUT:
|
||||
return (LIBUSB_ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
return (LIBUSB_ERROR_OTHER);
|
||||
}
|
||||
|
||||
int
|
||||
_cache_active_config_descriptor(struct libusb_device *dev)
|
||||
{
|
||||
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
|
||||
struct usb_device_cdesc udc;
|
||||
struct usb_device_fdesc udf;
|
||||
unsigned char* buf;
|
||||
int fd, len, err;
|
||||
|
||||
if ((fd = _bus_open(dev->bus_number)) < 0)
|
||||
return _errno_to_libusb(errno);
|
||||
|
||||
usbi_dbg("fd %d, addr %d", fd, dev->device_address);
|
||||
|
||||
udc.udc_bus = dev->bus_number;
|
||||
udc.udc_addr = dev->device_address;
|
||||
udc.udc_config_index = USB_CURRENT_CONFIG_INDEX;
|
||||
if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
return _errno_to_libusb(errno);
|
||||
}
|
||||
|
||||
usbi_dbg("active bLength %d", udc.udc_desc.bLength);
|
||||
|
||||
len = UGETW(udc.udc_desc.wTotalLength);
|
||||
buf = malloc(len);
|
||||
if (buf == NULL)
|
||||
return (LIBUSB_ERROR_NO_MEM);
|
||||
|
||||
udf.udf_bus = dev->bus_number;
|
||||
udf.udf_addr = dev->device_address;
|
||||
udf.udf_config_index = udc.udc_config_index;
|
||||
udf.udf_size = len;
|
||||
udf.udf_data = buf;
|
||||
|
||||
usbi_dbg("index %d, len %d", udf.udf_config_index, len);
|
||||
|
||||
if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
free(buf);
|
||||
return _errno_to_libusb(err);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (dpriv->cdesc)
|
||||
free(dpriv->cdesc);
|
||||
dpriv->cdesc = buf;
|
||||
|
||||
return (LIBUSB_SUCCESS);
|
||||
}
|
||||
|
||||
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 %x request %x value %x 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_addr = transfer->dev_handle->dev->device_address;
|
||||
req.ucr_request.bmRequestType = setup->bmRequestType;
|
||||
req.ucr_request.bRequest = setup->bRequest;
|
||||
/* Don't use USETW, libusb 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 (dpriv->devname == NULL) {
|
||||
/*
|
||||
* XXX If the device is not attached to ugen(4) it is
|
||||
* XXX still possible to submit a control transfer but
|
||||
* XXX with the default timeout only.
|
||||
*/
|
||||
int fd, err;
|
||||
|
||||
if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0)
|
||||
return _errno_to_libusb(errno);
|
||||
|
||||
if ((ioctl(fd, USB_REQUEST, &req)) < 0) {
|
||||
err = errno;
|
||||
close(fd);
|
||||
return _errno_to_libusb(err);
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
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 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 endpoint node */
|
||||
snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d",
|
||||
dpriv->devname, 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;
|
||||
struct device_priv *dpriv;
|
||||
int fd, nr = 1;
|
||||
|
||||
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
|
||||
|
||||
if (dpriv->devname == NULL)
|
||||
return (LIBUSB_ERROR_NOT_SUPPORTED);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
int
|
||||
_bus_open(int number)
|
||||
{
|
||||
char busnode[16];
|
||||
|
||||
snprintf(busnode, sizeof(busnode), USBDEV "%d", number);
|
||||
|
||||
return open(busnode, O_RDWR);
|
||||
}
|
||||
84
externals/libusb/libusb/libusb/os/poll_posix.c
vendored
Executable file
84
externals/libusb/libusb/libusb/os/poll_posix.c
vendored
Executable file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
|
||||
int usbi_pipe(int pipefd[2])
|
||||
{
|
||||
#if defined(HAVE_PIPE2)
|
||||
int ret = pipe2(pipefd, O_CLOEXEC);
|
||||
#else
|
||||
int ret = pipe(pipefd);
|
||||
#endif
|
||||
|
||||
if (ret != 0) {
|
||||
usbi_err(NULL, "failed to create pipe (%d)", errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_PIPE2) && defined(FD_CLOEXEC)
|
||||
ret = fcntl(pipefd[0], F_GETFD);
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to get pipe fd flags (%d)", errno);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
ret = fcntl(pipefd[0], F_SETFD, ret | FD_CLOEXEC);
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to set pipe fd flags (%d)", errno);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
|
||||
ret = fcntl(pipefd[1], F_GETFD);
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to get pipe fd flags (%d)", errno);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
ret = fcntl(pipefd[1], F_SETFD, ret | FD_CLOEXEC);
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to set pipe fd flags (%d)", errno);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = fcntl(pipefd[1], F_GETFL);
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to get pipe fd status flags (%d)", errno);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK);
|
||||
if (ret == -1) {
|
||||
usbi_err(NULL, "failed to set pipe fd status flags (%d)", errno);
|
||||
goto err_close_pipe;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_close_pipe:
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
return ret;
|
||||
}
|
||||
14
externals/libusb/libusb/libusb/os/poll_posix.h
vendored
Executable file
14
externals/libusb/libusb/libusb/os/poll_posix.h
vendored
Executable file
@@ -0,0 +1,14 @@
|
||||
#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]);
|
||||
|
||||
#define usbi_inc_fds_ref(x, y)
|
||||
#define usbi_dec_fds_ref(x, y)
|
||||
|
||||
#endif /* LIBUSB_POLL_POSIX_H */
|
||||
447
externals/libusb/libusb/libusb/os/poll_windows.c
vendored
Executable file
447
externals/libusb/libusb/libusb/os/poll_windows.c
vendored
Executable file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* poll_windows: poll compatibility wrapper for Windows
|
||||
* Copyright © 2017 Chris Dickens <christopher.a.dickens@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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* poll() and pipe() Windows compatibility layer for libusb 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.
|
||||
* - 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 <config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
#include "windows_common.h"
|
||||
|
||||
// public fd data
|
||||
const struct winfd INVALID_WINFD = { -1, NULL };
|
||||
|
||||
// private data
|
||||
struct file_descriptor {
|
||||
enum fd_type { FD_TYPE_PIPE, FD_TYPE_TRANSFER } type;
|
||||
OVERLAPPED overlapped;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
static usbi_mutex_static_t fd_table_lock = USBI_MUTEX_INITIALIZER;
|
||||
|
||||
static struct file_descriptor **fd_table;
|
||||
static size_t fd_count;
|
||||
static size_t fd_size;
|
||||
#define INC_FDS_EACH 256
|
||||
|
||||
static void usbi_dec_fd_table()
|
||||
{
|
||||
fd_count--;
|
||||
if (fd_count == 0) {
|
||||
free(fd_table);
|
||||
fd_size = 0;
|
||||
fd_table = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void smart_realloc_fd_table_space(int inc)
|
||||
{
|
||||
if (fd_table == NULL || fd_count + inc > fd_size) {
|
||||
struct file_descriptor **p = (struct file_descriptor **)realloc(fd_table, (fd_size + INC_FDS_EACH) * sizeof(struct file_descriptor *));
|
||||
if (p != NULL) {
|
||||
memset(p + fd_size, 0, INC_FDS_EACH * sizeof(struct file_descriptor *));
|
||||
fd_size += INC_FDS_EACH;
|
||||
fd_table = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct file_descriptor *create_fd(enum fd_type type)
|
||||
{
|
||||
struct file_descriptor *fd = calloc(1, sizeof(*fd));
|
||||
if (fd == NULL)
|
||||
return NULL;
|
||||
fd->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (fd->overlapped.hEvent == NULL) {
|
||||
free(fd);
|
||||
return NULL;
|
||||
}
|
||||
fd->type = type;
|
||||
fd->refcount = 1;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void free_fd(struct file_descriptor *fd)
|
||||
{
|
||||
CloseHandle(fd->overlapped.hEvent);
|
||||
free(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create both an fd and an OVERLAPPED, 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.
|
||||
* 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(void)
|
||||
{
|
||||
struct file_descriptor *fd;
|
||||
struct winfd wfd;
|
||||
|
||||
fd = create_fd(FD_TYPE_TRANSFER);
|
||||
if (fd == NULL)
|
||||
return INVALID_WINFD;
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
|
||||
smart_realloc_fd_table_space(1);
|
||||
|
||||
for (wfd.fd = 0; wfd.fd < fd_size; wfd.fd++) {
|
||||
if (fd_table[wfd.fd] != NULL)
|
||||
continue;
|
||||
fd_table[wfd.fd] = fd;
|
||||
fd_count++;
|
||||
break;
|
||||
}
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
|
||||
if (wfd.fd == fd_size) {
|
||||
free_fd(fd);
|
||||
return INVALID_WINFD;
|
||||
}
|
||||
|
||||
wfd.overlapped = &fd->overlapped;
|
||||
|
||||
return wfd;
|
||||
}
|
||||
|
||||
void usbi_inc_fds_ref(struct pollfd *fds, unsigned int nfds)
|
||||
{
|
||||
int n;
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
fd_table[fds[n].fd]->refcount++;
|
||||
}
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
}
|
||||
|
||||
void usbi_dec_fds_ref(struct pollfd *fds, unsigned int nfds)
|
||||
{
|
||||
int n;
|
||||
struct file_descriptor *fd;
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
fd = fd_table[fds[n].fd];
|
||||
fd->refcount--;
|
||||
//FD_TYPE_PIPE map fd to two _fd
|
||||
if (fd->refcount == 0 || (fd->refcount == 1 && fd->type == FD_TYPE_PIPE))
|
||||
{
|
||||
if (fd->type == FD_TYPE_PIPE) {
|
||||
// InternalHigh is our reference count
|
||||
fd->overlapped.InternalHigh--;
|
||||
if (fd->overlapped.InternalHigh == 0)
|
||||
free_fd(fd);
|
||||
}
|
||||
else {
|
||||
free_fd(fd);
|
||||
}
|
||||
fd_table[fds[n].fd] = NULL;
|
||||
usbi_dec_fd_table();
|
||||
}
|
||||
}
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
}
|
||||
|
||||
|
||||
static int check_pollfds(struct pollfd *fds, unsigned int nfds,
|
||||
HANDLE *wait_handles, DWORD *nb_wait_handles)
|
||||
{
|
||||
struct file_descriptor *fd;
|
||||
unsigned int n;
|
||||
int nready = 0;
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
fds[n].revents = 0;
|
||||
|
||||
// Keep it simple - only allow either POLLIN *or* POLLOUT
|
||||
assert((fds[n].events == POLLIN) || (fds[n].events == POLLOUT));
|
||||
if ((fds[n].events != POLLIN) && (fds[n].events != POLLOUT)) {
|
||||
fds[n].revents = POLLNVAL;
|
||||
nready++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((fds[n].fd >= 0) && (fds[n].fd < fd_size))
|
||||
fd = fd_table[fds[n].fd];
|
||||
else
|
||||
fd = NULL;
|
||||
|
||||
assert(fd != NULL);
|
||||
if (fd == NULL) {
|
||||
fds[n].revents = POLLNVAL;
|
||||
nready++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HasOverlappedIoCompleted(&fd->overlapped)
|
||||
&& (WaitForSingleObject(fd->overlapped.hEvent, 0) == WAIT_OBJECT_0)) {
|
||||
fds[n].revents = fds[n].events;
|
||||
nready++;
|
||||
} else if (wait_handles != NULL) {
|
||||
if (*nb_wait_handles == MAXIMUM_WAIT_OBJECTS) {
|
||||
usbi_warn(NULL, "too many HANDLEs to wait on");
|
||||
continue;
|
||||
}
|
||||
wait_handles[*nb_wait_handles] = fd->overlapped.hEvent;
|
||||
(*nb_wait_handles)++;
|
||||
}
|
||||
}
|
||||
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
|
||||
return nready;
|
||||
}
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
HANDLE wait_handles[MAXIMUM_WAIT_OBJECTS];
|
||||
DWORD nb_wait_handles = 0;
|
||||
DWORD ret;
|
||||
int nready;
|
||||
|
||||
nready = check_pollfds(fds, nfds, wait_handles, &nb_wait_handles);
|
||||
|
||||
// If nothing was triggered, wait on all fds that require it
|
||||
if ((nready == 0) && (nb_wait_handles != 0) && (timeout != 0)) {
|
||||
ret = WaitForMultipleObjects(nb_wait_handles, wait_handles,
|
||||
FALSE, (timeout < 0) ? INFINITE : (DWORD)timeout);
|
||||
if (ret < (WAIT_OBJECT_0 + nb_wait_handles)) {
|
||||
nready = check_pollfds(fds, nfds, NULL, NULL);
|
||||
} else if (ret != WAIT_TIMEOUT) {
|
||||
if (ret == WAIT_FAILED)
|
||||
usbi_err(NULL, "WaitForMultipleObjects failed: %u", (unsigned int)GetLastError());
|
||||
nready = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return nready;
|
||||
}
|
||||
|
||||
/*
|
||||
* close a fake file descriptor
|
||||
*/
|
||||
int usbi_close(int _fd)
|
||||
{
|
||||
struct file_descriptor *fd;
|
||||
|
||||
if (_fd < 0 || _fd >= fd_size)
|
||||
goto err_badfd;
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
fd = fd_table[_fd];
|
||||
fd->refcount--;
|
||||
//FD_TYPE_PIPE map fd to two _fd
|
||||
if(fd->refcount==0 || (fd->refcount == 1 && fd->type == FD_TYPE_PIPE))
|
||||
{ fd_table[_fd] = NULL;
|
||||
usbi_dec_fd_table();
|
||||
|
||||
if (fd->type == FD_TYPE_PIPE) {
|
||||
// InternalHigh is our reference count
|
||||
fd->overlapped.InternalHigh--;
|
||||
if (fd->overlapped.InternalHigh == 0)
|
||||
free_fd(fd);
|
||||
}
|
||||
else {
|
||||
free_fd(fd);
|
||||
}
|
||||
}
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
|
||||
if (fd == NULL)
|
||||
goto err_badfd;
|
||||
|
||||
return 0;
|
||||
|
||||
err_badfd:
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a fake pipe.
|
||||
* As libusb 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])
|
||||
{
|
||||
struct file_descriptor *fd;
|
||||
int r_fd = -1, w_fd = -1;
|
||||
int i;
|
||||
|
||||
fd = create_fd(FD_TYPE_PIPE);
|
||||
if (fd == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use InternalHigh as a reference count
|
||||
fd->overlapped.Internal = STATUS_PENDING;
|
||||
fd->overlapped.InternalHigh = 2;
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
do {
|
||||
smart_realloc_fd_table_space(2);
|
||||
|
||||
for (i = 0; i < fd_size; i++) {
|
||||
if (fd_table[i] != NULL)
|
||||
continue;
|
||||
if (r_fd == -1) {
|
||||
r_fd = i;
|
||||
} else if (w_fd == -1) {
|
||||
w_fd = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == fd_size)
|
||||
break;
|
||||
|
||||
fd_table[r_fd] = fd;
|
||||
fd_table[w_fd] = fd;
|
||||
|
||||
fd->refcount++; //this fd reference twice for r and w.
|
||||
|
||||
fd_count += 2;
|
||||
|
||||
} while (0);
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
|
||||
if (i == fd_size) {
|
||||
free_fd(fd);
|
||||
errno = EMFILE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
filedes[0] = r_fd;
|
||||
filedes[1] = w_fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* synchronous write for fake "pipe" signaling
|
||||
*/
|
||||
ssize_t usbi_write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
int error = EBADF;
|
||||
|
||||
UNUSED(buf);
|
||||
|
||||
if (fd < 0 || fd >= fd_size)
|
||||
goto err_out;
|
||||
|
||||
if (count != sizeof(unsigned char)) {
|
||||
usbi_err(NULL, "this function should only used for signaling");
|
||||
error = EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
if ((fd_table[fd] != NULL) && (fd_table[fd]->type == FD_TYPE_PIPE)) {
|
||||
assert(fd_table[fd]->overlapped.Internal == STATUS_PENDING);
|
||||
assert(fd_table[fd]->overlapped.InternalHigh == 2);
|
||||
fd_table[fd]->overlapped.Internal = STATUS_WAIT_0;
|
||||
SetEvent(fd_table[fd]->overlapped.hEvent);
|
||||
error = 0;
|
||||
}
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
|
||||
if (error)
|
||||
goto err_out;
|
||||
|
||||
return sizeof(unsigned char);
|
||||
|
||||
err_out:
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* synchronous read for fake "pipe" signaling
|
||||
*/
|
||||
ssize_t usbi_read(int fd, void *buf, size_t count)
|
||||
{
|
||||
int error = EBADF;
|
||||
|
||||
UNUSED(buf);
|
||||
|
||||
if (fd < 0 || fd >= fd_size)
|
||||
goto err_out;
|
||||
|
||||
if (count != sizeof(unsigned char)) {
|
||||
usbi_err(NULL, "this function should only used for signaling");
|
||||
error = EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
usbi_mutex_static_lock(&fd_table_lock);
|
||||
if ((fd_table[fd] != NULL) && (fd_table[fd]->type == FD_TYPE_PIPE)) {
|
||||
assert(fd_table[fd]->overlapped.Internal == STATUS_WAIT_0);
|
||||
assert(fd_table[fd]->overlapped.InternalHigh == 2);
|
||||
fd_table[fd]->overlapped.Internal = STATUS_PENDING;
|
||||
ResetEvent(fd_table[fd]->overlapped.hEvent);
|
||||
error = 0;
|
||||
}
|
||||
usbi_mutex_static_unlock(&fd_table_lock);
|
||||
|
||||
if (error)
|
||||
goto err_out;
|
||||
|
||||
return sizeof(unsigned char);
|
||||
|
||||
err_out:
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
98
externals/libusb/libusb/libusb/os/poll_windows.h
vendored
Executable file
98
externals/libusb/libusb/libusb/os/poll_windows.h
vendored
Executable file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Windows compat: POSIX compatibility wrapper
|
||||
* Copyright © 2012-2013 RealVNC Ltd.
|
||||
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2016-2018 Chris Dickens <christopher.a.dickens@gmail.com>
|
||||
* 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)
|
||||
|
||||
#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 */
|
||||
};
|
||||
|
||||
struct winfd {
|
||||
int fd; // what's exposed to libusb core
|
||||
OVERLAPPED *overlapped; // what will report our I/O status
|
||||
};
|
||||
|
||||
extern const struct winfd INVALID_WINFD;
|
||||
|
||||
struct winfd usbi_create_fd(void);
|
||||
|
||||
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 usbi_inc_fds_ref(struct pollfd *fds, unsigned int nfds);
|
||||
void usbi_dec_fds_ref(struct pollfd *fds, unsigned int nfds);
|
||||
|
||||
/*
|
||||
* 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
|
||||
1695
externals/libusb/libusb/libusb/os/sunos_usb.c
vendored
Executable file
1695
externals/libusb/libusb/libusb/os/sunos_usb.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
80
externals/libusb/libusb/libusb/os/sunos_usb.h
vendored
Executable file
80
externals/libusb/libusb/libusb/os/sunos_usb.h
vendored
Executable file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates.
|
||||
*
|
||||
* 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_SUNOS_H
|
||||
#define LIBUSB_SUNOS_H
|
||||
|
||||
#include <libdevinfo.h>
|
||||
#include <pthread.h>
|
||||
#include "libusbi.h"
|
||||
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
|
||||
typedef struct sunos_device_priv {
|
||||
uint8_t cfgvalue; /* active config value */
|
||||
uint8_t *raw_cfgdescr; /* active config descriptor */
|
||||
struct libusb_device_descriptor dev_descr; /* usb device descriptor */
|
||||
char *ugenpath; /* name of the ugen(4) node */
|
||||
char *phypath; /* physical path */
|
||||
} sunos_dev_priv_t;
|
||||
|
||||
typedef struct endpoint {
|
||||
int datafd; /* data file */
|
||||
int statfd; /* state file */
|
||||
} sunos_ep_priv_t;
|
||||
|
||||
typedef struct sunos_device_handle_priv {
|
||||
uint8_t altsetting[USB_MAXINTERFACES]; /* a interface's alt */
|
||||
uint8_t config_index;
|
||||
sunos_ep_priv_t eps[USB_MAXENDPOINTS];
|
||||
sunos_dev_priv_t *dpriv; /* device private */
|
||||
} sunos_dev_handle_priv_t;
|
||||
|
||||
typedef struct sunos_transfer_priv {
|
||||
struct aiocb aiocb;
|
||||
struct libusb_transfer *transfer;
|
||||
} sunos_xfer_priv_t;
|
||||
|
||||
struct node_args {
|
||||
struct libusb_context *ctx;
|
||||
struct discovered_devs **discdevs;
|
||||
const char *last_ugenpath;
|
||||
di_devlink_handle_t dlink_hdl;
|
||||
};
|
||||
|
||||
struct devlink_cbarg {
|
||||
struct node_args *nargs; /* di node walk arguments */
|
||||
di_node_t myself; /* the di node */
|
||||
di_minor_t minor;
|
||||
};
|
||||
|
||||
typedef struct walk_link {
|
||||
char *path;
|
||||
int len;
|
||||
char **linkpp;
|
||||
} walk_link_t;
|
||||
|
||||
/* AIO callback args */
|
||||
struct aio_callback_args{
|
||||
struct libusb_transfer *transfer;
|
||||
struct aiocb aiocb;
|
||||
};
|
||||
|
||||
#endif /* LIBUSB_SUNOS_H */
|
||||
80
externals/libusb/libusb/libusb/os/threads_posix.c
vendored
Executable file
80
externals/libusb/libusb/libusb/os/threads_posix.c
vendored
Executable file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* libusb 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <time.h>
|
||||
#if defined(__linux__) || defined(__OpenBSD__)
|
||||
# if defined(__OpenBSD__)
|
||||
# define _BSD_SOURCE
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
# include <sys/syscall.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include <pthread.h>
|
||||
#elif defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "threads_posix.h"
|
||||
#include "libusbi.h"
|
||||
|
||||
int usbi_cond_timedwait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex, const struct timeval *tv)
|
||||
{
|
||||
struct timespec timeout;
|
||||
int r;
|
||||
|
||||
r = usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &timeout);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
timeout.tv_sec += tv->tv_sec;
|
||||
timeout.tv_nsec += tv->tv_usec * 1000;
|
||||
while (timeout.tv_nsec >= 1000000000L) {
|
||||
timeout.tv_nsec -= 1000000000L;
|
||||
timeout.tv_sec++;
|
||||
}
|
||||
|
||||
return pthread_cond_timedwait(cond, mutex, &timeout);
|
||||
}
|
||||
|
||||
int usbi_get_tid(void)
|
||||
{
|
||||
int ret;
|
||||
#if defined(__ANDROID__)
|
||||
ret = gettid();
|
||||
#elif 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 = (int)pthread_mach_thread_np(pthread_self());
|
||||
#elif defined(__CYGWIN__)
|
||||
ret = GetCurrentThreadId();
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
/* TODO: NetBSD thread ID support */
|
||||
return ret;
|
||||
}
|
||||
102
externals/libusb/libusb/libusb/os/threads_posix.h
vendored
Executable file
102
externals/libusb/libusb/libusb/os/threads_posix.h
vendored
Executable file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* libusb 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>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t usbi_mutex_static_t;
|
||||
static inline void usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
|
||||
{
|
||||
(void)pthread_mutex_lock(mutex);
|
||||
}
|
||||
static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
|
||||
{
|
||||
(void)pthread_mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
typedef pthread_mutex_t usbi_mutex_t;
|
||||
static inline int usbi_mutex_init(usbi_mutex_t *mutex)
|
||||
{
|
||||
return pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
static inline void usbi_mutex_lock(usbi_mutex_t *mutex)
|
||||
{
|
||||
(void)pthread_mutex_lock(mutex);
|
||||
}
|
||||
static inline void usbi_mutex_unlock(usbi_mutex_t *mutex)
|
||||
{
|
||||
(void)pthread_mutex_unlock(mutex);
|
||||
}
|
||||
static inline int usbi_mutex_trylock(usbi_mutex_t *mutex)
|
||||
{
|
||||
return pthread_mutex_trylock(mutex);
|
||||
}
|
||||
static inline void usbi_mutex_destroy(usbi_mutex_t *mutex)
|
||||
{
|
||||
(void)pthread_mutex_destroy(mutex);
|
||||
}
|
||||
|
||||
typedef pthread_cond_t usbi_cond_t;
|
||||
static inline void usbi_cond_init(pthread_cond_t *cond)
|
||||
{
|
||||
(void)pthread_cond_init(cond, NULL);
|
||||
}
|
||||
static inline int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex)
|
||||
{
|
||||
return pthread_cond_wait(cond, mutex);
|
||||
}
|
||||
int usbi_cond_timedwait(usbi_cond_t *cond,
|
||||
usbi_mutex_t *mutex, const struct timeval *tv);
|
||||
static inline void usbi_cond_broadcast(usbi_cond_t *cond)
|
||||
{
|
||||
(void)pthread_cond_broadcast(cond);
|
||||
}
|
||||
static inline void usbi_cond_destroy(usbi_cond_t *cond)
|
||||
{
|
||||
(void)pthread_cond_destroy(cond);
|
||||
}
|
||||
|
||||
typedef pthread_key_t usbi_tls_key_t;
|
||||
static inline void usbi_tls_key_create(usbi_tls_key_t *key)
|
||||
{
|
||||
(void)pthread_key_create(key, NULL);
|
||||
}
|
||||
static inline void *usbi_tls_key_get(usbi_tls_key_t key)
|
||||
{
|
||||
return pthread_getspecific(key);
|
||||
}
|
||||
static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr)
|
||||
{
|
||||
(void)pthread_setspecific(key, ptr);
|
||||
}
|
||||
static inline void usbi_tls_key_delete(usbi_tls_key_t key)
|
||||
{
|
||||
(void)pthread_key_delete(key);
|
||||
}
|
||||
|
||||
int usbi_get_tid(void);
|
||||
|
||||
#endif /* LIBUSB_THREADS_POSIX_H */
|
||||
126
externals/libusb/libusb/libusb/os/threads_windows.c
vendored
Executable file
126
externals/libusb/libusb/libusb/os/threads_windows.c
vendored
Executable file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* libusb 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 <errno.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
|
||||
struct usbi_cond_perthread {
|
||||
struct list_head list;
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
void usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
|
||||
{
|
||||
while (InterlockedExchange(mutex, 1L) == 1L)
|
||||
SleepEx(0, TRUE);
|
||||
}
|
||||
|
||||
void usbi_cond_init(usbi_cond_t *cond)
|
||||
{
|
||||
list_init(&cond->waiters);
|
||||
list_init(&cond->not_waiting);
|
||||
}
|
||||
|
||||
static int usbi_cond_intwait(usbi_cond_t *cond,
|
||||
usbi_mutex_t *mutex, DWORD timeout_ms)
|
||||
{
|
||||
struct usbi_cond_perthread *pos;
|
||||
DWORD r;
|
||||
|
||||
// Same assumption as usbi_cond_broadcast() holds
|
||||
if (list_empty(&cond->not_waiting)) {
|
||||
pos = malloc(sizeof(*pos));
|
||||
if (pos == NULL)
|
||||
return ENOMEM; // This errno is not POSIX-allowed.
|
||||
pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
|
||||
if (pos->event == NULL) {
|
||||
free(pos);
|
||||
return ENOMEM;
|
||||
}
|
||||
} else {
|
||||
pos = list_first_entry(&cond->not_waiting, struct usbi_cond_perthread, list);
|
||||
list_del(&pos->list); // remove from not_waiting list.
|
||||
// Ensure the event is clear before waiting
|
||||
WaitForSingleObject(pos->event, 0);
|
||||
}
|
||||
|
||||
list_add(&pos->list, &cond->waiters);
|
||||
|
||||
LeaveCriticalSection(mutex);
|
||||
r = WaitForSingleObject(pos->event, timeout_ms);
|
||||
EnterCriticalSection(mutex);
|
||||
|
||||
list_del(&pos->list);
|
||||
list_add(&pos->list, &cond->not_waiting);
|
||||
|
||||
if (r == WAIT_OBJECT_0)
|
||||
return 0;
|
||||
else if (r == WAIT_TIMEOUT)
|
||||
return ETIMEDOUT;
|
||||
else
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
// 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 timeval *tv)
|
||||
{
|
||||
DWORD millis;
|
||||
|
||||
millis = (DWORD)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
|
||||
/* round up to next millisecond */
|
||||
if (tv->tv_usec % 1000)
|
||||
millis++;
|
||||
return usbi_cond_intwait(cond, mutex, millis);
|
||||
}
|
||||
|
||||
void 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!
|
||||
struct usbi_cond_perthread *pos;
|
||||
|
||||
list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread)
|
||||
SetEvent(pos->event);
|
||||
// The wait function will remove its respective item from the list.
|
||||
}
|
||||
|
||||
void 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;
|
||||
|
||||
if (!list_empty(&cond->waiters))
|
||||
return; // (!see above!)
|
||||
list_for_each_entry_safe(pos, next, &cond->not_waiting, list, struct usbi_cond_perthread) {
|
||||
CloseHandle(pos->event);
|
||||
list_del(&pos->list);
|
||||
free(pos);
|
||||
}
|
||||
}
|
||||
111
externals/libusb/libusb/libusb/os/threads_windows.h
vendored
Executable file
111
externals/libusb/libusb/libusb/os/threads_windows.h
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* libusb 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_INITIALIZER 0L
|
||||
#ifdef _WIN32_WCE
|
||||
typedef LONG usbi_mutex_static_t;
|
||||
#else
|
||||
typedef volatile LONG usbi_mutex_static_t;
|
||||
#endif
|
||||
void usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
|
||||
static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
|
||||
{
|
||||
InterlockedExchange(mutex, 0L);
|
||||
}
|
||||
|
||||
typedef CRITICAL_SECTION usbi_mutex_t;
|
||||
static inline int usbi_mutex_init(usbi_mutex_t *mutex)
|
||||
{
|
||||
InitializeCriticalSection(mutex);
|
||||
return 0;
|
||||
}
|
||||
static inline void usbi_mutex_lock(usbi_mutex_t *mutex)
|
||||
{
|
||||
EnterCriticalSection(mutex);
|
||||
}
|
||||
static inline void usbi_mutex_unlock(usbi_mutex_t *mutex)
|
||||
{
|
||||
LeaveCriticalSection(mutex);
|
||||
}
|
||||
static inline int usbi_mutex_trylock(usbi_mutex_t *mutex)
|
||||
{
|
||||
return !TryEnterCriticalSection(mutex);
|
||||
}
|
||||
static inline void usbi_mutex_destroy(usbi_mutex_t *mutex)
|
||||
{
|
||||
DeleteCriticalSection(mutex);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
typedef struct usbi_cond {
|
||||
// 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;
|
||||
} usbi_cond_t;
|
||||
|
||||
void usbi_cond_init(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 timeval *tv);
|
||||
void usbi_cond_broadcast(usbi_cond_t *cond);
|
||||
void usbi_cond_destroy(usbi_cond_t *cond);
|
||||
|
||||
typedef DWORD usbi_tls_key_t;
|
||||
static inline void usbi_tls_key_create(usbi_tls_key_t *key)
|
||||
{
|
||||
*key = TlsAlloc();
|
||||
}
|
||||
static inline void *usbi_tls_key_get(usbi_tls_key_t key)
|
||||
{
|
||||
return TlsGetValue(key);
|
||||
}
|
||||
static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr)
|
||||
{
|
||||
(void)TlsSetValue(key, ptr);
|
||||
}
|
||||
static inline void usbi_tls_key_delete(usbi_tls_key_t key)
|
||||
{
|
||||
(void)TlsFree(key);
|
||||
}
|
||||
|
||||
static inline int usbi_get_tid(void)
|
||||
{
|
||||
return (int)GetCurrentThreadId();
|
||||
}
|
||||
|
||||
#endif /* LIBUSB_THREADS_WINDOWS_H */
|
||||
888
externals/libusb/libusb/libusb/os/wince_usb.c
vendored
Executable file
888
externals/libusb/libusb/libusb/os/wince_usb.c
vendored
Executable file
@@ -0,0 +1,888 @@
|
||||
/*
|
||||
* Windows CE backend for libusb 1.0
|
||||
* Copyright © 2011-2013 RealVNC Ltd.
|
||||
* Large 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "libusbi.h"
|
||||
#include "wince_usb.h"
|
||||
|
||||
// Global variables
|
||||
int errno = 0;
|
||||
static uint64_t hires_frequency, hires_ticks_to_ps;
|
||||
static HANDLE driver_handle = INVALID_HANDLE_VALUE;
|
||||
static int concurrent_usage = -1;
|
||||
|
||||
/*
|
||||
* Converts a windows error to human readable string
|
||||
* uses retval as errorcode, or, if 0, use GetLastError()
|
||||
*/
|
||||
#if defined(ENABLE_LOGGING)
|
||||
static const char *windows_error_str(DWORD error_code)
|
||||
{
|
||||
static TCHAR wErr_string[ERR_BUFFER_SIZE];
|
||||
static char err_string[ERR_BUFFER_SIZE];
|
||||
|
||||
DWORD size;
|
||||
int len;
|
||||
|
||||
if (error_code == 0)
|
||||
error_code = GetLastError();
|
||||
|
||||
len = sprintf(err_string, "[%u] ", (unsigned int)error_code);
|
||||
|
||||
size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
wErr_string, ERR_BUFFER_SIZE, NULL);
|
||||
if (size == 0) {
|
||||
DWORD format_error = GetLastError();
|
||||
if (format_error)
|
||||
snprintf(err_string, ERR_BUFFER_SIZE,
|
||||
"Windows error code %u (FormatMessage error code %u)",
|
||||
(unsigned int)error_code, (unsigned int)format_error);
|
||||
else
|
||||
snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code);
|
||||
} else {
|
||||
// Remove CR/LF terminators, if present
|
||||
size_t pos = size - 2;
|
||||
if (wErr_string[pos] == 0x0D)
|
||||
wErr_string[pos] = 0;
|
||||
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, &err_string[len], ERR_BUFFER_SIZE - len, NULL, NULL))
|
||||
strcpy(err_string, "Unable to convert error string");
|
||||
}
|
||||
|
||||
return err_string;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct wince_device_priv *_device_priv(struct libusb_device *dev)
|
||||
{
|
||||
return (struct wince_device_priv *)dev->os_priv;
|
||||
}
|
||||
|
||||
// ceusbkwrapper to libusb error code mapping
|
||||
static int translate_driver_error(DWORD error)
|
||||
{
|
||||
switch (error) {
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
return LIBUSB_ERROR_INVALID_PARAM;
|
||||
case ERROR_CALL_NOT_IMPLEMENTED:
|
||||
case ERROR_NOT_SUPPORTED:
|
||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
case ERROR_INVALID_HANDLE:
|
||||
return LIBUSB_ERROR_NO_DEVICE;
|
||||
case ERROR_BUSY:
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
|
||||
// Error codes that are either unexpected, or have
|
||||
// no suitable LIBUSB_ERROR equivalent.
|
||||
case ERROR_CANCELLED:
|
||||
case ERROR_INTERNAL_ERROR:
|
||||
default:
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL init_dllimports(void)
|
||||
{
|
||||
DLL_GET_HANDLE(ceusbkwrapper);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
|
||||
DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void exit_dllimports(void)
|
||||
{
|
||||
DLL_FREE_HANDLE(ceusbkwrapper);
|
||||
}
|
||||
|
||||
static int init_device(
|
||||
struct libusb_device *dev, UKW_DEVICE drv_dev,
|
||||
unsigned char bus_addr, unsigned char dev_addr)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(dev);
|
||||
int r = LIBUSB_SUCCESS;
|
||||
|
||||
dev->bus_number = bus_addr;
|
||||
dev->device_address = dev_addr;
|
||||
priv->dev = drv_dev;
|
||||
|
||||
if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc)))
|
||||
r = translate_driver_error(GetLastError());
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Internal API functions
|
||||
static int wince_init(struct libusb_context *ctx)
|
||||
{
|
||||
int r = LIBUSB_ERROR_OTHER;
|
||||
HANDLE semaphore;
|
||||
LARGE_INTEGER li_frequency;
|
||||
TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
|
||||
|
||||
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
|
||||
semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
|
||||
if (semaphore == NULL) {
|
||||
usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
// A successful wait brings our semaphore count to 0 (unsignaled)
|
||||
// => any concurent wait stalls until the semaphore's release
|
||||
if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
|
||||
usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
|
||||
CloseHandle(semaphore);
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
// NB: concurrent usage supposes that init calls are equally balanced with
|
||||
// exit calls. If init is called more than exit, we will not exit properly
|
||||
if ( ++concurrent_usage == 0 ) { // First init?
|
||||
// Load DLL imports
|
||||
if (!init_dllimports()) {
|
||||
usbi_err(ctx, "could not resolve DLL functions");
|
||||
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
goto init_exit;
|
||||
}
|
||||
|
||||
// try to open a handle to the driver
|
||||
driver_handle = UkwOpenDriver();
|
||||
if (driver_handle == INVALID_HANDLE_VALUE) {
|
||||
usbi_err(ctx, "could not connect to driver");
|
||||
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
goto init_exit;
|
||||
}
|
||||
|
||||
// find out if we have access to a monotonic (hires) timer
|
||||
if (QueryPerformanceFrequency(&li_frequency)) {
|
||||
hires_frequency = li_frequency.QuadPart;
|
||||
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
|
||||
// to picoseconds to compute the tv_nsecs part in clock_gettime
|
||||
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
|
||||
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
|
||||
} else {
|
||||
usbi_dbg("no hires timer available on this platform");
|
||||
hires_frequency = 0;
|
||||
hires_ticks_to_ps = UINT64_C(0);
|
||||
}
|
||||
}
|
||||
// At this stage, either we went through full init successfully, or didn't need to
|
||||
r = LIBUSB_SUCCESS;
|
||||
|
||||
init_exit: // Holds semaphore here.
|
||||
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
|
||||
exit_dllimports();
|
||||
|
||||
if (driver_handle != INVALID_HANDLE_VALUE) {
|
||||
UkwCloseDriver(driver_handle);
|
||||
driver_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != LIBUSB_SUCCESS)
|
||||
--concurrent_usage; // Not expected to call libusb_exit if we failed.
|
||||
|
||||
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
||||
CloseHandle(semaphore);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void wince_exit(struct libusb_context *ctx)
|
||||
{
|
||||
HANDLE semaphore;
|
||||
TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
|
||||
UNUSED(ctx);
|
||||
|
||||
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
|
||||
semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
|
||||
if (semaphore == NULL)
|
||||
return;
|
||||
|
||||
// A successful wait brings our semaphore count to 0 (unsignaled)
|
||||
// => any concurent wait stalls until the semaphore release
|
||||
if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
|
||||
CloseHandle(semaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only works if exits and inits are balanced exactly
|
||||
if (--concurrent_usage < 0) { // Last exit
|
||||
exit_dllimports();
|
||||
|
||||
if (driver_handle != INVALID_HANDLE_VALUE) {
|
||||
UkwCloseDriver(driver_handle);
|
||||
driver_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
||||
CloseHandle(semaphore);
|
||||
}
|
||||
|
||||
static int wince_get_device_list(
|
||||
struct libusb_context *ctx,
|
||||
struct discovered_devs **discdevs)
|
||||
{
|
||||
UKW_DEVICE devices[MAX_DEVICE_COUNT];
|
||||
struct discovered_devs *new_devices = *discdevs;
|
||||
DWORD count = 0, i;
|
||||
struct libusb_device *dev = NULL;
|
||||
unsigned char bus_addr, dev_addr;
|
||||
unsigned long session_id;
|
||||
BOOL success;
|
||||
DWORD release_list_offset = 0;
|
||||
int r = LIBUSB_SUCCESS;
|
||||
|
||||
success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count);
|
||||
if (!success) {
|
||||
int libusbErr = translate_driver_error(GetLastError());
|
||||
usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
|
||||
return libusbErr;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
release_list_offset = i;
|
||||
success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
|
||||
if (!success) {
|
||||
r = translate_driver_error(GetLastError());
|
||||
usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0));
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
dev = usbi_get_device_by_session_id(ctx, session_id);
|
||||
if (dev) {
|
||||
usbi_dbg("using existing device for %u/%u (session %lu)",
|
||||
bus_addr, dev_addr, session_id);
|
||||
// Release just this element in the device list (as we already hold a
|
||||
// reference to it).
|
||||
UkwReleaseDeviceList(driver_handle, &devices[i], 1);
|
||||
release_list_offset++;
|
||||
} else {
|
||||
usbi_dbg("allocating new device for %u/%u (session %lu)",
|
||||
bus_addr, dev_addr, session_id);
|
||||
dev = usbi_alloc_device(ctx, session_id);
|
||||
if (!dev) {
|
||||
r = LIBUSB_ERROR_NO_MEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
r = init_device(dev, devices[i], bus_addr, dev_addr);
|
||||
if (r < 0)
|
||||
goto err_out;
|
||||
|
||||
r = usbi_sanitize_device(dev);
|
||||
if (r < 0)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
new_devices = discovered_devs_append(new_devices, dev);
|
||||
if (!new_devices) {
|
||||
r = LIBUSB_ERROR_NO_MEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
libusb_unref_device(dev);
|
||||
}
|
||||
|
||||
*discdevs = new_devices;
|
||||
return r;
|
||||
err_out:
|
||||
*discdevs = new_devices;
|
||||
libusb_unref_device(dev);
|
||||
// Release the remainder of the unprocessed device list.
|
||||
// The devices added to new_devices already will still be passed up to libusb,
|
||||
// which can dispose of them at its leisure.
|
||||
UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int wince_open(struct libusb_device_handle *handle)
|
||||
{
|
||||
// Nothing to do to open devices as a handle to it has
|
||||
// been retrieved by wince_get_device_list
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static void wince_close(struct libusb_device_handle *handle)
|
||||
{
|
||||
// Nothing to do as wince_open does nothing.
|
||||
}
|
||||
|
||||
static int wince_get_device_descriptor(
|
||||
struct libusb_device *device,
|
||||
unsigned char *buffer, int *host_endian)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(device);
|
||||
|
||||
*host_endian = 1;
|
||||
memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_get_active_config_descriptor(
|
||||
struct libusb_device *device,
|
||||
unsigned char *buffer, size_t len, int *host_endian)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(device);
|
||||
DWORD actualSize = len;
|
||||
|
||||
*host_endian = 0;
|
||||
if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return actualSize;
|
||||
}
|
||||
|
||||
static int wince_get_config_descriptor(
|
||||
struct libusb_device *device,
|
||||
uint8_t config_index,
|
||||
unsigned char *buffer, size_t len, int *host_endian)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(device);
|
||||
DWORD actualSize = len;
|
||||
|
||||
*host_endian = 0;
|
||||
if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return actualSize;
|
||||
}
|
||||
|
||||
static int wince_get_configuration(
|
||||
struct libusb_device_handle *handle,
|
||||
int *config)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
UCHAR cv = 0;
|
||||
|
||||
if (!UkwGetConfig(priv->dev, &cv))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
(*config) = cv;
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_set_configuration(
|
||||
struct libusb_device_handle *handle,
|
||||
int config)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
// Setting configuration 0 places the device in Address state.
|
||||
// This should correspond to the "unconfigured state" required by
|
||||
// libusb when the specified configuration is -1.
|
||||
UCHAR cv = (config < 0) ? 0 : config;
|
||||
if (!UkwSetConfig(priv->dev, cv))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_claim_interface(
|
||||
struct libusb_device_handle *handle,
|
||||
int interface_number)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwClaimInterface(priv->dev, interface_number))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_release_interface(
|
||||
struct libusb_device_handle *handle,
|
||||
int interface_number)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
if (!UkwReleaseInterface(priv->dev, interface_number))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_set_interface_altsetting(
|
||||
struct libusb_device_handle *handle,
|
||||
int interface_number, int altsetting)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_clear_halt(
|
||||
struct libusb_device_handle *handle,
|
||||
unsigned char endpoint)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwClearHaltHost(priv->dev, endpoint))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
if (!UkwClearHaltDevice(priv->dev, endpoint))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_reset_device(
|
||||
struct libusb_device_handle *handle)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwResetDevice(priv->dev))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_kernel_driver_active(
|
||||
struct libusb_device_handle *handle,
|
||||
int interface_number)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (!UkwKernelDriverActive(priv->dev, interface_number, &result))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return result ? 1 : 0;
|
||||
}
|
||||
|
||||
static int wince_detach_kernel_driver(
|
||||
struct libusb_device_handle *handle,
|
||||
int interface_number)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwDetachKernelDriver(priv->dev, interface_number))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_attach_kernel_driver(
|
||||
struct libusb_device_handle *handle,
|
||||
int interface_number)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||
|
||||
if (!UkwAttachKernelDriver(priv->dev, interface_number))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static void wince_destroy_device(struct libusb_device *dev)
|
||||
{
|
||||
struct wince_device_priv *priv = _device_priv(dev);
|
||||
|
||||
UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
|
||||
}
|
||||
|
||||
static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
||||
|
||||
usbi_close(transfer_priv->pollable_fd.fd);
|
||||
transfer_priv->pollable_fd = INVALID_WINFD;
|
||||
}
|
||||
|
||||
static int wince_cancel_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
||||
struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
||||
|
||||
if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT))
|
||||
return translate_driver_error(GetLastError());
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
|
||||
struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
||||
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
||||
BOOL direction_in, ret;
|
||||
struct winfd wfd;
|
||||
DWORD flags;
|
||||
PUKW_CONTROL_HEADER setup = NULL;
|
||||
const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;
|
||||
int r;
|
||||
|
||||
if (control_transfer) {
|
||||
setup = (PUKW_CONTROL_HEADER) transfer->buffer;
|
||||
direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
|
||||
} else {
|
||||
direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
|
||||
}
|
||||
flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
|
||||
flags |= UKW_TF_SHORT_TRANSFER_OK;
|
||||
|
||||
wfd = usbi_create_fd();
|
||||
if (wfd.fd < 0)
|
||||
return LIBUSB_ERROR_NO_MEM;
|
||||
|
||||
r = usbi_add_pollfd(ctx, wfd.fd, direction_in ? POLLIN : POLLOUT);
|
||||
if (r) {
|
||||
usbi_close(wfd.fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
transfer_priv->pollable_fd = wfd;
|
||||
|
||||
if (control_transfer) {
|
||||
// Split out control setup header and data buffer
|
||||
DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
|
||||
PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];
|
||||
|
||||
ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
|
||||
} else {
|
||||
ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
|
||||
transfer->length, &transfer->actual_length, wfd.overlapped);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
int libusbErr = translate_driver_error(GetLastError());
|
||||
usbi_err(ctx, "UkwIssue%sTransfer failed: error %u",
|
||||
control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError());
|
||||
usbi_remove_pollfd(ctx, wfd.fd);
|
||||
usbi_close(wfd.fd);
|
||||
transfer_priv->pollable_fd = INVALID_WINFD;
|
||||
return libusbErr;
|
||||
}
|
||||
|
||||
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
static int wince_submit_transfer(struct usbi_transfer *itransfer)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
|
||||
switch (transfer->type) {
|
||||
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||
return wince_submit_control_or_bulk_transfer(itransfer);
|
||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||
default:
|
||||
usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
|
||||
return LIBUSB_ERROR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
static void wince_transfer_callback(
|
||||
struct usbi_transfer *itransfer,
|
||||
uint32_t io_result, uint32_t io_size)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
|
||||
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
||||
int status;
|
||||
|
||||
usbi_dbg("handling I/O completion with errcode %u", io_result);
|
||||
|
||||
if (io_result == ERROR_NOT_SUPPORTED &&
|
||||
transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
|
||||
/* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
|
||||
* Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
|
||||
* endpoint isn't actually stalled.
|
||||
*
|
||||
* One example of this is that some devices will occasionally fail to reply to an IN
|
||||
* token. The WinCE USB layer carries on with the transaction until it is completed
|
||||
* (or cancelled) but then completes it with USB_ERROR_STALL.
|
||||
*
|
||||
* This code therefore needs to confirm that there really is a stall error, by both
|
||||
* checking the pipe status and requesting the endpoint status from the device.
|
||||
*/
|
||||
BOOL halted = FALSE;
|
||||
usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
|
||||
if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
|
||||
/* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
|
||||
* control request to the device. This is done synchronously, which is a bit
|
||||
* naughty, but this is a special corner case.
|
||||
*/
|
||||
WORD wStatus = 0;
|
||||
DWORD written = 0;
|
||||
UKW_CONTROL_HEADER ctrlHeader;
|
||||
ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD |
|
||||
LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT;
|
||||
ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS;
|
||||
ctrlHeader.wValue = 0;
|
||||
ctrlHeader.wIndex = transfer->endpoint;
|
||||
ctrlHeader.wLength = sizeof(wStatus);
|
||||
if (UkwIssueControlTransfer(priv->dev,
|
||||
UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT,
|
||||
&ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) {
|
||||
if (written == sizeof(wStatus) &&
|
||||
(wStatus & STATUS_HALT_FLAG) == 0) {
|
||||
if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) {
|
||||
usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success");
|
||||
io_result = ERROR_SUCCESS;
|
||||
} else {
|
||||
usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error");
|
||||
io_result = ERROR_IO_DEVICE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(io_result) {
|
||||
case ERROR_SUCCESS:
|
||||
itransfer->transferred += io_size;
|
||||
status = LIBUSB_TRANSFER_COMPLETED;
|
||||
break;
|
||||
case ERROR_CANCELLED:
|
||||
usbi_dbg("detected transfer cancel");
|
||||
status = LIBUSB_TRANSFER_CANCELLED;
|
||||
break;
|
||||
case ERROR_NOT_SUPPORTED:
|
||||
case ERROR_GEN_FAILURE:
|
||||
usbi_dbg("detected endpoint stall");
|
||||
status = LIBUSB_TRANSFER_STALL;
|
||||
break;
|
||||
case ERROR_SEM_TIMEOUT:
|
||||
usbi_dbg("detected semaphore timeout");
|
||||
status = LIBUSB_TRANSFER_TIMED_OUT;
|
||||
break;
|
||||
case ERROR_OPERATION_ABORTED:
|
||||
usbi_dbg("detected operation aborted");
|
||||
status = LIBUSB_TRANSFER_CANCELLED;
|
||||
break;
|
||||
default:
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
|
||||
status = LIBUSB_TRANSFER_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
wince_clear_transfer_priv(itransfer);
|
||||
if (status == LIBUSB_TRANSFER_CANCELLED)
|
||||
usbi_handle_transfer_cancellation(itransfer);
|
||||
else
|
||||
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
|
||||
}
|
||||
|
||||
static void wince_handle_callback(
|
||||
struct usbi_transfer *itransfer,
|
||||
uint32_t io_result, uint32_t io_size)
|
||||
{
|
||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||
|
||||
switch (transfer->type) {
|
||||
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||
wince_transfer_callback (itransfer, io_result, io_size);
|
||||
break;
|
||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||
break;
|
||||
default:
|
||||
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
||||
}
|
||||
}
|
||||
|
||||
static int wince_handle_events(
|
||||
struct libusb_context *ctx,
|
||||
struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
|
||||
{
|
||||
struct wince_transfer_priv* transfer_priv = NULL;
|
||||
POLL_NFDS_TYPE i = 0;
|
||||
BOOL found = FALSE;
|
||||
struct usbi_transfer *itransfer;
|
||||
DWORD io_size, io_result;
|
||||
int r = LIBUSB_SUCCESS;
|
||||
|
||||
usbi_mutex_lock(&ctx->open_devs_lock);
|
||||
for (i = 0; i < nfds && num_ready > 0; i++) {
|
||||
|
||||
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
|
||||
|
||||
if (!fds[i].revents)
|
||||
continue;
|
||||
|
||||
num_ready--;
|
||||
|
||||
// Because a Windows OVERLAPPED is used for poll emulation,
|
||||
// a pollable fd is created and stored with each transfer
|
||||
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
||||
list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
||||
transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
||||
if (transfer_priv->pollable_fd.fd == fds[i].fd) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
||||
|
||||
if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) {
|
||||
io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal;
|
||||
io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
|
||||
usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
|
||||
// let handle_callback free the event using the transfer wfd
|
||||
// If you don't use the transfer wfd, you run a risk of trying to free a
|
||||
// newly allocated wfd that took the place of the one from the transfer.
|
||||
wince_handle_callback(itransfer, io_result, io_size);
|
||||
} else if (found) {
|
||||
usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]);
|
||||
r = LIBUSB_ERROR_OTHER;
|
||||
break;
|
||||
} else {
|
||||
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
|
||||
r = LIBUSB_ERROR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Monotonic and real time functions
|
||||
*/
|
||||
static int wince_clock_gettime(int clk_id, struct timespec *tp)
|
||||
{
|
||||
LARGE_INTEGER hires_counter;
|
||||
ULARGE_INTEGER rtime;
|
||||
FILETIME filetime;
|
||||
SYSTEMTIME st;
|
||||
|
||||
switch(clk_id) {
|
||||
case USBI_CLOCK_MONOTONIC:
|
||||
if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
|
||||
tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
||||
tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
// Fall through and return real-time if monotonic read failed or was not detected @ init
|
||||
case USBI_CLOCK_REALTIME:
|
||||
// We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
|
||||
// with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
|
||||
// Note however that our resolution is bounded by the Windows system time
|
||||
// functions and is at best of the order of 1 ms (or, usually, worse)
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &filetime);
|
||||
rtime.LowPart = filetime.dwLowDateTime;
|
||||
rtime.HighPart = filetime.dwHighDateTime;
|
||||
rtime.QuadPart -= EPOCH_TIME;
|
||||
tp->tv_sec = (long)(rtime.QuadPart / 10000000);
|
||||
tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
|
||||
return LIBUSB_SUCCESS;
|
||||
default:
|
||||
return LIBUSB_ERROR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
const struct usbi_os_backend usbi_backend = {
|
||||
"Windows CE",
|
||||
0,
|
||||
wince_init,
|
||||
wince_exit,
|
||||
NULL, /* set_option() */
|
||||
|
||||
wince_get_device_list,
|
||||
NULL, /* hotplug_poll */
|
||||
wince_open,
|
||||
wince_close,
|
||||
|
||||
wince_get_device_descriptor,
|
||||
wince_get_active_config_descriptor,
|
||||
wince_get_config_descriptor,
|
||||
NULL, /* get_config_descriptor_by_value() */
|
||||
|
||||
wince_get_configuration,
|
||||
wince_set_configuration,
|
||||
wince_claim_interface,
|
||||
wince_release_interface,
|
||||
|
||||
wince_set_interface_altsetting,
|
||||
wince_clear_halt,
|
||||
wince_reset_device,
|
||||
|
||||
NULL, /* alloc_streams */
|
||||
NULL, /* free_streams */
|
||||
|
||||
NULL, /* dev_mem_alloc() */
|
||||
NULL, /* dev_mem_free() */
|
||||
|
||||
wince_kernel_driver_active,
|
||||
wince_detach_kernel_driver,
|
||||
wince_attach_kernel_driver,
|
||||
|
||||
wince_destroy_device,
|
||||
|
||||
wince_submit_transfer,
|
||||
wince_cancel_transfer,
|
||||
wince_clear_transfer_priv,
|
||||
|
||||
wince_handle_events,
|
||||
NULL, /* handle_transfer_completion() */
|
||||
|
||||
wince_clock_gettime,
|
||||
0,
|
||||
sizeof(struct wince_device_priv),
|
||||
0,
|
||||
sizeof(struct wince_transfer_priv),
|
||||
};
|
||||
126
externals/libusb/libusb/libusb/os/wince_usb.h
vendored
Executable file
126
externals/libusb/libusb/libusb/os/wince_usb.h
vendored
Executable file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Windows CE backend for libusb 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 libusb 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_HANDLE(ceusbkwrapper);
|
||||
DLL_DECLARE_FUNC(WINAPI, HANDLE, UkwOpenDriver, ());
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, void, UkwCloseDriver, (HANDLE));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
|
||||
DLL_DECLARE_FUNC(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
|
||||
DLL_DECLARE_FUNC(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_transfer_priv {
|
||||
struct winfd pollable_fd;
|
||||
uint8_t interface_number;
|
||||
};
|
||||
|
||||
128
externals/libusb/libusb/libusb/os/windows_common.h
vendored
Executable file
128
externals/libusb/libusb/libusb/os/windows_common.h
vendored
Executable file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Windows backend common header for libusb 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 EPOCH_TIME UINT64_C(116444736000000000) // 1970.01.01 00:00:000 in MS Filetime
|
||||
|
||||
#if defined(__CYGWIN__ )
|
||||
#define _stricmp strcasecmp
|
||||
#define _strdup strdup
|
||||
// _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, (LPDWORD)f)
|
||||
#endif
|
||||
|
||||
#define safe_free(p) do {if (p != NULL) {free((void *)p); p = NULL;}} while (0)
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
#define ERR_BUFFER_SIZE 256
|
||||
|
||||
/*
|
||||
* API macros - leveraged from libusb-win32 1.x
|
||||
*/
|
||||
#ifndef _WIN32_WCE
|
||||
#define DLL_STRINGIFY(s) #s
|
||||
#define DLL_LOAD_LIBRARY(name) LoadLibraryA(DLL_STRINGIFY(name))
|
||||
#else
|
||||
#define DLL_STRINGIFY(s) L#s
|
||||
#define DLL_LOAD_LIBRARY(name) LoadLibrary(DLL_STRINGIFY(name))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros for handling DLL themselves
|
||||
*/
|
||||
#define DLL_HANDLE_NAME(name) __dll_##name##_handle
|
||||
|
||||
#define DLL_DECLARE_HANDLE(name) \
|
||||
static HMODULE DLL_HANDLE_NAME(name) = NULL
|
||||
|
||||
#define DLL_GET_HANDLE(name) \
|
||||
do { \
|
||||
DLL_HANDLE_NAME(name) = DLL_LOAD_LIBRARY(name); \
|
||||
if (!DLL_HANDLE_NAME(name)) \
|
||||
return FALSE; \
|
||||
} while (0)
|
||||
|
||||
#define DLL_FREE_HANDLE(name) \
|
||||
do { \
|
||||
if (DLL_HANDLE_NAME(name)) { \
|
||||
FreeLibrary(DLL_HANDLE_NAME(name)); \
|
||||
DLL_HANDLE_NAME(name) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Macros for handling functions within a DLL
|
||||
*/
|
||||
#define DLL_FUNC_NAME(name) __dll_##name##_func_t
|
||||
|
||||
#define DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefixname, name, args) \
|
||||
typedef ret (api * DLL_FUNC_NAME(name))args; \
|
||||
static DLL_FUNC_NAME(name) prefixname = NULL
|
||||
|
||||
#define DLL_DECLARE_FUNC(api, ret, name, args) \
|
||||
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, name, name, args)
|
||||
#define DLL_DECLARE_FUNC_PREFIXED(api, ret, prefix, name, args) \
|
||||
DLL_DECLARE_FUNC_PREFIXNAME(api, ret, prefix##name, name, args)
|
||||
|
||||
#define DLL_LOAD_FUNC_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
|
||||
do { \
|
||||
HMODULE h = DLL_HANDLE_NAME(dll); \
|
||||
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
|
||||
DLL_STRINGIFY(name)); \
|
||||
if (prefixname) \
|
||||
break; \
|
||||
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
|
||||
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
|
||||
if (prefixname) \
|
||||
break; \
|
||||
prefixname = (DLL_FUNC_NAME(name))GetProcAddress(h, \
|
||||
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
|
||||
if (prefixname) \
|
||||
break; \
|
||||
if (ret_on_failure) \
|
||||
return FALSE; \
|
||||
} while (0)
|
||||
|
||||
#define DLL_LOAD_FUNC(dll, name, ret_on_failure) \
|
||||
DLL_LOAD_FUNC_PREFIXNAME(dll, name, name, ret_on_failure)
|
||||
#define DLL_LOAD_FUNC_PREFIXED(dll, prefix, name, ret_on_failure) \
|
||||
DLL_LOAD_FUNC_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user