Merge pull request #4150 from Pringo/master
Externals: Update libusb to version 1.0.20
This commit is contained in:
commit
be6aeaad33
|
@ -8,20 +8,22 @@ Copyright © 2010-2012 Michael Plante <michael.plante@gmail.com>
|
||||||
Copyright © 2011-2013 Hans de Goede <hdegoede@redhat.com>
|
Copyright © 2011-2013 Hans de Goede <hdegoede@redhat.com>
|
||||||
Copyright © 2012-2013 Martin Pieuchot <mpi@openbsd.org>
|
Copyright © 2012-2013 Martin Pieuchot <mpi@openbsd.org>
|
||||||
Copyright © 2012-2013 Toby Gray <toby.gray@realvnc.com>
|
Copyright © 2012-2013 Toby Gray <toby.gray@realvnc.com>
|
||||||
|
Copyright © 2013-2015 Chris Dickens <christopher.a.dickens@gmail.com>
|
||||||
|
|
||||||
Other contributors:
|
Other contributors:
|
||||||
|
Akshay Jaggi
|
||||||
Alan Ott
|
Alan Ott
|
||||||
Alan Stern
|
Alan Stern
|
||||||
Alex Vatchenko
|
Alex Vatchenko
|
||||||
Andrew Fernandes
|
Andrew Fernandes
|
||||||
Anthony Clay
|
Anthony Clay
|
||||||
|
Antonio Ospite
|
||||||
Artem Egorkine
|
Artem Egorkine
|
||||||
Aurelien Jarno
|
Aurelien Jarno
|
||||||
Bastien Nocera
|
Bastien Nocera
|
||||||
Bei Zhang
|
Bei Zhang
|
||||||
Benjamin Dobell
|
Benjamin Dobell
|
||||||
Carl Karsten
|
Carl Karsten
|
||||||
Chris Dickens
|
|
||||||
Colin Walters
|
Colin Walters
|
||||||
Dave Camarillo
|
Dave Camarillo
|
||||||
David Engraf
|
David Engraf
|
||||||
|
@ -32,6 +34,7 @@ Felipe Balbi
|
||||||
Florian Albrechtskirchinger
|
Florian Albrechtskirchinger
|
||||||
Francesco Montorsi
|
Francesco Montorsi
|
||||||
Francisco Facioni
|
Francisco Facioni
|
||||||
|
Gaurav Gupta
|
||||||
Graeme Gill
|
Graeme Gill
|
||||||
Gustavo Zacarias
|
Gustavo Zacarias
|
||||||
Hans Ulrich Niedermann
|
Hans Ulrich Niedermann
|
||||||
|
@ -48,7 +51,9 @@ Kuangye Guo
|
||||||
Lars Kanis
|
Lars Kanis
|
||||||
Lars Wirzenius
|
Lars Wirzenius
|
||||||
Luca Longinotti
|
Luca Longinotti
|
||||||
|
Marcus Meissner
|
||||||
Markus Heidelberg
|
Markus Heidelberg
|
||||||
|
Martin Ettl
|
||||||
Martin Koegler
|
Martin Koegler
|
||||||
Matthias Bolte
|
Matthias Bolte
|
||||||
Mike Frysinger
|
Mike Frysinger
|
||||||
|
@ -64,15 +69,21 @@ Rob Walker
|
||||||
Sean McBride
|
Sean McBride
|
||||||
Sebastian Pipping
|
Sebastian Pipping
|
||||||
Simon Haggett
|
Simon Haggett
|
||||||
|
Simon Newton
|
||||||
Thomas Röfer
|
Thomas Röfer
|
||||||
|
Tim Hutt
|
||||||
Tim Roberts
|
Tim Roberts
|
||||||
|
Tobias Klauser
|
||||||
Toby Peterson
|
Toby Peterson
|
||||||
|
Tormod Volden
|
||||||
Trygve Laugstøl
|
Trygve Laugstøl
|
||||||
Uri Lublin
|
Uri Lublin
|
||||||
Vasily Khoruzhick
|
Vasily Khoruzhick
|
||||||
Vegard Storheil Eriksen
|
Vegard Storheil Eriksen
|
||||||
|
Venkatesh Shukla
|
||||||
Vitali Lovich
|
Vitali Lovich
|
||||||
Xiaofan Chen
|
Xiaofan Chen
|
||||||
Zoltán Kovács
|
Zoltán Kovács
|
||||||
Роман Донченко
|
Роман Донченко
|
||||||
|
parafin
|
||||||
xantares
|
xantares
|
||||||
|
|
|
@ -1,14 +1,30 @@
|
||||||
For detailed information about the changes below, please see the git log or
|
For detailed information about the changes below, please see the git log or
|
||||||
visit: http://log.libusb.info
|
visit: http://log.libusb.info
|
||||||
|
|
||||||
|
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
|
2014-05-30: v1.0.19
|
||||||
* Add support for USB bulk streams on Linux and Mac OS X (#11)
|
* 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: Add AMD and Intel USB-3.0 root hub support
|
||||||
* Windows: Fix USB 3.0 speed detection on Windows 8 or later (#10)
|
* Windows: Fix USB 3.0 speed detection on Windows 8 or later (#10)
|
||||||
* Added Russian translation for libusb_strerror strings
|
* Added Russian translation for libusb_strerror strings
|
||||||
* All: Various small fixes and cleanups
|
* All: Various small fixes and cleanups
|
||||||
The (#xx) numbers are libusb issue numbers, see ie:
|
|
||||||
https://github.com/libusb/libusb/issues/11
|
|
||||||
|
|
||||||
2014-01-25: v1.0.18
|
2014-01-25: v1.0.18
|
||||||
* Fix multiple memory leaks
|
* Fix multiple memory leaks
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Dolphin-specific changes (as of 2015-02-12)
|
Dolphin-specific changes (as of 2016-08-25)
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
- removed all toplevel directories save msvc/ & libusb/
|
- removed all toplevel directories save msvc/ & libusb/
|
||||||
|
|
|
@ -2,9 +2,10 @@ libusb
|
||||||
======
|
======
|
||||||
|
|
||||||
libusb is a library for USB device access from Linux, Mac OS X,
|
libusb is a library for USB device access from Linux, Mac OS X,
|
||||||
Windows and OpenBSD/NetBSD userspace.
|
Windows, OpenBSD/NetBSD and Haiku userspace.
|
||||||
It is written in C and licensed under the GNU Lesser General Public
|
It is written in C (Haiku backend in C++) and licensed under the GNU
|
||||||
License version 2.1 or, at your option, any later version (see COPYING).
|
Lesser General Public License version 2.1 or, at your option, any later
|
||||||
|
version (see COPYING).
|
||||||
|
|
||||||
libusb is abstracted internally in such a way that it can hopefully
|
libusb is abstracted internally in such a way that it can hopefully
|
||||||
be ported to other operating systems. Please see the PORTING file
|
be ported to other operating systems. Please see the PORTING file
|
||||||
|
@ -24,4 +25,5 @@ http://mailing-list.libusb.info
|
||||||
- Xiaofan Chen <xiaofanc@gmail.com>
|
- Xiaofan Chen <xiaofanc@gmail.com>
|
||||||
- Ludovic Rousseau <ludovic.rousseau@gmail.com>
|
- Ludovic Rousseau <ludovic.rousseau@gmail.com>
|
||||||
- Nathan Hjelm <hjelmn@users.sourceforge.net>
|
- Nathan Hjelm <hjelmn@users.sourceforge.net>
|
||||||
|
- Chris Dickens <christopher.a.dickens@gmail.com>
|
||||||
(Please use the mailing list rather than mailing developers directly)
|
(Please use the mailing list rather than mailing developers directly)
|
||||||
|
|
|
@ -12,12 +12,18 @@ NETBSD_USB_SRC = os/netbsd_usb.c
|
||||||
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
|
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
|
||||||
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
|
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
|
||||||
|
|
||||||
|
DIST_SUBDIRS =
|
||||||
|
|
||||||
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
|
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
|
||||||
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
|
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
|
||||||
$(POSIX_POLL_SRC) \
|
$(POSIX_POLL_SRC) \
|
||||||
os/threads_posix.c os/threads_windows.c \
|
os/threads_posix.c os/threads_windows.c \
|
||||||
os/linux_udev.c os/linux_netlink.c
|
os/linux_udev.c os/linux_netlink.c
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
cp -r os/haiku $(distdir)/os/haiku
|
||||||
|
rm -rf $(distdir)/os/haiku/autom4te.cache
|
||||||
|
|
||||||
if OS_LINUX
|
if OS_LINUX
|
||||||
|
|
||||||
if USE_UDEV
|
if USE_UDEV
|
||||||
|
@ -43,6 +49,11 @@ if OS_NETBSD
|
||||||
OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC)
|
OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if OS_HAIKU
|
||||||
|
OS_SRC = $(POSIX_POLL_SRC)
|
||||||
|
SUBDIRS = os/haiku
|
||||||
|
endif
|
||||||
|
|
||||||
if OS_WINDOWS
|
if OS_WINDOWS
|
||||||
OS_SRC = $(WINDOWS_USB_SRC)
|
OS_SRC = $(WINDOWS_USB_SRC)
|
||||||
|
|
||||||
|
@ -71,5 +82,9 @@ libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
|
||||||
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
|
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
|
||||||
os/poll_posix.h os/poll_windows.h
|
os/poll_posix.h os/poll_windows.h
|
||||||
|
|
||||||
|
if OS_HAIKU
|
||||||
|
libusb_1_0_la_LIBADD = os/haiku/libhaikuusb.la
|
||||||
|
endif
|
||||||
|
|
||||||
hdrdir = $(includedir)/libusb-1.0
|
hdrdir = $(includedir)/libusb-1.0
|
||||||
hdr_HEADERS = libusb.h
|
hdr_HEADERS = libusb.h
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Makefile.in generated by automake 1.14.1 from Makefile.am.
|
# Makefile.in generated by automake 1.15 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# This Makefile.in is free software; the Free Software Foundation
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
@ -16,7 +16,17 @@
|
||||||
|
|
||||||
|
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
|
am__is_gnu_make = { \
|
||||||
|
if test -z '$(MAKELEVEL)'; then \
|
||||||
|
false; \
|
||||||
|
elif test -n '$(MAKE_HOST)'; then \
|
||||||
|
true; \
|
||||||
|
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
am__make_running_with_option = \
|
am__make_running_with_option = \
|
||||||
case $${target_option-} in \
|
case $${target_option-} in \
|
||||||
?) ;; \
|
?) ;; \
|
||||||
|
@ -80,8 +90,6 @@ POST_UNINSTALL = :
|
||||||
build_triplet = @build@
|
build_triplet = @build@
|
||||||
host_triplet = @host@
|
host_triplet = @host@
|
||||||
subdir = libusb
|
subdir = libusb
|
||||||
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
|
||||||
$(top_srcdir)/depcomp $(hdr_HEADERS)
|
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||||
|
@ -89,6 +97,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||||
$(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
|
$(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
$(ACLOCAL_M4)
|
$(ACLOCAL_M4)
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(hdr_HEADERS) $(am__DIST_COMMON)
|
||||||
mkinstalldirs = $(install_sh) -d
|
mkinstalldirs = $(install_sh) -d
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
CONFIG_HEADER = $(top_builddir)/config.h
|
||||||
CONFIG_CLEAN_FILES =
|
CONFIG_CLEAN_FILES =
|
||||||
|
@ -122,7 +131,7 @@ am__uninstall_files_from_dir = { \
|
||||||
}
|
}
|
||||||
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
|
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
|
||||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||||
libusb_1_0_la_LIBADD =
|
@OS_HAIKU_TRUE@libusb_1_0_la_DEPENDENCIES = os/haiku/libhaikuusb.la
|
||||||
am__libusb_1_0_la_SOURCES_DIST = libusbi.h core.c descriptor.c io.c \
|
am__libusb_1_0_la_SOURCES_DIST = libusbi.h core.c descriptor.c io.c \
|
||||||
strerror.c sync.c os/linux_usbfs.h os/darwin_usb.h \
|
strerror.c sync.c os/linux_usbfs.h os/darwin_usb.h \
|
||||||
os/windows_usb.h os/windows_common.h hotplug.h hotplug.c \
|
os/windows_usb.h os/windows_common.h hotplug.h hotplug.c \
|
||||||
|
@ -143,17 +152,18 @@ am__objects_5 = os/libusb_1_0_la-netbsd_usb.lo
|
||||||
am__objects_6 = os/libusb_1_0_la-openbsd_usb.lo
|
am__objects_6 = os/libusb_1_0_la-openbsd_usb.lo
|
||||||
am__objects_7 = os/libusb_1_0_la-poll_windows.lo \
|
am__objects_7 = os/libusb_1_0_la-poll_windows.lo \
|
||||||
os/libusb_1_0_la-windows_usb.lo libusb-1.0.lo
|
os/libusb_1_0_la-windows_usb.lo libusb-1.0.lo
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_WINDOWS_TRUE@am__objects_8 = $(am__objects_7)
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_WINDOWS_TRUE@am__objects_8 = $(am__objects_7)
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@am__objects_8 = $(am__objects_6) \
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@am__objects_8 = $(am__objects_6) \
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@ $(am__objects_3)
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@ $(am__objects_3)
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@am__objects_8 = $(am__objects_5) \
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@am__objects_8 = $(am__objects_5) \
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@ $(am__objects_3)
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@ $(am__objects_3)
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_8 = $(am__objects_4) \
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_8 = $(am__objects_4) \
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ $(am__objects_3) \
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ $(am__objects_3) \
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/libusb_1_0_la-linux_netlink.lo
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/libusb_1_0_la-linux_netlink.lo
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@am__objects_8 = $(am__objects_4) \
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@am__objects_8 = $(am__objects_4) \
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ $(am__objects_3) \
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ $(am__objects_3) \
|
||||||
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/libusb_1_0_la-linux_udev.lo
|
@OS_DARWIN_FALSE@@OS_HAIKU_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/libusb_1_0_la-linux_udev.lo
|
||||||
|
@OS_DARWIN_FALSE@@OS_HAIKU_TRUE@am__objects_8 = $(am__objects_3)
|
||||||
@OS_DARWIN_TRUE@am__objects_8 = $(am__objects_2) $(am__objects_3)
|
@OS_DARWIN_TRUE@am__objects_8 = $(am__objects_2) $(am__objects_3)
|
||||||
am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
|
am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
|
||||||
libusb_1_0_la-descriptor.lo libusb_1_0_la-io.lo \
|
libusb_1_0_la-descriptor.lo libusb_1_0_la-io.lo \
|
||||||
|
@ -203,12 +213,28 @@ am__v_CCLD_0 = @echo " CCLD " $@;
|
||||||
am__v_CCLD_1 =
|
am__v_CCLD_1 =
|
||||||
SOURCES = $(libusb_1_0_la_SOURCES)
|
SOURCES = $(libusb_1_0_la_SOURCES)
|
||||||
DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST)
|
DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST)
|
||||||
|
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||||
|
ctags-recursive dvi-recursive html-recursive info-recursive \
|
||||||
|
install-data-recursive install-dvi-recursive \
|
||||||
|
install-exec-recursive install-html-recursive \
|
||||||
|
install-info-recursive install-pdf-recursive \
|
||||||
|
install-ps-recursive install-recursive installcheck-recursive \
|
||||||
|
installdirs-recursive pdf-recursive ps-recursive \
|
||||||
|
tags-recursive uninstall-recursive
|
||||||
am__can_run_installinfo = \
|
am__can_run_installinfo = \
|
||||||
case $$AM_UPDATE_INFO_DIR in \
|
case $$AM_UPDATE_INFO_DIR in \
|
||||||
n|no|NO) false;; \
|
n|no|NO) false;; \
|
||||||
*) (install-info --version) >/dev/null 2>&1;; \
|
*) (install-info --version) >/dev/null 2>&1;; \
|
||||||
esac
|
esac
|
||||||
HEADERS = $(hdr_HEADERS)
|
HEADERS = $(hdr_HEADERS)
|
||||||
|
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||||
|
distclean-recursive maintainer-clean-recursive
|
||||||
|
am__recursive_targets = \
|
||||||
|
$(RECURSIVE_TARGETS) \
|
||||||
|
$(RECURSIVE_CLEAN_TARGETS) \
|
||||||
|
$(am__extra_recursive_targets)
|
||||||
|
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||||
|
distdir
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||||
# Read a list of newline-separated strings from the standard input,
|
# Read a list of newline-separated strings from the standard input,
|
||||||
# and print each of them once, without duplicates. Input order is
|
# and print each of them once, without duplicates. Input order is
|
||||||
|
@ -228,7 +254,33 @@ am__define_uniq_tagged_files = \
|
||||||
done | $(am__uniquify_input)`
|
done | $(am__uniquify_input)`
|
||||||
ETAGS = etags
|
ETAGS = etags
|
||||||
CTAGS = ctags
|
CTAGS = ctags
|
||||||
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
am__relativize = \
|
||||||
|
dir0=`pwd`; \
|
||||||
|
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||||
|
sed_rest='s,^[^/]*/*,,'; \
|
||||||
|
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||||
|
sed_butlast='s,/*[^/]*$$,,'; \
|
||||||
|
while test -n "$$dir1"; do \
|
||||||
|
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||||
|
if test "$$first" != "."; then \
|
||||||
|
if test "$$first" = ".."; then \
|
||||||
|
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||||
|
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||||
|
else \
|
||||||
|
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||||
|
if test "$$first2" = "$$first"; then \
|
||||||
|
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||||
|
else \
|
||||||
|
dir2="../$$dir2"; \
|
||||||
|
fi; \
|
||||||
|
dir0="$$dir0"/"$$first"; \
|
||||||
|
fi; \
|
||||||
|
fi; \
|
||||||
|
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||||
|
done; \
|
||||||
|
reldir="$$dir2"
|
||||||
ACLOCAL = @ACLOCAL@
|
ACLOCAL = @ACLOCAL@
|
||||||
AMTAR = @AMTAR@
|
AMTAR = @AMTAR@
|
||||||
AM_CFLAGS = @AM_CFLAGS@
|
AM_CFLAGS = @AM_CFLAGS@
|
||||||
|
@ -279,6 +331,7 @@ NMEDIT = @NMEDIT@
|
||||||
OBJDUMP = @OBJDUMP@
|
OBJDUMP = @OBJDUMP@
|
||||||
OBJEXT = @OBJEXT@
|
OBJEXT = @OBJEXT@
|
||||||
OS_DARWIN = @OS_DARWIN@
|
OS_DARWIN = @OS_DARWIN@
|
||||||
|
OS_HAIKU = @OS_HAIKU@
|
||||||
OS_LINUX = @OS_LINUX@
|
OS_LINUX = @OS_LINUX@
|
||||||
OS_NETBSD = @OS_NETBSD@
|
OS_NETBSD = @OS_NETBSD@
|
||||||
OS_OPENBSD = @OS_OPENBSD@
|
OS_OPENBSD = @OS_OPENBSD@
|
||||||
|
@ -348,6 +401,7 @@ psdir = @psdir@
|
||||||
sbindir = @sbindir@
|
sbindir = @sbindir@
|
||||||
sharedstatedir = @sharedstatedir@
|
sharedstatedir = @sharedstatedir@
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
|
subdirs = @subdirs@
|
||||||
sysconfdir = @sysconfdir@
|
sysconfdir = @sysconfdir@
|
||||||
target_alias = @target_alias@
|
target_alias = @target_alias@
|
||||||
top_build_prefix = @top_build_prefix@
|
top_build_prefix = @top_build_prefix@
|
||||||
|
@ -362,6 +416,7 @@ OPENBSD_USB_SRC = os/openbsd_usb.c
|
||||||
NETBSD_USB_SRC = os/netbsd_usb.c
|
NETBSD_USB_SRC = os/netbsd_usb.c
|
||||||
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
|
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
|
||||||
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
|
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
|
||||||
|
DIST_SUBDIRS =
|
||||||
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
|
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
|
||||||
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
|
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
|
||||||
$(POSIX_POLL_SRC) \
|
$(POSIX_POLL_SRC) \
|
||||||
|
@ -369,6 +424,7 @@ EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
|
||||||
os/linux_udev.c os/linux_netlink.c
|
os/linux_udev.c os/linux_netlink.c
|
||||||
|
|
||||||
@OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
|
@OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
|
||||||
|
@OS_HAIKU_TRUE@OS_SRC = $(POSIX_POLL_SRC)
|
||||||
@OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
|
@OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
|
||||||
@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/linux_netlink.c
|
@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/linux_netlink.c
|
||||||
|
|
||||||
|
@ -379,6 +435,7 @@ EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
|
||||||
@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
|
@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
|
||||||
@OS_WINDOWS_TRUE@OS_SRC = $(WINDOWS_USB_SRC)
|
@OS_WINDOWS_TRUE@OS_SRC = $(WINDOWS_USB_SRC)
|
||||||
@OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp
|
@OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp
|
||||||
|
@OS_HAIKU_TRUE@SUBDIRS = os/haiku
|
||||||
@THREADS_POSIX_FALSE@THREADS_SRC = os/threads_windows.h os/threads_windows.c
|
@THREADS_POSIX_FALSE@THREADS_SRC = os/threads_windows.h os/threads_windows.c
|
||||||
@THREADS_POSIX_TRUE@THREADS_SRC = os/threads_posix.h os/threads_posix.c
|
@THREADS_POSIX_TRUE@THREADS_SRC = os/threads_posix.h os/threads_posix.c
|
||||||
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
|
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
@ -388,9 +445,10 @@ libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
|
||||||
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
|
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
|
||||||
os/poll_posix.h os/poll_windows.h
|
os/poll_posix.h os/poll_windows.h
|
||||||
|
|
||||||
|
@OS_HAIKU_TRUE@libusb_1_0_la_LIBADD = os/haiku/libhaikuusb.la
|
||||||
hdrdir = $(includedir)/libusb-1.0
|
hdrdir = $(includedir)/libusb-1.0
|
||||||
hdr_HEADERS = libusb.h
|
hdr_HEADERS = libusb.h
|
||||||
all: all-am
|
all: all-recursive
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .c .lo .o .obj .rc
|
.SUFFIXES: .c .lo .o .obj .rc
|
||||||
|
@ -406,7 +464,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
|
||||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
|
||||||
$(am__cd) $(top_srcdir) && \
|
$(am__cd) $(top_srcdir) && \
|
||||||
$(AUTOMAKE) --gnu libusb/Makefile
|
$(AUTOMAKE) --gnu libusb/Makefile
|
||||||
.PRECIOUS: Makefile
|
|
||||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
@case '$?' in \
|
@case '$?' in \
|
||||||
*config.status*) \
|
*config.status*) \
|
||||||
|
@ -688,14 +745,61 @@ uninstall-hdrHEADERS:
|
||||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
|
dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
|
||||||
|
|
||||||
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
|
# into them and run 'make' without going through this Makefile.
|
||||||
|
# To change the values of 'make' variables: instead of editing Makefiles,
|
||||||
|
# (1) if the variable is set in 'config.status', edit 'config.status'
|
||||||
|
# (which will cause the Makefiles to be regenerated when you run 'make');
|
||||||
|
# (2) otherwise, pass the desired values on the 'make' command line.
|
||||||
|
$(am__recursive_targets):
|
||||||
|
@fail=; \
|
||||||
|
if $(am__make_keepgoing); then \
|
||||||
|
failcom='fail=yes'; \
|
||||||
|
else \
|
||||||
|
failcom='exit 1'; \
|
||||||
|
fi; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
for subdir in $$list; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
dot_seen=yes; \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| eval $$failcom; \
|
||||||
|
done; \
|
||||||
|
if test "$$dot_seen" = "no"; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||||
|
fi; test -z "$$fail"
|
||||||
|
|
||||||
ID: $(am__tagged_files)
|
ID: $(am__tagged_files)
|
||||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||||
tags: tags-am
|
tags: tags-recursive
|
||||||
TAGS: tags
|
TAGS: tags
|
||||||
|
|
||||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
set x; \
|
set x; \
|
||||||
here=`pwd`; \
|
here=`pwd`; \
|
||||||
|
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||||
|
include_option=--etags-include; \
|
||||||
|
empty_fix=.; \
|
||||||
|
else \
|
||||||
|
include_option=--include; \
|
||||||
|
empty_fix=; \
|
||||||
|
fi; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test ! -f $$subdir/TAGS || \
|
||||||
|
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
$(am__define_uniq_tagged_files); \
|
$(am__define_uniq_tagged_files); \
|
||||||
shift; \
|
shift; \
|
||||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||||
|
@ -708,7 +812,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
$$unique; \
|
$$unique; \
|
||||||
fi; \
|
fi; \
|
||||||
fi
|
fi
|
||||||
ctags: ctags-am
|
ctags: ctags-recursive
|
||||||
|
|
||||||
CTAGS: ctags
|
CTAGS: ctags
|
||||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
@ -721,7 +825,7 @@ GTAGS:
|
||||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
&& $(am__cd) $(top_srcdir) \
|
&& $(am__cd) $(top_srcdir) \
|
||||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||||
cscopelist: cscopelist-am
|
cscopelist: cscopelist-recursive
|
||||||
|
|
||||||
cscopelist-am: $(am__tagged_files)
|
cscopelist-am: $(am__tagged_files)
|
||||||
list='$(am__tagged_files)'; \
|
list='$(am__tagged_files)'; \
|
||||||
|
@ -770,22 +874,51 @@ distdir: $(DISTFILES)
|
||||||
|| exit 1; \
|
|| exit 1; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
|
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
$(am__make_dryrun) \
|
||||||
|
|| test -d "$(distdir)/$$subdir" \
|
||||||
|
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||||
|
|| exit 1; \
|
||||||
|
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||||
|
$(am__relativize); \
|
||||||
|
new_distdir=$$reldir; \
|
||||||
|
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||||
|
$(am__relativize); \
|
||||||
|
new_top_distdir=$$reldir; \
|
||||||
|
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||||
|
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||||
|
($(am__cd) $$subdir && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$$new_top_distdir" \
|
||||||
|
distdir="$$new_distdir" \
|
||||||
|
am__remove_distdir=: \
|
||||||
|
am__skip_length_check=: \
|
||||||
|
am__skip_mode_fix=: \
|
||||||
|
distdir) \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||||
|
dist-hook
|
||||||
check-am: all-am
|
check-am: all-am
|
||||||
check: check-am
|
check: check-recursive
|
||||||
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
|
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
|
||||||
installdirs:
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
|
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
|
||||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||||
done
|
done
|
||||||
install: install-am
|
install: install-recursive
|
||||||
install-exec: install-exec-am
|
install-exec: install-exec-recursive
|
||||||
install-data: install-data-am
|
install-data: install-data-recursive
|
||||||
uninstall: uninstall-am
|
uninstall: uninstall-recursive
|
||||||
|
|
||||||
install-am: all-am
|
install-am: all-am
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
installcheck: installcheck-am
|
installcheck: installcheck-recursive
|
||||||
install-strip:
|
install-strip:
|
||||||
if test -z '$(STRIP)'; then \
|
if test -z '$(STRIP)'; then \
|
||||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
@ -809,97 +942,103 @@ distclean-generic:
|
||||||
maintainer-clean-generic:
|
maintainer-clean-generic:
|
||||||
@echo "This command is intended for maintainers to use"
|
@echo "This command is intended for maintainers to use"
|
||||||
@echo "it deletes files that may require special tools to rebuild."
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
clean: clean-am
|
clean: clean-recursive
|
||||||
|
|
||||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||||
mostlyclean-am
|
mostlyclean-am
|
||||||
|
|
||||||
distclean: distclean-am
|
distclean: distclean-recursive
|
||||||
-rm -rf ./$(DEPDIR) os/$(DEPDIR)
|
-rm -rf ./$(DEPDIR) os/$(DEPDIR)
|
||||||
-rm -f Makefile
|
-rm -f Makefile
|
||||||
distclean-am: clean-am distclean-compile distclean-generic \
|
distclean-am: clean-am distclean-compile distclean-generic \
|
||||||
distclean-tags
|
distclean-tags
|
||||||
|
|
||||||
dvi: dvi-am
|
dvi: dvi-recursive
|
||||||
|
|
||||||
dvi-am:
|
dvi-am:
|
||||||
|
|
||||||
html: html-am
|
html: html-recursive
|
||||||
|
|
||||||
html-am:
|
html-am:
|
||||||
|
|
||||||
info: info-am
|
info: info-recursive
|
||||||
|
|
||||||
info-am:
|
info-am:
|
||||||
|
|
||||||
install-data-am: install-hdrHEADERS
|
install-data-am: install-hdrHEADERS
|
||||||
|
|
||||||
install-dvi: install-dvi-am
|
install-dvi: install-dvi-recursive
|
||||||
|
|
||||||
install-dvi-am:
|
install-dvi-am:
|
||||||
|
|
||||||
install-exec-am: install-libLTLIBRARIES
|
install-exec-am: install-libLTLIBRARIES
|
||||||
|
|
||||||
install-html: install-html-am
|
install-html: install-html-recursive
|
||||||
|
|
||||||
install-html-am:
|
install-html-am:
|
||||||
|
|
||||||
install-info: install-info-am
|
install-info: install-info-recursive
|
||||||
|
|
||||||
install-info-am:
|
install-info-am:
|
||||||
|
|
||||||
install-man:
|
install-man:
|
||||||
|
|
||||||
install-pdf: install-pdf-am
|
install-pdf: install-pdf-recursive
|
||||||
|
|
||||||
install-pdf-am:
|
install-pdf-am:
|
||||||
|
|
||||||
install-ps: install-ps-am
|
install-ps: install-ps-recursive
|
||||||
|
|
||||||
install-ps-am:
|
install-ps-am:
|
||||||
|
|
||||||
installcheck-am:
|
installcheck-am:
|
||||||
|
|
||||||
maintainer-clean: maintainer-clean-am
|
maintainer-clean: maintainer-clean-recursive
|
||||||
-rm -rf ./$(DEPDIR) os/$(DEPDIR)
|
-rm -rf ./$(DEPDIR) os/$(DEPDIR)
|
||||||
-rm -f Makefile
|
-rm -f Makefile
|
||||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
mostlyclean: mostlyclean-am
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||||
mostlyclean-libtool
|
mostlyclean-libtool
|
||||||
|
|
||||||
pdf: pdf-am
|
pdf: pdf-recursive
|
||||||
|
|
||||||
pdf-am:
|
pdf-am:
|
||||||
|
|
||||||
ps: ps-am
|
ps: ps-recursive
|
||||||
|
|
||||||
ps-am:
|
ps-am:
|
||||||
|
|
||||||
uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
|
uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
|
||||||
|
|
||||||
.MAKE: install-am install-strip
|
.MAKE: $(am__recursive_targets) install-am install-strip
|
||||||
|
|
||||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
|
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
|
||||||
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
|
check-am clean clean-generic clean-libLTLIBRARIES \
|
||||||
ctags-am distclean distclean-compile distclean-generic \
|
clean-libtool cscopelist-am ctags ctags-am dist-hook distclean \
|
||||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
distclean-compile distclean-generic distclean-libtool \
|
||||||
html-am info info-am install install-am install-data \
|
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||||
install-data-am install-dvi install-dvi-am install-exec \
|
install install-am install-data install-data-am install-dvi \
|
||||||
install-exec-am install-hdrHEADERS install-html \
|
install-dvi-am install-exec install-exec-am install-hdrHEADERS \
|
||||||
install-html-am install-info install-info-am \
|
install-html install-html-am install-info install-info-am \
|
||||||
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
|
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
|
||||||
install-ps install-ps-am install-strip installcheck \
|
install-ps install-ps-am install-strip installcheck \
|
||||||
installcheck-am installdirs maintainer-clean \
|
installcheck-am installdirs installdirs-am maintainer-clean \
|
||||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||||
tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
|
tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
|
||||||
uninstall-libLTLIBRARIES
|
uninstall-libLTLIBRARIES
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
all: libusb-1.0.la libusb-1.0.dll
|
all: libusb-1.0.la libusb-1.0.dll
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
cp -r os/haiku $(distdir)/os/haiku
|
||||||
|
rm -rf $(distdir)/os/haiku/autom4te.cache
|
||||||
|
|
||||||
@OS_WINDOWS_TRUE@.rc.lo:
|
@OS_WINDOWS_TRUE@.rc.lo:
|
||||||
@OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
|
@OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ const struct usbi_os_backend * const usbi_backend = &netbsd_backend;
|
||||||
const struct usbi_os_backend * const usbi_backend = &windows_backend;
|
const struct usbi_os_backend * const usbi_backend = &windows_backend;
|
||||||
#elif defined(OS_WINCE)
|
#elif defined(OS_WINCE)
|
||||||
const struct usbi_os_backend * const usbi_backend = &wince_backend;
|
const struct usbi_os_backend * const usbi_backend = &wince_backend;
|
||||||
|
#elif defined(OS_HAIKU)
|
||||||
|
const struct usbi_os_backend * const usbi_backend = &haiku_usb_raw_backend;
|
||||||
#else
|
#else
|
||||||
#error "Unsupported OS"
|
#error "Unsupported OS"
|
||||||
#endif
|
#endif
|
||||||
|
@ -92,6 +94,10 @@ struct list_head active_contexts_list;
|
||||||
* Specification</a> which is available for free download. You can probably
|
* Specification</a> which is available for free download. You can probably
|
||||||
* find less verbose introductions by searching the web.
|
* find less verbose introductions by searching the web.
|
||||||
*
|
*
|
||||||
|
* \section API Application Programming Interface (API)
|
||||||
|
*
|
||||||
|
* See the \ref api page for a complete list of the libusb functions.
|
||||||
|
*
|
||||||
* \section features Library features
|
* \section features Library features
|
||||||
*
|
*
|
||||||
* - All transfer types supported (control/bulk/interrupt/isochronous)
|
* - All transfer types supported (control/bulk/interrupt/isochronous)
|
||||||
|
@ -217,9 +223,6 @@ struct list_head active_contexts_list;
|
||||||
* -# If the device is already in the desired configuration, calling
|
* -# If the device is already in the desired configuration, calling
|
||||||
* libusb_set_configuration() using the same configuration value will cause
|
* libusb_set_configuration() using the same configuration value will cause
|
||||||
* a lightweight device reset. This may not be desirable behaviour.
|
* a lightweight device reset. This may not be desirable behaviour.
|
||||||
* -# libusb will be unable to change configuration if the device is in
|
|
||||||
* another configuration and other programs or drivers have claimed
|
|
||||||
* interfaces under that configuration.
|
|
||||||
* -# In the case where the desired configuration is already active, libusb
|
* -# In the case where the desired configuration is already active, libusb
|
||||||
* may not even be able to perform a lightweight device reset. For example,
|
* may not even be able to perform a lightweight device reset. For example,
|
||||||
* take my USB keyboard with fingerprint reader: I'm interested in driving
|
* take my USB keyboard with fingerprint reader: I'm interested in driving
|
||||||
|
@ -228,12 +231,17 @@ struct list_head active_contexts_list;
|
||||||
* Because the kernel has claimed an interface, it is not even possible to
|
* Because the kernel has claimed an interface, it is not even possible to
|
||||||
* perform the lightweight device reset, so libusb_set_configuration() will
|
* perform the lightweight device reset, so libusb_set_configuration() will
|
||||||
* fail. (Luckily the device in question only has a single configuration.)
|
* fail. (Luckily the device in question only has a single configuration.)
|
||||||
|
* -# libusb will be unable to set a configuration if other programs or
|
||||||
|
* drivers have claimed interfaces. In particular, this means that kernel
|
||||||
|
* drivers must be detached from all the interfaces before
|
||||||
|
* libusb_set_configuration() may succeed.
|
||||||
*
|
*
|
||||||
* One solution to some of the above problems is to consider the currently
|
* One solution to some of the above problems is to consider the currently
|
||||||
* active configuration. If the configuration we want is already active, then
|
* active configuration. If the configuration we want is already active, then
|
||||||
* we don't have to select any configuration:
|
* we don't have to select any configuration:
|
||||||
\code
|
\code
|
||||||
cfg = libusb_get_configuration(dev);
|
cfg = -1;
|
||||||
|
libusb_get_configuration(dev, &cfg);
|
||||||
if (cfg != desired)
|
if (cfg != desired)
|
||||||
libusb_set_configuration(dev, desired);
|
libusb_set_configuration(dev, desired);
|
||||||
\endcode
|
\endcode
|
||||||
|
@ -323,6 +331,151 @@ if (cfg != desired)
|
||||||
* can infer the context from those objects.
|
* can infer the context from those objects.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page api Application Programming Interface
|
||||||
|
*
|
||||||
|
* This is the complete list of libusb functions, structures and
|
||||||
|
* enumerations in alphabetical order.
|
||||||
|
*
|
||||||
|
* \section Functions
|
||||||
|
* - libusb_alloc_streams()
|
||||||
|
* - libusb_alloc_transfer()
|
||||||
|
* - libusb_attach_kernel_driver()
|
||||||
|
* - libusb_bulk_transfer()
|
||||||
|
* - libusb_cancel_transfer()
|
||||||
|
* - libusb_claim_interface()
|
||||||
|
* - libusb_clear_halt()
|
||||||
|
* - libusb_close()
|
||||||
|
* - libusb_control_transfer()
|
||||||
|
* - libusb_control_transfer_get_data()
|
||||||
|
* - libusb_control_transfer_get_setup()
|
||||||
|
* - libusb_cpu_to_le16()
|
||||||
|
* - libusb_detach_kernel_driver()
|
||||||
|
* - libusb_error_name()
|
||||||
|
* - libusb_event_handler_active()
|
||||||
|
* - libusb_event_handling_ok()
|
||||||
|
* - libusb_exit()
|
||||||
|
* - libusb_fill_bulk_stream_transfer()
|
||||||
|
* - libusb_fill_bulk_transfer()
|
||||||
|
* - libusb_fill_control_setup()
|
||||||
|
* - libusb_fill_control_transfer()
|
||||||
|
* - libusb_fill_interrupt_transfer()
|
||||||
|
* - libusb_fill_iso_transfer()
|
||||||
|
* - libusb_free_bos_descriptor()
|
||||||
|
* - libusb_free_config_descriptor()
|
||||||
|
* - libusb_free_container_id_descriptor()
|
||||||
|
* - libusb_free_device_list()
|
||||||
|
* - libusb_free_ss_endpoint_companion_descriptor()
|
||||||
|
* - libusb_free_ss_usb_device_capability_descriptor()
|
||||||
|
* - libusb_free_streams()
|
||||||
|
* - libusb_free_transfer()
|
||||||
|
* - libusb_free_usb_2_0_extension_descriptor()
|
||||||
|
* - libusb_get_active_config_descriptor()
|
||||||
|
* - libusb_get_bos_descriptor()
|
||||||
|
* - libusb_get_bus_number()
|
||||||
|
* - libusb_get_config_descriptor()
|
||||||
|
* - libusb_get_config_descriptor_by_value()
|
||||||
|
* - libusb_get_configuration()
|
||||||
|
* - libusb_get_container_id_descriptor()
|
||||||
|
* - libusb_get_descriptor()
|
||||||
|
* - libusb_get_device()
|
||||||
|
* - libusb_get_device_address()
|
||||||
|
* - libusb_get_device_descriptor()
|
||||||
|
* - libusb_get_device_list()
|
||||||
|
* - libusb_get_device_speed()
|
||||||
|
* - libusb_get_iso_packet_buffer()
|
||||||
|
* - libusb_get_iso_packet_buffer_simple()
|
||||||
|
* - libusb_get_max_iso_packet_size()
|
||||||
|
* - libusb_get_max_packet_size()
|
||||||
|
* - libusb_get_next_timeout()
|
||||||
|
* - libusb_get_parent()
|
||||||
|
* - libusb_get_port_number()
|
||||||
|
* - libusb_get_port_numbers()
|
||||||
|
* - libusb_get_ss_endpoint_companion_descriptor()
|
||||||
|
* - libusb_get_ss_usb_device_capability_descriptor()
|
||||||
|
* - libusb_get_string_descriptor()
|
||||||
|
* - libusb_get_string_descriptor_ascii()
|
||||||
|
* - libusb_get_usb_2_0_extension_descriptor()
|
||||||
|
* - libusb_get_version()
|
||||||
|
* - libusb_handle_events()
|
||||||
|
* - libusb_handle_events_completed()
|
||||||
|
* - libusb_handle_events_locked()
|
||||||
|
* - libusb_handle_events_timeout()
|
||||||
|
* - libusb_handle_events_timeout_completed()
|
||||||
|
* - libusb_has_capability()
|
||||||
|
* - libusb_hotplug_deregister_callback()
|
||||||
|
* - libusb_hotplug_register_callback()
|
||||||
|
* - libusb_init()
|
||||||
|
* - libusb_interrupt_transfer()
|
||||||
|
* - libusb_kernel_driver_active()
|
||||||
|
* - libusb_lock_events()
|
||||||
|
* - libusb_lock_event_waiters()
|
||||||
|
* - libusb_open()
|
||||||
|
* - libusb_open_device_with_vid_pid()
|
||||||
|
* - libusb_pollfds_handle_timeouts()
|
||||||
|
* - libusb_ref_device()
|
||||||
|
* - libusb_release_interface()
|
||||||
|
* - libusb_reset_device()
|
||||||
|
* - libusb_set_auto_detach_kernel_driver()
|
||||||
|
* - libusb_set_configuration()
|
||||||
|
* - libusb_set_debug()
|
||||||
|
* - libusb_set_interface_alt_setting()
|
||||||
|
* - libusb_set_iso_packet_lengths()
|
||||||
|
* - libusb_setlocale()
|
||||||
|
* - libusb_set_pollfd_notifiers()
|
||||||
|
* - libusb_strerror()
|
||||||
|
* - libusb_submit_transfer()
|
||||||
|
* - libusb_transfer_get_stream_id()
|
||||||
|
* - libusb_transfer_set_stream_id()
|
||||||
|
* - libusb_try_lock_events()
|
||||||
|
* - libusb_unlock_events()
|
||||||
|
* - libusb_unlock_event_waiters()
|
||||||
|
* - libusb_unref_device()
|
||||||
|
* - libusb_wait_for_event()
|
||||||
|
*
|
||||||
|
* \section Structures
|
||||||
|
* - libusb_bos_descriptor
|
||||||
|
* - libusb_bos_dev_capability_descriptor
|
||||||
|
* - libusb_config_descriptor
|
||||||
|
* - libusb_container_id_descriptor
|
||||||
|
* - \ref libusb_context
|
||||||
|
* - libusb_control_setup
|
||||||
|
* - \ref libusb_device
|
||||||
|
* - libusb_device_descriptor
|
||||||
|
* - \ref libusb_device_handle
|
||||||
|
* - libusb_endpoint_descriptor
|
||||||
|
* - libusb_interface
|
||||||
|
* - libusb_interface_descriptor
|
||||||
|
* - libusb_iso_packet_descriptor
|
||||||
|
* - libusb_pollfd
|
||||||
|
* - libusb_ss_endpoint_companion_descriptor
|
||||||
|
* - libusb_ss_usb_device_capability_descriptor
|
||||||
|
* - libusb_transfer
|
||||||
|
* - libusb_usb_2_0_extension_descriptor
|
||||||
|
* - libusb_version
|
||||||
|
*
|
||||||
|
* \section Enums
|
||||||
|
* - \ref libusb_bos_type
|
||||||
|
* - \ref libusb_capability
|
||||||
|
* - \ref libusb_class_code
|
||||||
|
* - \ref libusb_descriptor_type
|
||||||
|
* - \ref libusb_endpoint_direction
|
||||||
|
* - \ref libusb_error
|
||||||
|
* - \ref libusb_iso_sync_type
|
||||||
|
* - \ref libusb_iso_usage_type
|
||||||
|
* - \ref libusb_log_level
|
||||||
|
* - \ref libusb_request_recipient
|
||||||
|
* - \ref libusb_request_type
|
||||||
|
* - \ref libusb_speed
|
||||||
|
* - \ref libusb_ss_usb_device_capability_attributes
|
||||||
|
* - \ref libusb_standard_request
|
||||||
|
* - \ref libusb_supported_speed
|
||||||
|
* - \ref libusb_transfer_flags
|
||||||
|
* - \ref libusb_transfer_status
|
||||||
|
* - \ref libusb_transfer_type
|
||||||
|
* - \ref libusb_usb_2_0_extension_attributes
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup lib Library initialization/deinitialization
|
* @defgroup lib Library initialization/deinitialization
|
||||||
* This page details how to initialize and deinitialize libusb. Initialization
|
* This page details how to initialize and deinitialize libusb. Initialization
|
||||||
|
@ -533,12 +686,8 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
|
||||||
|
|
||||||
void usbi_connect_device(struct libusb_device *dev)
|
void usbi_connect_device(struct libusb_device *dev)
|
||||||
{
|
{
|
||||||
libusb_hotplug_message message;
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
memset(&message, 0, sizeof(message));
|
|
||||||
message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
|
|
||||||
message.device = dev;
|
|
||||||
dev->attached = 1;
|
dev->attached = 1;
|
||||||
|
|
||||||
usbi_mutex_lock(&dev->ctx->usb_devs_lock);
|
usbi_mutex_lock(&dev->ctx->usb_devs_lock);
|
||||||
|
@ -546,25 +695,17 @@ void usbi_connect_device(struct libusb_device *dev)
|
||||||
usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
|
usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
|
||||||
|
|
||||||
/* Signal that an event has occurred for this device if we support hotplug AND
|
/* Signal that an event has occurred for this device if we support hotplug AND
|
||||||
* the hotplug pipe is ready. This prevents an event from getting raised during
|
* the hotplug message list is ready. This prevents an event from getting raised
|
||||||
* initial enumeration. */
|
* during initial enumeration. */
|
||||||
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) {
|
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) {
|
||||||
ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message));
|
usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
|
||||||
if (sizeof (message) != ret) {
|
|
||||||
usbi_err(DEVICE_CTX(dev), "error writing hotplug message");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbi_disconnect_device(struct libusb_device *dev)
|
void usbi_disconnect_device(struct libusb_device *dev)
|
||||||
{
|
{
|
||||||
libusb_hotplug_message message;
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
||||||
struct libusb_context *ctx = dev->ctx;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
memset(&message, 0, sizeof(message));
|
|
||||||
message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
|
|
||||||
message.device = dev;
|
|
||||||
usbi_mutex_lock(&dev->lock);
|
usbi_mutex_lock(&dev->lock);
|
||||||
dev->attached = 0;
|
dev->attached = 0;
|
||||||
usbi_mutex_unlock(&dev->lock);
|
usbi_mutex_unlock(&dev->lock);
|
||||||
|
@ -574,14 +715,11 @@ void usbi_disconnect_device(struct libusb_device *dev)
|
||||||
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
||||||
|
|
||||||
/* Signal that an event has occurred for this device if we support hotplug AND
|
/* Signal that an event has occurred for this device if we support hotplug AND
|
||||||
* the hotplug pipe is ready. This prevents an event from getting raised during
|
* the hotplug message list is ready. This prevents an event from getting raised
|
||||||
* initial enumeration. libusb_handle_events will take care of dereferencing the
|
* during initial enumeration. libusb_handle_events will take care of dereferencing
|
||||||
* device. */
|
* the device. */
|
||||||
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) {
|
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) {
|
||||||
ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message));
|
usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
|
||||||
if (sizeof(message) != ret) {
|
|
||||||
usbi_err(DEVICE_CTX(dev), "error writing hotplug message");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,47 +1159,41 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupt the iteration of the event handling thread, so that it picks
|
* Signal the event pipe so that the event handling thread will be
|
||||||
* up the new fd.
|
* interrupted to process an internal event.
|
||||||
*/
|
*/
|
||||||
void usbi_fd_notification(struct libusb_context *ctx)
|
int usbi_signal_event(struct libusb_context *ctx)
|
||||||
{
|
{
|
||||||
unsigned char dummy = 1;
|
unsigned char dummy = 1;
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
|
||||||
if (ctx == NULL)
|
/* write some data on event pipe to interrupt event handlers */
|
||||||
return;
|
r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy));
|
||||||
|
if (r != sizeof(dummy)) {
|
||||||
/* record that we are messing with poll fds */
|
|
||||||
usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
|
||||||
ctx->pollfd_modify++;
|
|
||||||
usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
|
||||||
|
|
||||||
/* write some data on control pipe to interrupt event handlers */
|
|
||||||
r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
|
|
||||||
if (r <= 0) {
|
|
||||||
usbi_warn(ctx, "internal signalling write failed");
|
usbi_warn(ctx, "internal signalling write failed");
|
||||||
usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
return LIBUSB_ERROR_IO;
|
||||||
ctx->pollfd_modify--;
|
|
||||||
usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* take event handling lock */
|
return 0;
|
||||||
libusb_lock_events(ctx);
|
}
|
||||||
|
|
||||||
/* read the dummy data */
|
/*
|
||||||
r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
|
* Clear the event pipe so that the event handling will no longer be
|
||||||
if (r <= 0)
|
* interrupted.
|
||||||
|
*/
|
||||||
|
int usbi_clear_event(struct libusb_context *ctx)
|
||||||
|
{
|
||||||
|
unsigned char dummy;
|
||||||
|
ssize_t r;
|
||||||
|
|
||||||
|
/* read some data on event pipe to clear it */
|
||||||
|
r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy));
|
||||||
|
if (r != sizeof(dummy)) {
|
||||||
usbi_warn(ctx, "internal signalling read failed");
|
usbi_warn(ctx, "internal signalling read failed");
|
||||||
|
return LIBUSB_ERROR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
/* we're done with modifying poll fds */
|
return 0;
|
||||||
usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
|
||||||
ctx->pollfd_modify--;
|
|
||||||
usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
|
||||||
|
|
||||||
/* Release event handling lock and wake up event waiters */
|
|
||||||
libusb_unlock_events(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \ingroup dev
|
/** \ingroup dev
|
||||||
|
@ -1125,14 +1257,6 @@ int API_EXPORTED libusb_open(libusb_device *dev,
|
||||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||||
*handle = _handle;
|
*handle = _handle;
|
||||||
|
|
||||||
/* At this point, we want to interrupt any existing event handlers so
|
|
||||||
* that they realise the addition of the new device's poll fd. One
|
|
||||||
* example when this is desirable is if the user is running a separate
|
|
||||||
* dedicated libusb events handling thread, which is running with a long
|
|
||||||
* or infinite timeout. We want to interrupt that iteration of the loop,
|
|
||||||
* so that it picks up the new fd, and then continues. */
|
|
||||||
usbi_fd_notification(ctx);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,8 +1384,7 @@ static void do_close(struct libusb_context *ctx,
|
||||||
void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
|
void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
|
||||||
{
|
{
|
||||||
struct libusb_context *ctx;
|
struct libusb_context *ctx;
|
||||||
unsigned char dummy = 1;
|
int pending_events;
|
||||||
ssize_t r;
|
|
||||||
|
|
||||||
if (!dev_handle)
|
if (!dev_handle)
|
||||||
return;
|
return;
|
||||||
|
@ -1275,37 +1398,29 @@ void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
|
||||||
* thread from doing event handling) because we will be removing a file
|
* thread from doing event handling) because we will be removing a file
|
||||||
* descriptor from the polling loop. */
|
* descriptor from the polling loop. */
|
||||||
|
|
||||||
/* record that we are messing with poll fds */
|
/* Record that we are closing a device.
|
||||||
usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
* Only signal an event if there are no prior pending events. */
|
||||||
ctx->pollfd_modify++;
|
usbi_mutex_lock(&ctx->event_data_lock);
|
||||||
usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
pending_events = usbi_pending_events(ctx);
|
||||||
|
ctx->device_close++;
|
||||||
/* write some data on control pipe to interrupt event handlers */
|
if (!pending_events)
|
||||||
r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
|
usbi_signal_event(ctx);
|
||||||
if (r <= 0) {
|
usbi_mutex_unlock(&ctx->event_data_lock);
|
||||||
usbi_warn(ctx, "internal signalling write failed, closing anyway");
|
|
||||||
do_close(ctx, dev_handle);
|
|
||||||
usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
|
||||||
ctx->pollfd_modify--;
|
|
||||||
usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* take event handling lock */
|
/* take event handling lock */
|
||||||
libusb_lock_events(ctx);
|
libusb_lock_events(ctx);
|
||||||
|
|
||||||
/* read the dummy data */
|
|
||||||
r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
|
|
||||||
if (r <= 0)
|
|
||||||
usbi_warn(ctx, "internal signalling read failed, closing anyway");
|
|
||||||
|
|
||||||
/* Close the device */
|
/* Close the device */
|
||||||
do_close(ctx, dev_handle);
|
do_close(ctx, dev_handle);
|
||||||
|
|
||||||
/* we're done with modifying poll fds */
|
/* We're done with closing this device.
|
||||||
usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
* Clear the event pipe if there are no further pending events. */
|
||||||
ctx->pollfd_modify--;
|
usbi_mutex_lock(&ctx->event_data_lock);
|
||||||
usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
ctx->device_close--;
|
||||||
|
pending_events = usbi_pending_events(ctx);
|
||||||
|
if (!pending_events)
|
||||||
|
usbi_clear_event(ctx);
|
||||||
|
usbi_mutex_unlock(&ctx->event_data_lock);
|
||||||
|
|
||||||
/* Release event handling lock and wake up event waiters */
|
/* Release event handling lock and wake up event waiters */
|
||||||
libusb_unlock_events(ctx);
|
libusb_unlock_events(ctx);
|
||||||
|
@ -1413,7 +1528,8 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev,
|
||||||
*
|
*
|
||||||
* \param dev a device handle
|
* \param dev a device handle
|
||||||
* \param configuration the bConfigurationValue of the configuration you
|
* \param configuration the bConfigurationValue of the configuration you
|
||||||
* wish to activate, or -1 if you wish to put the device in unconfigured state
|
* wish to activate, or -1 if you wish to put the device in an unconfigured
|
||||||
|
* state
|
||||||
* \returns 0 on success
|
* \returns 0 on success
|
||||||
* \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist
|
* \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist
|
||||||
* \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed
|
* \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed
|
||||||
|
@ -1907,8 +2023,8 @@ int API_EXPORTED libusb_init(libusb_context **context)
|
||||||
usbi_dbg("created default context");
|
usbi_dbg("created default context");
|
||||||
}
|
}
|
||||||
|
|
||||||
usbi_dbg("libusb v%d.%d.%d.%d", libusb_version_internal.major, libusb_version_internal.minor,
|
usbi_dbg("libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor,
|
||||||
libusb_version_internal.micro, libusb_version_internal.nano);
|
libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc);
|
||||||
|
|
||||||
usbi_mutex_init(&ctx->usb_devs_lock, NULL);
|
usbi_mutex_init(&ctx->usb_devs_lock, NULL);
|
||||||
usbi_mutex_init(&ctx->open_devs_lock, NULL);
|
usbi_mutex_init(&ctx->open_devs_lock, NULL);
|
||||||
|
@ -1946,8 +2062,10 @@ err_backend_exit:
|
||||||
if (usbi_backend->exit)
|
if (usbi_backend->exit)
|
||||||
usbi_backend->exit();
|
usbi_backend->exit();
|
||||||
err_free_ctx:
|
err_free_ctx:
|
||||||
if (ctx == usbi_default_context)
|
if (ctx == usbi_default_context) {
|
||||||
usbi_default_context = NULL;
|
usbi_default_context = NULL;
|
||||||
|
default_context_refcnt--;
|
||||||
|
}
|
||||||
|
|
||||||
usbi_mutex_static_lock(&active_contexts_lock);
|
usbi_mutex_static_lock(&active_contexts_lock);
|
||||||
list_del (&ctx->list);
|
list_del (&ctx->list);
|
||||||
|
@ -2191,8 +2309,8 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
|
||||||
usbi_gettimeofday(&now, NULL);
|
usbi_gettimeofday(&now, NULL);
|
||||||
if ((global_debug) && (!has_debug_header_been_displayed)) {
|
if ((global_debug) && (!has_debug_header_been_displayed)) {
|
||||||
has_debug_header_been_displayed = 1;
|
has_debug_header_been_displayed = 1;
|
||||||
usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>\n");
|
usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>" USBI_LOG_LINE_END);
|
||||||
usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------\n");
|
usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END);
|
||||||
}
|
}
|
||||||
if (now.tv_usec < timestamp_origin.tv_usec) {
|
if (now.tv_usec < timestamp_origin.tv_usec) {
|
||||||
now.tv_sec--;
|
now.tv_sec--;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -453,7 +455,7 @@ static int parse_configuration(struct libusb_context *ctx,
|
||||||
(header.bDescriptorType == LIBUSB_DT_DEVICE))
|
(header.bDescriptorType == LIBUSB_DT_DEVICE))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType);
|
usbi_dbg("skipping descriptor 0x%x", header.bDescriptorType);
|
||||||
buffer += header.bLength;
|
buffer += header.bLength;
|
||||||
size -= header.bLength;
|
size -= header.bLength;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
*
|
*
|
||||||
* \page hotplug Device hotplug event notification
|
* \page hotplug Device hotplug event notification
|
||||||
*
|
*
|
||||||
* \section intro Introduction
|
* \section hotplug_intro Introduction
|
||||||
*
|
*
|
||||||
* Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support
|
* 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
|
* for hotplug events on <b>some</b> platforms (you should test if your platform
|
||||||
|
@ -203,6 +203,30 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
||||||
/* the backend is expected to call the callback for each active transfer */
|
/* the backend is expected to call the callback for each active transfer */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
|
||||||
|
libusb_hotplug_event event)
|
||||||
|
{
|
||||||
|
int pending_events;
|
||||||
|
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,
|
int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
|
||||||
libusb_hotplug_event events, libusb_hotplug_flag flags,
|
libusb_hotplug_event events, libusb_hotplug_flag flags,
|
||||||
int vendor_id, int product_id, int dev_class,
|
int vendor_id, int product_id, int dev_class,
|
||||||
|
@ -285,8 +309,6 @@ void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx
|
||||||
libusb_hotplug_callback_handle handle)
|
libusb_hotplug_callback_handle handle)
|
||||||
{
|
{
|
||||||
struct libusb_hotplug_callback *hotplug_cb;
|
struct libusb_hotplug_callback *hotplug_cb;
|
||||||
libusb_hotplug_message message;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
/* check for hotplug support */
|
/* check for hotplug support */
|
||||||
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
||||||
|
@ -305,12 +327,7 @@ void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx
|
||||||
}
|
}
|
||||||
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
||||||
|
|
||||||
/* wakeup handle_events to do the actual free */
|
usbi_hotplug_notification(ctx, NULL, 0);
|
||||||
memset(&message, 0, sizeof(message));
|
|
||||||
ret = usbi_write(ctx->hotplug_pipe[1], &message, sizeof(message));
|
|
||||||
if (sizeof(message) != ret) {
|
|
||||||
usbi_err(ctx, "error writing hotplug message");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbi_hotplug_deregister_all(struct libusb_context *ctx) {
|
void usbi_hotplug_deregister_all(struct libusb_context *ctx) {
|
||||||
|
|
|
@ -69,8 +69,14 @@ struct libusb_hotplug_callback {
|
||||||
typedef struct libusb_hotplug_callback libusb_hotplug_callback;
|
typedef struct libusb_hotplug_callback libusb_hotplug_callback;
|
||||||
|
|
||||||
struct libusb_hotplug_message {
|
struct libusb_hotplug_message {
|
||||||
|
/** The hotplug event that occurred */
|
||||||
libusb_hotplug_event event;
|
libusb_hotplug_event event;
|
||||||
|
|
||||||
|
/** The device for which this hotplug event occurred */
|
||||||
struct libusb_device *device;
|
struct libusb_device *device;
|
||||||
|
|
||||||
|
/** List this message is contained in (ctx->hotplug_msgs) */
|
||||||
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct libusb_hotplug_message libusb_hotplug_message;
|
typedef struct libusb_hotplug_message libusb_hotplug_message;
|
||||||
|
@ -78,5 +84,7 @@ typedef struct libusb_hotplug_message libusb_hotplug_message;
|
||||||
void usbi_hotplug_deregister_all(struct libusb_context *ctx);
|
void usbi_hotplug_deregister_all(struct libusb_context *ctx);
|
||||||
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
||||||
libusb_hotplug_event event);
|
libusb_hotplug_event event);
|
||||||
|
void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
|
||||||
|
libusb_hotplug_event event);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -80,6 +80,8 @@ EXPORTS
|
||||||
libusb_get_parent@4 = libusb_get_parent
|
libusb_get_parent@4 = libusb_get_parent
|
||||||
libusb_get_pollfds
|
libusb_get_pollfds
|
||||||
libusb_get_pollfds@4 = libusb_get_pollfds
|
libusb_get_pollfds@4 = libusb_get_pollfds
|
||||||
|
libusb_free_pollfds
|
||||||
|
libusb_free_pollfds@4 = libusb_free_pollfds
|
||||||
libusb_get_port_number
|
libusb_get_port_number
|
||||||
libusb_get_port_number@4 = libusb_get_port_number
|
libusb_get_port_number@4 = libusb_get_port_number
|
||||||
libusb_get_port_numbers
|
libusb_get_port_numbers
|
||||||
|
|
|
@ -54,7 +54,7 @@ typedef unsigned __int32 uint32_t;
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__)
|
#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__)
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ typedef unsigned __int32 uint32_t;
|
||||||
* Under Windows, the selection of available compilers and configurations
|
* Under Windows, the selection of available compilers and configurations
|
||||||
* means that, unlike other platforms, there is not <em>one true calling
|
* means that, unlike other platforms, there is not <em>one true calling
|
||||||
* convention</em> (calling convention: the manner in which parameters are
|
* convention</em> (calling convention: the manner in which parameters are
|
||||||
* passed to funcions in the generated assembly code).
|
* passed to functions in the generated assembly code).
|
||||||
*
|
*
|
||||||
* Matching the Windows API itself, libusb uses the WINAPI convention (which
|
* Matching the Windows API itself, libusb uses the WINAPI convention (which
|
||||||
* translates to the <tt>stdcall</tt> convention) and guarantees that the
|
* translates to the <tt>stdcall</tt> convention) and guarantees that the
|
||||||
|
@ -138,13 +138,10 @@ typedef unsigned __int32 uint32_t;
|
||||||
* #endif
|
* #endif
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* Another feature of LIBUSB_API_VERSION is that it can be used to detect
|
|
||||||
* whether you are compiling against the libusb or the libusb library.
|
|
||||||
*
|
|
||||||
* Internally, LIBUSB_API_VERSION is defined as follows:
|
* Internally, LIBUSB_API_VERSION is defined as follows:
|
||||||
* (libusb major << 24) | (libusb minor << 16) | (16 bit incremental)
|
* (libusb major << 24) | (libusb minor << 16) | (16 bit incremental)
|
||||||
*/
|
*/
|
||||||
#define LIBUSB_API_VERSION 0x01000103
|
#define LIBUSB_API_VERSION 0x01000104
|
||||||
|
|
||||||
/* The following is kept for compatibility, but will be deprecated in the future */
|
/* The following is kept for compatibility, but will be deprecated in the future */
|
||||||
#define LIBUSBX_API_VERSION LIBUSB_API_VERSION
|
#define LIBUSBX_API_VERSION LIBUSB_API_VERSION
|
||||||
|
@ -668,8 +665,9 @@ struct libusb_config_descriptor {
|
||||||
uint8_t bmAttributes;
|
uint8_t bmAttributes;
|
||||||
|
|
||||||
/** Maximum power consumption of the USB device from this bus in this
|
/** Maximum power consumption of the USB device from this bus in this
|
||||||
* configuration when the device is fully opreation. Expressed in units
|
* configuration when the device is fully operation. Expressed in units
|
||||||
* of 2 mA. */
|
* of 2 mA when the device is operating in high-speed mode and in units
|
||||||
|
* of 8 mA when the device is operating in super-speed mode. */
|
||||||
uint8_t MaxPower;
|
uint8_t MaxPower;
|
||||||
|
|
||||||
/** Array of interfaces supported by this configuration. The length of
|
/** Array of interfaces supported by this configuration. The length of
|
||||||
|
@ -900,7 +898,6 @@ struct libusb_control_setup {
|
||||||
struct libusb_context;
|
struct libusb_context;
|
||||||
struct libusb_device;
|
struct libusb_device;
|
||||||
struct libusb_device_handle;
|
struct libusb_device_handle;
|
||||||
struct libusb_hotplug_callback;
|
|
||||||
|
|
||||||
/** \ingroup lib
|
/** \ingroup lib
|
||||||
* Structure providing the version of the libusb runtime
|
* Structure providing the version of the libusb runtime
|
||||||
|
@ -1860,6 +1857,7 @@ typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data);
|
||||||
|
|
||||||
const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
|
const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
|
||||||
libusb_context *ctx);
|
libusb_context *ctx);
|
||||||
|
void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds);
|
||||||
void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
|
void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
|
||||||
libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
|
libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
@ -1884,8 +1882,11 @@ typedef int libusb_hotplug_callback_handle;
|
||||||
*
|
*
|
||||||
* Flags for hotplug events */
|
* Flags for hotplug events */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
/** Default value when not using any flags. */
|
||||||
|
LIBUSB_HOTPLUG_NO_FLAGS = 0,
|
||||||
|
|
||||||
/** Arm the callback and fire it for all matching currently attached devices. */
|
/** Arm the callback and fire it for all matching currently attached devices. */
|
||||||
LIBUSB_HOTPLUG_ENUMERATE = 1,
|
LIBUSB_HOTPLUG_ENUMERATE = 1<<0,
|
||||||
} libusb_hotplug_flag;
|
} libusb_hotplug_flag;
|
||||||
|
|
||||||
/** \ingroup hotplug
|
/** \ingroup hotplug
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#ifndef LIBUSBI_H
|
#ifndef LIBUSBI_H
|
||||||
#define LIBUSBI_H
|
#define LIBUSBI_H
|
||||||
|
|
||||||
#include "config.h"
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@
|
||||||
#ifdef HAVE_POLL_H
|
#ifdef HAVE_POLL_H
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_MISSING_H
|
#ifdef HAVE_MISSING_H
|
||||||
#include "missing.h"
|
#include <missing.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libusb.h"
|
#include "libusb.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@
|
||||||
*/
|
*/
|
||||||
#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY
|
#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEVICE_DESC_LENGTH 18
|
#define DEVICE_DESC_LENGTH 18
|
||||||
|
|
||||||
#define USB_MAXENDPOINTS 32
|
#define USB_MAXENDPOINTS 32
|
||||||
|
@ -82,6 +86,9 @@ struct list_head {
|
||||||
#define list_entry(ptr, type, member) \
|
#define list_entry(ptr, type, member) \
|
||||||
((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))
|
((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))
|
||||||
|
|
||||||
|
#define list_first_entry(ptr, type, member) \
|
||||||
|
list_entry((ptr)->next, type, member)
|
||||||
|
|
||||||
/* Get each entry from a list
|
/* Get each entry from a list
|
||||||
* pos - A structure pointer has a "member" element
|
* pos - A structure pointer has a "member" element
|
||||||
* head - list head
|
* head - list head
|
||||||
|
@ -144,8 +151,12 @@ static inline void *usbi_reallocf(void *ptr, size_t size)
|
||||||
const typeof( ((type *)0)->member ) *mptr = (ptr); \
|
const typeof( ((type *)0)->member ) *mptr = (ptr); \
|
||||||
(type *)( (char *)mptr - offsetof(type,member) );})
|
(type *)( (char *)mptr - offsetof(type,member) );})
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#ifndef MAX
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
|
#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
|
||||||
|
|
||||||
|
@ -228,13 +239,15 @@ static inline void usbi_dbg(const char *format, ...)
|
||||||
|
|
||||||
extern struct libusb_context *usbi_default_context;
|
extern struct libusb_context *usbi_default_context;
|
||||||
|
|
||||||
|
/* Forward declaration for use in context (fully defined inside poll abstraction) */
|
||||||
|
struct pollfd;
|
||||||
|
|
||||||
struct libusb_context {
|
struct libusb_context {
|
||||||
int debug;
|
int debug;
|
||||||
int debug_fixed;
|
int debug_fixed;
|
||||||
|
|
||||||
/* internal control pipe, used for interrupting event handling when
|
/* internal event pipe, used for signalling occurrence of an internal event. */
|
||||||
* something needs to modify poll fds. */
|
int event_pipe[2];
|
||||||
int ctrl_pipe[2];
|
|
||||||
|
|
||||||
struct list_head usb_devs;
|
struct list_head usb_devs;
|
||||||
usbi_mutex_t usb_devs_lock;
|
usbi_mutex_t usb_devs_lock;
|
||||||
|
@ -247,7 +260,6 @@ struct libusb_context {
|
||||||
/* A list of registered hotplug callbacks */
|
/* A list of registered hotplug callbacks */
|
||||||
struct list_head hotplug_cbs;
|
struct list_head hotplug_cbs;
|
||||||
usbi_mutex_t hotplug_cbs_lock;
|
usbi_mutex_t hotplug_cbs_lock;
|
||||||
int hotplug_pipe[2];
|
|
||||||
|
|
||||||
/* this is a list of in-flight transfer handles, sorted by timeout
|
/* this is a list of in-flight transfer handles, sorted by timeout
|
||||||
* expiration. URBs to timeout the soonest are placed at the beginning of
|
* expiration. URBs to timeout the soonest are placed at the beginning of
|
||||||
|
@ -256,15 +268,6 @@ struct libusb_context {
|
||||||
struct list_head flying_transfers;
|
struct list_head flying_transfers;
|
||||||
usbi_mutex_t flying_transfers_lock;
|
usbi_mutex_t flying_transfers_lock;
|
||||||
|
|
||||||
/* list of poll fds */
|
|
||||||
struct list_head pollfds;
|
|
||||||
usbi_mutex_t pollfds_lock;
|
|
||||||
|
|
||||||
/* a counter that is set when we want to interrupt event handling, in order
|
|
||||||
* to modify the poll fd set. and a lock to protect it. */
|
|
||||||
unsigned int pollfd_modify;
|
|
||||||
usbi_mutex_t pollfd_modify_lock;
|
|
||||||
|
|
||||||
/* user callbacks for pollfd changes */
|
/* user callbacks for pollfd changes */
|
||||||
libusb_pollfd_added_cb fd_added_cb;
|
libusb_pollfd_added_cb fd_added_cb;
|
||||||
libusb_pollfd_removed_cb fd_removed_cb;
|
libusb_pollfd_removed_cb fd_removed_cb;
|
||||||
|
@ -281,6 +284,28 @@ struct libusb_context {
|
||||||
usbi_mutex_t event_waiters_lock;
|
usbi_mutex_t event_waiters_lock;
|
||||||
usbi_cond_t event_waiters_cond;
|
usbi_cond_t event_waiters_cond;
|
||||||
|
|
||||||
|
/* A lock to protect internal context event data. */
|
||||||
|
usbi_mutex_t event_data_lock;
|
||||||
|
|
||||||
|
/* A counter that is set when we want to interrupt and prevent event handling,
|
||||||
|
* in order to safely close a device. Protected by event_data_lock. */
|
||||||
|
unsigned int device_close;
|
||||||
|
|
||||||
|
/* list and count of poll fds and an array of poll fd structures that is
|
||||||
|
* (re)allocated as necessary prior to polling, and a flag to indicate
|
||||||
|
* when the list of poll fds has changed since the last poll.
|
||||||
|
* Protected by event_data_lock. */
|
||||||
|
struct list_head ipollfds;
|
||||||
|
struct pollfd *pollfds;
|
||||||
|
POLL_NFDS_TYPE pollfds_cnt;
|
||||||
|
unsigned int pollfds_modified;
|
||||||
|
|
||||||
|
/* A list of pending hotplug messages. Protected by event_data_lock. */
|
||||||
|
struct list_head hotplug_msgs;
|
||||||
|
|
||||||
|
/* A list of pending completed transfers. Protected by event_data_lock. */
|
||||||
|
struct list_head completed_transfers;
|
||||||
|
|
||||||
#ifdef USBI_TIMERFD_AVAILABLE
|
#ifdef USBI_TIMERFD_AVAILABLE
|
||||||
/* used for timeout handling, if supported by OS.
|
/* used for timeout handling, if supported by OS.
|
||||||
* this timerfd is maintained to trigger on the next pending timeout */
|
* this timerfd is maintained to trigger on the next pending timeout */
|
||||||
|
@ -290,6 +315,11 @@ struct libusb_context {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Update the following macro if new event sources are added */
|
||||||
|
#define usbi_pending_events(ctx) \
|
||||||
|
((ctx)->device_close || (ctx)->pollfds_modified \
|
||||||
|
|| !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers))
|
||||||
|
|
||||||
#ifdef USBI_TIMERFD_AVAILABLE
|
#ifdef USBI_TIMERFD_AVAILABLE
|
||||||
#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0)
|
#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0)
|
||||||
#else
|
#else
|
||||||
|
@ -364,6 +394,7 @@ enum {
|
||||||
struct usbi_transfer {
|
struct usbi_transfer {
|
||||||
int num_iso_packets;
|
int num_iso_packets;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct list_head completed_list;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int transferred;
|
int transferred;
|
||||||
uint32_t stream_id;
|
uint32_t stream_id;
|
||||||
|
@ -377,6 +408,10 @@ struct usbi_transfer {
|
||||||
* its completion (presumably there would be races within your OS backend
|
* its completion (presumably there would be races within your OS backend
|
||||||
* if this were possible). */
|
* if this were possible). */
|
||||||
usbi_mutex_t lock;
|
usbi_mutex_t lock;
|
||||||
|
|
||||||
|
/* this lock should be held whenever viewing or modifying flags
|
||||||
|
* relating to the transfer state */
|
||||||
|
usbi_mutex_t flags_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum usbi_transfer_flags {
|
enum usbi_transfer_flags {
|
||||||
|
@ -392,8 +427,17 @@ enum usbi_transfer_flags {
|
||||||
/* Operation on the transfer failed because the device disappeared */
|
/* Operation on the transfer failed because the device disappeared */
|
||||||
USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3,
|
USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3,
|
||||||
|
|
||||||
/* Set by backend submit_transfer() if the fds in use have been updated */
|
/* Transfer is currently being submitted */
|
||||||
USBI_TRANSFER_UPDATED_FDS = 1 << 4,
|
USBI_TRANSFER_SUBMITTING = 1 << 4,
|
||||||
|
|
||||||
|
/* Transfer successfully submitted by backend */
|
||||||
|
USBI_TRANSFER_IN_FLIGHT = 1 << 5,
|
||||||
|
|
||||||
|
/* Completion handler has run */
|
||||||
|
USBI_TRANSFER_COMPLETED = 1 << 6,
|
||||||
|
|
||||||
|
/* The transfer timeout has been handled */
|
||||||
|
USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
|
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
|
||||||
|
@ -434,6 +478,7 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle);
|
||||||
int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
||||||
enum libusb_transfer_status status);
|
enum libusb_transfer_status status);
|
||||||
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);
|
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);
|
||||||
|
void usbi_signal_transfer_completion(struct usbi_transfer *transfer);
|
||||||
|
|
||||||
int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
|
int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
|
||||||
void *dest, int host_endian);
|
void *dest, int host_endian);
|
||||||
|
@ -444,8 +489,11 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
|
||||||
void usbi_connect_device (struct libusb_device *dev);
|
void usbi_connect_device (struct libusb_device *dev);
|
||||||
void usbi_disconnect_device (struct libusb_device *dev);
|
void usbi_disconnect_device (struct libusb_device *dev);
|
||||||
|
|
||||||
|
int usbi_signal_event(struct libusb_context *ctx);
|
||||||
|
int usbi_clear_event(struct libusb_context *ctx);
|
||||||
|
|
||||||
/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
|
/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
|
||||||
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD)
|
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "os/poll_posix.h"
|
#include "os/poll_posix.h"
|
||||||
#elif defined(OS_WINDOWS) || defined(OS_WINCE)
|
#elif defined(OS_WINDOWS) || defined(OS_WINCE)
|
||||||
|
@ -474,7 +522,6 @@ struct usbi_pollfd {
|
||||||
|
|
||||||
int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
|
int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
|
||||||
void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
|
void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
|
||||||
void usbi_fd_notification(struct libusb_context *ctx);
|
|
||||||
|
|
||||||
/* device discovery */
|
/* device discovery */
|
||||||
|
|
||||||
|
@ -765,7 +812,7 @@ struct usbi_os_backend {
|
||||||
* This function should not generate any bus I/O and should not block.
|
* This function should not generate any bus I/O and should not block.
|
||||||
* Interface claiming is a logical operation that simply ensures that
|
* Interface claiming is a logical operation that simply ensures that
|
||||||
* no other drivers/applications are using the interface, and after
|
* no other drivers/applications are using the interface, and after
|
||||||
* claiming, no other drivers/applicatiosn can use the interface because
|
* claiming, no other drivers/applications can use the interface because
|
||||||
* we now "own" it.
|
* we now "own" it.
|
||||||
*
|
*
|
||||||
* Return:
|
* Return:
|
||||||
|
@ -943,8 +990,14 @@ struct usbi_os_backend {
|
||||||
*/
|
*/
|
||||||
void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
|
void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
|
||||||
|
|
||||||
/* Handle any pending events. This involves monitoring any active
|
/* Handle any pending events on file descriptors. Optional.
|
||||||
* transfers and processing their completion or cancellation.
|
*
|
||||||
|
* Provide this function when file descriptors directly indicate device
|
||||||
|
* or transfer activity. If your backend does not have such file descriptors,
|
||||||
|
* implement the handle_transfer_completion function below.
|
||||||
|
*
|
||||||
|
* This involves monitoring any active transfers and processing their
|
||||||
|
* completion or cancellation.
|
||||||
*
|
*
|
||||||
* The function is passed an array of pollfd structures (size nfds)
|
* The function is passed an array of pollfd structures (size nfds)
|
||||||
* as a result of the poll() system call. The num_ready parameter
|
* as a result of the poll() system call. The num_ready parameter
|
||||||
|
@ -972,6 +1025,31 @@ struct usbi_os_backend {
|
||||||
int (*handle_events)(struct libusb_context *ctx,
|
int (*handle_events)(struct libusb_context *ctx,
|
||||||
struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
|
struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
|
||||||
|
|
||||||
|
/* Handle transfer completion. Optional.
|
||||||
|
*
|
||||||
|
* Provide this function when there are no file descriptors available
|
||||||
|
* that directly indicate device or transfer activity. If your backend does
|
||||||
|
* have such file descriptors, implement the handle_events function above.
|
||||||
|
*
|
||||||
|
* Your backend must tell the library when a transfer has completed by
|
||||||
|
* calling usbi_signal_transfer_completion(). You should store any private
|
||||||
|
* information about the transfer and its completion status in the transfer's
|
||||||
|
* private backend data.
|
||||||
|
*
|
||||||
|
* During event handling, this function will be called on each transfer for
|
||||||
|
* which usbi_signal_transfer_completion() was called.
|
||||||
|
*
|
||||||
|
* For any cancelled transfers, call usbi_handle_transfer_cancellation().
|
||||||
|
* For completed transfers, call usbi_handle_transfer_completion().
|
||||||
|
* For control/bulk/interrupt transfers, populate the "transferred"
|
||||||
|
* element of the appropriate usbi_transfer structure before calling the
|
||||||
|
* above functions. For isochronous transfers, populate the status and
|
||||||
|
* transferred fields of the iso packet descriptors of the transfer.
|
||||||
|
*
|
||||||
|
* Return 0 on success, or a LIBUSB_ERROR code on failure.
|
||||||
|
*/
|
||||||
|
int (*handle_transfer_completion)(struct usbi_transfer *itransfer);
|
||||||
|
|
||||||
/* Get time from specified clock. At least two clocks must be implemented
|
/* Get time from specified clock. At least two clocks must be implemented
|
||||||
by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
|
by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
|
||||||
|
|
||||||
|
@ -1002,12 +1080,6 @@ struct usbi_os_backend {
|
||||||
* usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance.
|
* usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance.
|
||||||
*/
|
*/
|
||||||
size_t transfer_priv_size;
|
size_t transfer_priv_size;
|
||||||
|
|
||||||
/* Mumber of additional bytes for os_priv for each iso packet.
|
|
||||||
* Can your backend use this? */
|
|
||||||
/* FIXME: linux can't use this any more. if other OS's cannot either,
|
|
||||||
* then remove this */
|
|
||||||
size_t add_iso_packet_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct usbi_os_backend * const usbi_backend;
|
extern const struct usbi_os_backend * const usbi_backend;
|
||||||
|
@ -1018,8 +1090,13 @@ extern const struct usbi_os_backend openbsd_backend;
|
||||||
extern const struct usbi_os_backend netbsd_backend;
|
extern const struct usbi_os_backend netbsd_backend;
|
||||||
extern const struct usbi_os_backend windows_backend;
|
extern const struct usbi_os_backend windows_backend;
|
||||||
extern const struct usbi_os_backend wince_backend;
|
extern const struct usbi_os_backend wince_backend;
|
||||||
|
extern const struct usbi_os_backend haiku_usb_raw_backend;
|
||||||
|
|
||||||
extern struct list_head active_contexts_list;
|
extern struct list_head active_contexts_list;
|
||||||
extern usbi_mutex_static_t active_contexts_lock;
|
extern usbi_mutex_static_t active_contexts_lock;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -246,7 +246,7 @@ static usb_device_t **darwin_device_from_service (io_service_t service)
|
||||||
&score);
|
&score);
|
||||||
|
|
||||||
if (kIOReturnSuccess != result || !plugInInterface) {
|
if (kIOReturnSuccess != result || !plugInInterface) {
|
||||||
usbi_dbg ("could not set up plugin for service: %s\n", darwin_error_str (result));
|
usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (result));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +279,7 @@ static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
|
||||||
static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
||||||
struct libusb_device *dev = NULL;
|
struct libusb_device *dev = NULL;
|
||||||
struct libusb_context *ctx;
|
struct libusb_context *ctx;
|
||||||
|
struct darwin_cached_device *old_device;
|
||||||
|
|
||||||
io_service_t device;
|
io_service_t device;
|
||||||
UInt64 session;
|
UInt64 session;
|
||||||
|
@ -293,6 +294,17 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
||||||
if (!ret)
|
if (!ret)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
|
||||||
|
otherwise no cached device will ever get freed */
|
||||||
|
usbi_mutex_lock(&darwin_cached_devices_lock);
|
||||||
|
list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
|
||||||
|
if (old_device->session == session) {
|
||||||
|
darwin_deref_cached_device (old_device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usbi_mutex_unlock(&darwin_cached_devices_lock);
|
||||||
|
|
||||||
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
|
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
|
||||||
usbi_dbg ("notifying context %p of device disconnect", ctx);
|
usbi_dbg ("notifying context %p of device disconnect", ctx);
|
||||||
|
|
||||||
|
@ -973,14 +985,6 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
|
||||||
/* device opened successfully */
|
/* device opened successfully */
|
||||||
dpriv->open_count++;
|
dpriv->open_count++;
|
||||||
|
|
||||||
/* create a file descriptor for notifications */
|
|
||||||
pipe (priv->fds);
|
|
||||||
|
|
||||||
/* set the pipe to be non-blocking */
|
|
||||||
fcntl (priv->fds[1], F_SETFD, O_NONBLOCK);
|
|
||||||
|
|
||||||
usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
|
|
||||||
|
|
||||||
usbi_dbg ("device open for access");
|
usbi_dbg ("device open for access");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -994,7 +998,7 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
|
||||||
|
|
||||||
if (dpriv->open_count == 0) {
|
if (dpriv->open_count == 0) {
|
||||||
/* something is probably very wrong if this is the case */
|
/* something is probably very wrong if this is the case */
|
||||||
usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!\n");
|
usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,13 +1028,6 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* file descriptors are maintained per-instance */
|
|
||||||
usbi_remove_pollfd (HANDLE_CTX (dev_handle), priv->fds[0]);
|
|
||||||
close (priv->fds[1]);
|
|
||||||
close (priv->fds[0]);
|
|
||||||
|
|
||||||
priv->fds[0] = priv->fds[1] = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
|
static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
|
||||||
|
@ -1761,9 +1758,7 @@ static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) {
|
||||||
static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
|
static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
|
||||||
struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
|
struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
|
||||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||||
struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
|
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
||||||
struct darwin_msg_async_io_complete message = {.itransfer = itransfer, .result = result,
|
|
||||||
.size = (UInt32) (uintptr_t) arg0};
|
|
||||||
|
|
||||||
usbi_dbg ("an async io operation has completed");
|
usbi_dbg ("an async io operation has completed");
|
||||||
|
|
||||||
|
@ -1777,8 +1772,11 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
|
||||||
(*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
|
(*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send a completion message to the device's file descriptor */
|
tpriv->result = result;
|
||||||
write (priv->fds[1], &message, sizeof (message));
|
tpriv->size = (UInt32) (uintptr_t) arg0;
|
||||||
|
|
||||||
|
/* signal the core that this transfer is complete */
|
||||||
|
usbi_signal_transfer_completion(itransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
|
static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
|
||||||
|
@ -1807,7 +1805,7 @@ static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
|
static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
|
||||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||||
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
||||||
int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
|
int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
|
||||||
|
@ -1818,13 +1816,13 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
|
||||||
|
|
||||||
if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
|
if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
|
||||||
usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
|
usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
|
||||||
return;
|
return LIBUSB_ERROR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
usbi_dbg ("handling %s completion with kernel status %d",
|
usbi_dbg ("handling %s completion with kernel status %d",
|
||||||
isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", result);
|
isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
|
||||||
|
|
||||||
if (kIOReturnSuccess == result || kIOReturnUnderrun == result) {
|
if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
|
||||||
if (isIsoc && tpriv->isoc_framelist) {
|
if (isIsoc && tpriv->isoc_framelist) {
|
||||||
/* copy isochronous results back */
|
/* copy isochronous results back */
|
||||||
|
|
||||||
|
@ -1834,48 +1832,11 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
|
||||||
lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
|
lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
|
||||||
}
|
}
|
||||||
} else if (!isIsoc)
|
} else if (!isIsoc)
|
||||||
itransfer->transferred += io_size;
|
itransfer->transferred += tpriv->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
|
/* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
|
||||||
usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
|
return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
|
||||||
}
|
|
||||||
|
|
||||||
static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
|
|
||||||
struct darwin_msg_async_io_complete message;
|
|
||||||
POLL_NFDS_TYPE i = 0;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
usbi_mutex_lock(&ctx->open_devs_lock);
|
|
||||||
|
|
||||||
for (i = 0; i < nfds && num_ready > 0; i++) {
|
|
||||||
struct pollfd *pollfd = &fds[i];
|
|
||||||
|
|
||||||
usbi_dbg ("checking fd %i with revents = %x", pollfd->fd, pollfd->revents);
|
|
||||||
|
|
||||||
if (!pollfd->revents)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
num_ready--;
|
|
||||||
|
|
||||||
if (pollfd->revents & POLLERR) {
|
|
||||||
/* this probably will never happen so ignore the error an move on. */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* there is only one type of message */
|
|
||||||
ret = read (pollfd->fd, &message, sizeof (message));
|
|
||||||
if (ret < (ssize_t) sizeof (message)) {
|
|
||||||
usbi_dbg ("WARNING: short read on async io completion pipe\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
darwin_handle_callback (message.itransfer, message.result, message.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
|
static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
|
||||||
|
@ -1998,12 +1959,11 @@ const struct usbi_os_backend darwin_backend = {
|
||||||
.cancel_transfer = darwin_cancel_transfer,
|
.cancel_transfer = darwin_cancel_transfer,
|
||||||
.clear_transfer_priv = darwin_clear_transfer_priv,
|
.clear_transfer_priv = darwin_clear_transfer_priv,
|
||||||
|
|
||||||
.handle_events = op_handle_events,
|
.handle_transfer_completion = darwin_handle_transfer_completion,
|
||||||
|
|
||||||
.clock_gettime = darwin_clock_gettime,
|
.clock_gettime = darwin_clock_gettime,
|
||||||
|
|
||||||
.device_priv_size = sizeof(struct darwin_device_priv),
|
.device_priv_size = sizeof(struct darwin_device_priv),
|
||||||
.device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
|
.device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
|
||||||
.transfer_priv_size = sizeof(struct darwin_transfer_priv),
|
.transfer_priv_size = sizeof(struct darwin_transfer_priv),
|
||||||
.add_iso_packet_size = 0,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <IOKit/IOCFPlugIn.h>
|
#include <IOKit/IOCFPlugIn.h>
|
||||||
|
|
||||||
/* IOUSBInterfaceInferface */
|
/* IOUSBInterfaceInferface */
|
||||||
#if defined (kIOUSBInterfaceInterfaceID550)
|
#if defined (kIOUSBInterfaceInterfaceID550) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
|
||||||
|
|
||||||
#define usb_interface_t IOUSBInterfaceInterface550
|
#define usb_interface_t IOUSBInterfaceInterface550
|
||||||
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550
|
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* IOUSBDeviceInterface */
|
/* IOUSBDeviceInterface */
|
||||||
#if defined (kIOUSBDeviceInterfaceID500)
|
#if defined (kIOUSBDeviceInterfaceID500) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
|
||||||
|
|
||||||
#define usb_device_t IOUSBDeviceInterface500
|
#define usb_device_t IOUSBDeviceInterface500
|
||||||
#define DeviceInterfaceID kIOUSBDeviceInterfaceID500
|
#define DeviceInterfaceID kIOUSBDeviceInterfaceID500
|
||||||
|
@ -130,7 +130,6 @@ struct darwin_device_priv {
|
||||||
struct darwin_device_handle_priv {
|
struct darwin_device_handle_priv {
|
||||||
int is_open;
|
int is_open;
|
||||||
CFRunLoopSourceRef cfSource;
|
CFRunLoopSourceRef cfSource;
|
||||||
int fds[2];
|
|
||||||
|
|
||||||
struct darwin_interface {
|
struct darwin_interface {
|
||||||
usb_interface_t **interface;
|
usb_interface_t **interface;
|
||||||
|
@ -150,11 +149,8 @@ struct darwin_transfer_priv {
|
||||||
IOUSBDevRequestTO req;
|
IOUSBDevRequestTO req;
|
||||||
|
|
||||||
/* Bulk */
|
/* Bulk */
|
||||||
};
|
|
||||||
|
|
||||||
/* structure for signaling io completion */
|
/* Completion status */
|
||||||
struct darwin_msg_async_io_complete {
|
|
||||||
struct usbi_transfer *itransfer;
|
|
||||||
IOReturn result;
|
IOReturn result;
|
||||||
UInt32 size;
|
UInt32 size;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
AUTOMAKE_OPTIONS = subdir-objects
|
||||||
|
noinst_LTLIBRARIES = libhaikuusb.la
|
||||||
|
libhaikuusb_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(srcdir)/../../.. -I$(srcdir)/../../../..
|
||||||
|
libhaikuusb_la_SOURCES = haiku_usb_raw.cpp haiku_usb_backend.cpp haiku_pollfs.cpp haiku_usb_raw.h haiku_usb.h
|
|
@ -0,0 +1,810 @@
|
||||||
|
# Makefile.in generated by automake 1.15 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
am__is_gnu_make = { \
|
||||||
|
if test -z '$(MAKELEVEL)'; then \
|
||||||
|
false; \
|
||||||
|
elif test -n '$(MAKE_HOST)'; then \
|
||||||
|
true; \
|
||||||
|
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
|
am__make_running_with_option = \
|
||||||
|
case $${target_option-} in \
|
||||||
|
?) ;; \
|
||||||
|
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||||
|
"target option '$${target_option-}' specified" >&2; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
has_opt=no; \
|
||||||
|
sane_makeflags=$$MAKEFLAGS; \
|
||||||
|
if $(am__is_gnu_make); then \
|
||||||
|
sane_makeflags=$$MFLAGS; \
|
||||||
|
else \
|
||||||
|
case $$MAKEFLAGS in \
|
||||||
|
*\\[\ \ ]*) \
|
||||||
|
bs=\\; \
|
||||||
|
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||||
|
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||||
|
esac; \
|
||||||
|
fi; \
|
||||||
|
skip_next=no; \
|
||||||
|
strip_trailopt () \
|
||||||
|
{ \
|
||||||
|
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||||
|
}; \
|
||||||
|
for flg in $$sane_makeflags; do \
|
||||||
|
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||||
|
case $$flg in \
|
||||||
|
*=*|--*) continue;; \
|
||||||
|
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||||
|
-*I?*) strip_trailopt 'I';; \
|
||||||
|
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||||
|
-*O?*) strip_trailopt 'O';; \
|
||||||
|
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||||
|
-*l?*) strip_trailopt 'l';; \
|
||||||
|
-[dEDm]) skip_next=yes;; \
|
||||||
|
-[JT]) skip_next=yes;; \
|
||||||
|
esac; \
|
||||||
|
case $$flg in \
|
||||||
|
*$$target_option*) has_opt=yes; break;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
test $$has_opt = yes
|
||||||
|
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||||
|
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||||
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||||
|
install_sh_DATA = $(install_sh) -c -m 644
|
||||||
|
install_sh_PROGRAM = $(install_sh) -c
|
||||||
|
install_sh_SCRIPT = $(install_sh) -c
|
||||||
|
INSTALL_HEADER = $(INSTALL_DATA)
|
||||||
|
transform = $(program_transform_name)
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
build_triplet = @build@
|
||||||
|
host_triplet = @host@
|
||||||
|
subdir = .
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||||
|
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||||
|
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
|
||||||
|
$(am__configure_deps) $(am__DIST_COMMON)
|
||||||
|
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||||
|
configure.lineno config.status.lineno
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
|
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||||
|
libhaikuusb_la_LIBADD =
|
||||||
|
am_libhaikuusb_la_OBJECTS = libhaikuusb_la-haiku_usb_raw.lo \
|
||||||
|
libhaikuusb_la-haiku_usb_backend.lo \
|
||||||
|
libhaikuusb_la-haiku_pollfs.lo
|
||||||
|
libhaikuusb_la_OBJECTS = $(am_libhaikuusb_la_OBJECTS)
|
||||||
|
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||||
|
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||||
|
am__v_lt_0 = --silent
|
||||||
|
am__v_lt_1 =
|
||||||
|
AM_V_P = $(am__v_P_@AM_V@)
|
||||||
|
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||||
|
am__v_P_0 = false
|
||||||
|
am__v_P_1 = :
|
||||||
|
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||||
|
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||||
|
am__v_GEN_0 = @echo " GEN " $@;
|
||||||
|
am__v_GEN_1 =
|
||||||
|
AM_V_at = $(am__v_at_@AM_V@)
|
||||||
|
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||||
|
am__v_at_0 = @
|
||||||
|
am__v_at_1 =
|
||||||
|
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||||
|
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||||
|
am__depfiles_maybe = depfiles
|
||||||
|
am__mv = mv -f
|
||||||
|
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||||
|
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
|
||||||
|
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||||
|
$(AM_CXXFLAGS) $(CXXFLAGS)
|
||||||
|
AM_V_CXX = $(am__v_CXX_@AM_V@)
|
||||||
|
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
|
||||||
|
am__v_CXX_0 = @echo " CXX " $@;
|
||||||
|
am__v_CXX_1 =
|
||||||
|
CXXLD = $(CXX)
|
||||||
|
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||||
|
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
|
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
|
||||||
|
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
|
||||||
|
am__v_CXXLD_0 = @echo " CXXLD " $@;
|
||||||
|
am__v_CXXLD_1 =
|
||||||
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||||
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||||
|
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||||
|
$(AM_CFLAGS) $(CFLAGS)
|
||||||
|
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||||
|
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||||
|
am__v_CC_0 = @echo " CC " $@;
|
||||||
|
am__v_CC_1 =
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
|
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
|
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||||
|
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||||
|
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||||
|
am__v_CCLD_1 =
|
||||||
|
SOURCES = $(libhaikuusb_la_SOURCES)
|
||||||
|
DIST_SOURCES = $(libhaikuusb_la_SOURCES)
|
||||||
|
am__can_run_installinfo = \
|
||||||
|
case $$AM_UPDATE_INFO_DIR in \
|
||||||
|
n|no|NO) false;; \
|
||||||
|
*) (install-info --version) >/dev/null 2>&1;; \
|
||||||
|
esac
|
||||||
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||||
|
# Read a list of newline-separated strings from the standard input,
|
||||||
|
# and print each of them once, without duplicates. Input order is
|
||||||
|
# *not* preserved.
|
||||||
|
am__uniquify_input = $(AWK) '\
|
||||||
|
BEGIN { nonempty = 0; } \
|
||||||
|
{ items[$$0] = 1; nonempty = 1; } \
|
||||||
|
END { if (nonempty) { for (i in items) print i; }; } \
|
||||||
|
'
|
||||||
|
# Make sure the list of sources is unique. This is necessary because,
|
||||||
|
# e.g., the same source file might be shared among _SOURCES variables
|
||||||
|
# for different programs/libraries.
|
||||||
|
am__define_uniq_tagged_files = \
|
||||||
|
list='$(am__tagged_files)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | $(am__uniquify_input)`
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
CSCOPE = cscope
|
||||||
|
AM_RECURSIVE_TARGETS = cscope
|
||||||
|
am__DIST_COMMON = $(srcdir)/Makefile.in compile config.guess \
|
||||||
|
config.sub depcomp install-sh ltmain.sh missing
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
distdir = $(PACKAGE)-$(VERSION)
|
||||||
|
top_distdir = $(distdir)
|
||||||
|
am__remove_distdir = \
|
||||||
|
if test -d "$(distdir)"; then \
|
||||||
|
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||||
|
&& rm -rf "$(distdir)" \
|
||||||
|
|| { sleep 5 && rm -rf "$(distdir)"; }; \
|
||||||
|
else :; fi
|
||||||
|
am__post_remove_distdir = $(am__remove_distdir)
|
||||||
|
DIST_ARCHIVES = $(distdir).tar.gz
|
||||||
|
GZIP_ENV = --best
|
||||||
|
DIST_TARGETS = dist-gzip
|
||||||
|
distuninstallcheck_listfiles = find . -type f -print
|
||||||
|
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
||||||
|
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
||||||
|
distcleancheck_listfiles = find . -type f -print
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||||
|
AR = @AR@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
DLLTOOL = @DLLTOOL@
|
||||||
|
DSYMUTIL = @DSYMUTIL@
|
||||||
|
DUMPBIN = @DUMPBIN@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
FGREP = @FGREP@
|
||||||
|
GREP = @GREP@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LD = @LD@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBOBJS = @LIBOBJS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LIPO = @LIPO@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
NM = @NM@
|
||||||
|
NMEDIT = @NMEDIT@
|
||||||
|
OBJDUMP = @OBJDUMP@
|
||||||
|
OBJEXT = @OBJEXT@
|
||||||
|
OTOOL = @OTOOL@
|
||||||
|
OTOOL64 = @OTOOL64@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||||
|
PACKAGE_NAME = @PACKAGE_NAME@
|
||||||
|
PACKAGE_STRING = @PACKAGE_STRING@
|
||||||
|
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||||
|
PACKAGE_URL = @PACKAGE_URL@
|
||||||
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
SED = @SED@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_AR = @ac_ct_AR@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||||
|
am__include = @am__include@
|
||||||
|
am__leading_dot = @am__leading_dot@
|
||||||
|
am__quote = @am__quote@
|
||||||
|
am__tar = @am__tar@
|
||||||
|
am__untar = @am__untar@
|
||||||
|
bindir = @bindir@
|
||||||
|
build = @build@
|
||||||
|
build_alias = @build_alias@
|
||||||
|
build_cpu = @build_cpu@
|
||||||
|
build_os = @build_os@
|
||||||
|
build_vendor = @build_vendor@
|
||||||
|
builddir = @builddir@
|
||||||
|
datadir = @datadir@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
docdir = @docdir@
|
||||||
|
dvidir = @dvidir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
host = @host@
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_cpu = @host_cpu@
|
||||||
|
host_os = @host_os@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
htmldir = @htmldir@
|
||||||
|
includedir = @includedir@
|
||||||
|
infodir = @infodir@
|
||||||
|
install_sh = @install_sh@
|
||||||
|
libdir = @libdir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
localedir = @localedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
target_alias = @target_alias@
|
||||||
|
top_build_prefix = @top_build_prefix@
|
||||||
|
top_builddir = @top_builddir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
AUTOMAKE_OPTIONS = subdir-objects
|
||||||
|
noinst_LTLIBRARIES = libhaikuusb.la
|
||||||
|
libhaikuusb_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(srcdir)/../../.. -I$(srcdir)/../../../..
|
||||||
|
libhaikuusb_la_SOURCES = haiku_usb_raw.cpp haiku_usb_backend.cpp haiku_pollfs.cpp haiku_usb_raw.h haiku_usb.h
|
||||||
|
all: all-am
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .cpp .lo .o .obj
|
||||||
|
am--refresh: Makefile
|
||||||
|
@:
|
||||||
|
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
|
@for dep in $?; do \
|
||||||
|
case '$(am__configure_deps)' in \
|
||||||
|
*$$dep*) \
|
||||||
|
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
|
||||||
|
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
|
||||||
|
&& exit 0; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||||
|
$(am__cd) $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --foreign Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
@case '$?' in \
|
||||||
|
*config.status*) \
|
||||||
|
echo ' $(SHELL) ./config.status'; \
|
||||||
|
$(SHELL) ./config.status;; \
|
||||||
|
*) \
|
||||||
|
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||||
|
esac;
|
||||||
|
|
||||||
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
$(SHELL) ./config.status --recheck
|
||||||
|
|
||||||
|
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||||
|
$(am__cd) $(srcdir) && $(AUTOCONF)
|
||||||
|
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||||
|
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||||
|
$(am__aclocal_m4_deps):
|
||||||
|
|
||||||
|
clean-noinstLTLIBRARIES:
|
||||||
|
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||||
|
@list='$(noinst_LTLIBRARIES)'; \
|
||||||
|
locs=`for p in $$list; do echo $$p; done | \
|
||||||
|
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||||
|
sort -u`; \
|
||||||
|
test -z "$$locs" || { \
|
||||||
|
echo rm -f $${locs}; \
|
||||||
|
rm -f $${locs}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
libhaikuusb.la: $(libhaikuusb_la_OBJECTS) $(libhaikuusb_la_DEPENDENCIES) $(EXTRA_libhaikuusb_la_DEPENDENCIES)
|
||||||
|
$(AM_V_CXXLD)$(CXXLINK) $(libhaikuusb_la_OBJECTS) $(libhaikuusb_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.$(OBJEXT)
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhaikuusb_la-haiku_pollfs.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhaikuusb_la-haiku_usb_backend.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhaikuusb_la-haiku_usb_raw.Plo@am__quote@
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||||
|
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||||
|
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
|
||||||
|
|
||||||
|
.cpp.obj:
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
||||||
|
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
||||||
|
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||||
|
|
||||||
|
.cpp.lo:
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
||||||
|
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||||
|
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
|
||||||
|
|
||||||
|
libhaikuusb_la-haiku_usb_raw.lo: haiku_usb_raw.cpp
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhaikuusb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhaikuusb_la-haiku_usb_raw.lo -MD -MP -MF $(DEPDIR)/libhaikuusb_la-haiku_usb_raw.Tpo -c -o libhaikuusb_la-haiku_usb_raw.lo `test -f 'haiku_usb_raw.cpp' || echo '$(srcdir)/'`haiku_usb_raw.cpp
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhaikuusb_la-haiku_usb_raw.Tpo $(DEPDIR)/libhaikuusb_la-haiku_usb_raw.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='haiku_usb_raw.cpp' object='libhaikuusb_la-haiku_usb_raw.lo' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhaikuusb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhaikuusb_la-haiku_usb_raw.lo `test -f 'haiku_usb_raw.cpp' || echo '$(srcdir)/'`haiku_usb_raw.cpp
|
||||||
|
|
||||||
|
libhaikuusb_la-haiku_usb_backend.lo: haiku_usb_backend.cpp
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhaikuusb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhaikuusb_la-haiku_usb_backend.lo -MD -MP -MF $(DEPDIR)/libhaikuusb_la-haiku_usb_backend.Tpo -c -o libhaikuusb_la-haiku_usb_backend.lo `test -f 'haiku_usb_backend.cpp' || echo '$(srcdir)/'`haiku_usb_backend.cpp
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhaikuusb_la-haiku_usb_backend.Tpo $(DEPDIR)/libhaikuusb_la-haiku_usb_backend.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='haiku_usb_backend.cpp' object='libhaikuusb_la-haiku_usb_backend.lo' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhaikuusb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhaikuusb_la-haiku_usb_backend.lo `test -f 'haiku_usb_backend.cpp' || echo '$(srcdir)/'`haiku_usb_backend.cpp
|
||||||
|
|
||||||
|
libhaikuusb_la-haiku_pollfs.lo: haiku_pollfs.cpp
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhaikuusb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libhaikuusb_la-haiku_pollfs.lo -MD -MP -MF $(DEPDIR)/libhaikuusb_la-haiku_pollfs.Tpo -c -o libhaikuusb_la-haiku_pollfs.lo `test -f 'haiku_pollfs.cpp' || echo '$(srcdir)/'`haiku_pollfs.cpp
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhaikuusb_la-haiku_pollfs.Tpo $(DEPDIR)/libhaikuusb_la-haiku_pollfs.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='haiku_pollfs.cpp' object='libhaikuusb_la-haiku_pollfs.lo' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhaikuusb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libhaikuusb_la-haiku_pollfs.lo `test -f 'haiku_pollfs.cpp' || echo '$(srcdir)/'`haiku_pollfs.cpp
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
distclean-libtool:
|
||||||
|
-rm -f libtool config.lt
|
||||||
|
|
||||||
|
ID: $(am__tagged_files)
|
||||||
|
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||||
|
tags: tags-am
|
||||||
|
TAGS: tags
|
||||||
|
|
||||||
|
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
set x; \
|
||||||
|
here=`pwd`; \
|
||||||
|
$(am__define_uniq_tagged_files); \
|
||||||
|
shift; \
|
||||||
|
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||||
|
test -n "$$unique" || unique=$$empty_fix; \
|
||||||
|
if test $$# -gt 0; then \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
"$$@" $$unique; \
|
||||||
|
else \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$unique; \
|
||||||
|
fi; \
|
||||||
|
fi
|
||||||
|
ctags: ctags-am
|
||||||
|
|
||||||
|
CTAGS: ctags
|
||||||
|
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
$(am__define_uniq_tagged_files); \
|
||||||
|
test -z "$(CTAGS_ARGS)$$unique" \
|
||||||
|
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||||
|
$$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& $(am__cd) $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||||
|
cscope: cscope.files
|
||||||
|
test ! -s cscope.files \
|
||||||
|
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
|
||||||
|
clean-cscope:
|
||||||
|
-rm -f cscope.files
|
||||||
|
cscope.files: clean-cscope cscopelist
|
||||||
|
cscopelist: cscopelist-am
|
||||||
|
|
||||||
|
cscopelist-am: $(am__tagged_files)
|
||||||
|
list='$(am__tagged_files)'; \
|
||||||
|
case "$(srcdir)" in \
|
||||||
|
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||||
|
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||||
|
esac; \
|
||||||
|
for i in $$list; do \
|
||||||
|
if test -f "$$i"; then \
|
||||||
|
echo "$(subdir)/$$i"; \
|
||||||
|
else \
|
||||||
|
echo "$$sdir/$$i"; \
|
||||||
|
fi; \
|
||||||
|
done >> $(top_builddir)/cscope.files
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
$(am__remove_distdir)
|
||||||
|
test -d "$(distdir)" || mkdir "$(distdir)"
|
||||||
|
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||||
|
list='$(DISTFILES)'; \
|
||||||
|
dist_files=`for file in $$list; do echo $$file; done | \
|
||||||
|
sed -e "s|^$$srcdirstrip/||;t" \
|
||||||
|
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||||
|
case $$dist_files in \
|
||||||
|
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||||
|
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||||
|
sort -u` ;; \
|
||||||
|
esac; \
|
||||||
|
for file in $$dist_files; do \
|
||||||
|
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||||
|
if test -d $$d/$$file; then \
|
||||||
|
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||||
|
if test -d "$(distdir)/$$file"; then \
|
||||||
|
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||||
|
fi; \
|
||||||
|
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||||
|
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||||
|
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||||
|
fi; \
|
||||||
|
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||||
|
else \
|
||||||
|
test -f "$(distdir)/$$file" \
|
||||||
|
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
-test -n "$(am__skip_mode_fix)" \
|
||||||
|
|| find "$(distdir)" -type d ! -perm -755 \
|
||||||
|
-exec chmod u+rwx,go+rx {} \; -o \
|
||||||
|
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|
||||||
|
|| chmod -R a+r "$(distdir)"
|
||||||
|
dist-gzip: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist-bzip2: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist-lzip: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist-xz: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist-tarZ: distdir
|
||||||
|
@echo WARNING: "Support for distribution archives compressed with" \
|
||||||
|
"legacy program 'compress' is deprecated." >&2
|
||||||
|
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
|
||||||
|
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist-shar: distdir
|
||||||
|
@echo WARNING: "Support for shar distribution archives is" \
|
||||||
|
"deprecated." >&2
|
||||||
|
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
|
||||||
|
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist-zip: distdir
|
||||||
|
-rm -f $(distdir).zip
|
||||||
|
zip -rq $(distdir).zip $(distdir)
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
dist dist-all:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
|
||||||
|
# This target untars the dist file and tries a VPATH configuration. Then
|
||||||
|
# it guarantees that the distribution is self-contained by making another
|
||||||
|
# tarfile.
|
||||||
|
distcheck: dist
|
||||||
|
case '$(DIST_ARCHIVES)' in \
|
||||||
|
*.tar.gz*) \
|
||||||
|
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
|
||||||
|
*.tar.bz2*) \
|
||||||
|
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
|
||||||
|
*.tar.lz*) \
|
||||||
|
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
|
||||||
|
*.tar.xz*) \
|
||||||
|
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
|
||||||
|
*.tar.Z*) \
|
||||||
|
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
||||||
|
*.shar.gz*) \
|
||||||
|
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
|
||||||
|
*.zip*) \
|
||||||
|
unzip $(distdir).zip ;;\
|
||||||
|
esac
|
||||||
|
chmod -R a-w $(distdir)
|
||||||
|
chmod u+w $(distdir)
|
||||||
|
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
|
||||||
|
chmod a-w $(distdir)
|
||||||
|
test -d $(distdir)/_build || exit 0; \
|
||||||
|
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||||
|
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||||
|
&& am__cwd=`pwd` \
|
||||||
|
&& $(am__cd) $(distdir)/_build/sub \
|
||||||
|
&& ../../configure \
|
||||||
|
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
|
||||||
|
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||||
|
--srcdir=../.. --prefix="$$dc_install_base" \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||||
|
distuninstallcheck \
|
||||||
|
&& chmod -R a-w "$$dc_install_base" \
|
||||||
|
&& ({ \
|
||||||
|
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||||
|
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||||
|
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||||
|
&& rm -rf "$$dc_destdir" \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
||||||
|
&& rm -rf $(DIST_ARCHIVES) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
|
||||||
|
&& cd "$$am__cwd" \
|
||||||
|
|| exit 1
|
||||||
|
$(am__post_remove_distdir)
|
||||||
|
@(echo "$(distdir) archives ready for distribution: "; \
|
||||||
|
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
||||||
|
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
|
||||||
|
distuninstallcheck:
|
||||||
|
@test -n '$(distuninstallcheck_dir)' || { \
|
||||||
|
echo 'ERROR: trying to run $@ with an empty' \
|
||||||
|
'$$(distuninstallcheck_dir)' >&2; \
|
||||||
|
exit 1; \
|
||||||
|
}; \
|
||||||
|
$(am__cd) '$(distuninstallcheck_dir)' || { \
|
||||||
|
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
|
||||||
|
exit 1; \
|
||||||
|
}; \
|
||||||
|
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|
||||||
|
|| { echo "ERROR: files left after uninstall:" ; \
|
||||||
|
if test -n "$(DESTDIR)"; then \
|
||||||
|
echo " (check DESTDIR support)"; \
|
||||||
|
fi ; \
|
||||||
|
$(distuninstallcheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
distcleancheck: distclean
|
||||||
|
@if test '$(srcdir)' = . ; then \
|
||||||
|
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
||||||
|
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||||
|
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||||
|
$(distcleancheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
check-am: all-am
|
||||||
|
check: check-am
|
||||||
|
all-am: Makefile $(LTLIBRARIES)
|
||||||
|
installdirs:
|
||||||
|
install: install-am
|
||||||
|
install-exec: install-exec-am
|
||||||
|
install-data: install-data-am
|
||||||
|
uninstall: uninstall-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-strip:
|
||||||
|
if test -z '$(STRIP)'; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
install; \
|
||||||
|
else \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||||
|
fi
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||||
|
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-am
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
|
||||||
|
mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-am
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
-rm -f Makefile
|
||||||
|
distclean-am: clean-am distclean-compile distclean-generic \
|
||||||
|
distclean-libtool distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-am
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
html: html-am
|
||||||
|
|
||||||
|
html-am:
|
||||||
|
|
||||||
|
info: info-am
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-dvi: install-dvi-am
|
||||||
|
|
||||||
|
install-dvi-am:
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-html: install-html-am
|
||||||
|
|
||||||
|
install-html-am:
|
||||||
|
|
||||||
|
install-info: install-info-am
|
||||||
|
|
||||||
|
install-info-am:
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
install-pdf: install-pdf-am
|
||||||
|
|
||||||
|
install-pdf-am:
|
||||||
|
|
||||||
|
install-ps: install-ps-am
|
||||||
|
|
||||||
|
install-ps-am:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -rf $(top_srcdir)/autom4te.cache
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
-rm -f Makefile
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||||
|
mostlyclean-libtool
|
||||||
|
|
||||||
|
pdf: pdf-am
|
||||||
|
|
||||||
|
pdf-am:
|
||||||
|
|
||||||
|
ps: ps-am
|
||||||
|
|
||||||
|
ps-am:
|
||||||
|
|
||||||
|
uninstall-am:
|
||||||
|
|
||||||
|
.MAKE: install-am install-strip
|
||||||
|
|
||||||
|
.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
|
||||||
|
clean-cscope clean-generic clean-libtool \
|
||||||
|
clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \
|
||||||
|
dist dist-all dist-bzip2 dist-gzip dist-lzip dist-shar \
|
||||||
|
dist-tarZ dist-xz dist-zip distcheck distclean \
|
||||||
|
distclean-compile distclean-generic distclean-libtool \
|
||||||
|
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
||||||
|
dvi-am html html-am info info-am install install-am \
|
||||||
|
install-data install-data-am install-dvi install-dvi-am \
|
||||||
|
install-exec install-exec-am install-html install-html-am \
|
||||||
|
install-info install-info-am install-man install-pdf \
|
||||||
|
install-pdf-am install-ps install-ps-am install-strip \
|
||||||
|
installcheck installcheck-am installdirs maintainer-clean \
|
||||||
|
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||||
|
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||||
|
tags tags-am uninstall uninstall-am
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,347 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Wrapper for compilers which do not understand '-c -o'.
|
||||||
|
|
||||||
|
scriptversion=2012-10-14.11; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# This file is maintained in Automake, please report
|
||||||
|
# bugs to <bug-automake@gnu.org> or send patches to
|
||||||
|
# <automake-patches@gnu.org>.
|
||||||
|
|
||||||
|
nl='
|
||||||
|
'
|
||||||
|
|
||||||
|
# We need space, tab and new line, in precisely that order. Quoting is
|
||||||
|
# there to prevent tools from complaining about whitespace usage.
|
||||||
|
IFS=" "" $nl"
|
||||||
|
|
||||||
|
file_conv=
|
||||||
|
|
||||||
|
# func_file_conv build_file lazy
|
||||||
|
# Convert a $build file to $host form and store it in $file
|
||||||
|
# Currently only supports Windows hosts. If the determined conversion
|
||||||
|
# type is listed in (the comma separated) LAZY, no conversion will
|
||||||
|
# take place.
|
||||||
|
func_file_conv ()
|
||||||
|
{
|
||||||
|
file=$1
|
||||||
|
case $file in
|
||||||
|
/ | /[!/]*) # absolute file, and not a UNC file
|
||||||
|
if test -z "$file_conv"; then
|
||||||
|
# lazily determine how to convert abs files
|
||||||
|
case `uname -s` in
|
||||||
|
MINGW*)
|
||||||
|
file_conv=mingw
|
||||||
|
;;
|
||||||
|
CYGWIN*)
|
||||||
|
file_conv=cygwin
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
file_conv=wine
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
case $file_conv/,$2, in
|
||||||
|
*,$file_conv,*)
|
||||||
|
;;
|
||||||
|
mingw/*)
|
||||||
|
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||||
|
;;
|
||||||
|
cygwin/*)
|
||||||
|
file=`cygpath -m "$file" || echo "$file"`
|
||||||
|
;;
|
||||||
|
wine/*)
|
||||||
|
file=`winepath -w "$file" || echo "$file"`
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# func_cl_dashL linkdir
|
||||||
|
# Make cl look for libraries in LINKDIR
|
||||||
|
func_cl_dashL ()
|
||||||
|
{
|
||||||
|
func_file_conv "$1"
|
||||||
|
if test -z "$lib_path"; then
|
||||||
|
lib_path=$file
|
||||||
|
else
|
||||||
|
lib_path="$lib_path;$file"
|
||||||
|
fi
|
||||||
|
linker_opts="$linker_opts -LIBPATH:$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# func_cl_dashl library
|
||||||
|
# Do a library search-path lookup for cl
|
||||||
|
func_cl_dashl ()
|
||||||
|
{
|
||||||
|
lib=$1
|
||||||
|
found=no
|
||||||
|
save_IFS=$IFS
|
||||||
|
IFS=';'
|
||||||
|
for dir in $lib_path $LIB
|
||||||
|
do
|
||||||
|
IFS=$save_IFS
|
||||||
|
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||||
|
found=yes
|
||||||
|
lib=$dir/$lib.dll.lib
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -f "$dir/$lib.lib"; then
|
||||||
|
found=yes
|
||||||
|
lib=$dir/$lib.lib
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -f "$dir/lib$lib.a"; then
|
||||||
|
found=yes
|
||||||
|
lib=$dir/lib$lib.a
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS=$save_IFS
|
||||||
|
|
||||||
|
if test "$found" != yes; then
|
||||||
|
lib=$lib.lib
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# func_cl_wrapper cl arg...
|
||||||
|
# Adjust compile command to suit cl
|
||||||
|
func_cl_wrapper ()
|
||||||
|
{
|
||||||
|
# Assume a capable shell
|
||||||
|
lib_path=
|
||||||
|
shared=:
|
||||||
|
linker_opts=
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.[oO][bB][jJ])
|
||||||
|
func_file_conv "$2"
|
||||||
|
set x "$@" -Fo"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
func_file_conv "$2"
|
||||||
|
set x "$@" -Fe"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
-I)
|
||||||
|
eat=1
|
||||||
|
func_file_conv "$2" mingw
|
||||||
|
set x "$@" -I"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-I*)
|
||||||
|
func_file_conv "${1#-I}" mingw
|
||||||
|
set x "$@" -I"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-l)
|
||||||
|
eat=1
|
||||||
|
func_cl_dashl "$2"
|
||||||
|
set x "$@" "$lib"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-l*)
|
||||||
|
func_cl_dashl "${1#-l}"
|
||||||
|
set x "$@" "$lib"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-L)
|
||||||
|
eat=1
|
||||||
|
func_cl_dashL "$2"
|
||||||
|
;;
|
||||||
|
-L*)
|
||||||
|
func_cl_dashL "${1#-L}"
|
||||||
|
;;
|
||||||
|
-static)
|
||||||
|
shared=false
|
||||||
|
;;
|
||||||
|
-Wl,*)
|
||||||
|
arg=${1#-Wl,}
|
||||||
|
save_ifs="$IFS"; IFS=','
|
||||||
|
for flag in $arg; do
|
||||||
|
IFS="$save_ifs"
|
||||||
|
linker_opts="$linker_opts $flag"
|
||||||
|
done
|
||||||
|
IFS="$save_ifs"
|
||||||
|
;;
|
||||||
|
-Xlinker)
|
||||||
|
eat=1
|
||||||
|
linker_opts="$linker_opts $2"
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||||
|
func_file_conv "$1"
|
||||||
|
set x "$@" -Tp"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||||
|
func_file_conv "$1" mingw
|
||||||
|
set x "$@" "$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
if test -n "$linker_opts"; then
|
||||||
|
linker_opts="-link$linker_opts"
|
||||||
|
fi
|
||||||
|
exec "$@" $linker_opts
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
eat=
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Wrapper for compilers which do not understand '-c -o'.
|
||||||
|
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||||
|
arguments, and rename the output as expected.
|
||||||
|
|
||||||
|
If you are trying to build a whole package this is not the
|
||||||
|
right script to run: please start by reading the file 'INSTALL'.
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "compile $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||||
|
func_cl_wrapper "$@" # Doesn't return...
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ofile=
|
||||||
|
cfile=
|
||||||
|
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||||
|
# So we strip '-o arg' only if arg is an object.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.obj)
|
||||||
|
ofile=$2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" -o "$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*.c)
|
||||||
|
cfile=$1
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$ofile" || test -z "$cfile"; then
|
||||||
|
# If no '-o' option was seen then we might have been invoked from a
|
||||||
|
# pattern rule where we don't need one. That is ok -- this is a
|
||||||
|
# normal compilation that the losing compiler can handle. If no
|
||||||
|
# '.c' file was seen then we are probably linking. That is also
|
||||||
|
# ok.
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Name of file we expect compiler to create.
|
||||||
|
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||||
|
|
||||||
|
# Create the lock directory.
|
||||||
|
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||||
|
# that we are using for the .o file. Also, base the name on the expected
|
||||||
|
# object file name, since that is what matters with a parallel build.
|
||||||
|
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||||
|
while true; do
|
||||||
|
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# FIXME: race condition here if user kills between mkdir and trap.
|
||||||
|
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||||
|
|
||||||
|
# Run the compile.
|
||||||
|
"$@"
|
||||||
|
ret=$?
|
||||||
|
|
||||||
|
if test -f "$cofile"; then
|
||||||
|
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||||
|
elif test -f "${cofile}bj"; then
|
||||||
|
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir "$lockdir"
|
||||||
|
exit $ret
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
||||||
|
AC_INIT([haikuusb], [1.0])
|
||||||
|
AM_INIT_AUTOMAKE([no-define foreign])
|
||||||
|
AM_MAINTAINER_MODE
|
||||||
|
LT_INIT
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_CONFIG_FILES([Makefile])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
AC_OUTPUT
|
|
@ -0,0 +1,791 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# depcomp - compile a program generating dependencies as side-effects
|
||||||
|
|
||||||
|
scriptversion=2013-05-30.07; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||||
|
as side-effects.
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
depmode Dependency tracking mode.
|
||||||
|
source Source file read by 'PROGRAMS ARGS'.
|
||||||
|
object Object file output by 'PROGRAMS ARGS'.
|
||||||
|
DEPDIR directory where to store dependencies.
|
||||||
|
depfile Dependency file to output.
|
||||||
|
tmpdepfile Temporary file to use when outputting dependencies.
|
||||||
|
libtool Whether libtool is used (yes/no).
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "depcomp $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Get the directory component of the given path, and save it in the
|
||||||
|
# global variables '$dir'. Note that this directory component will
|
||||||
|
# be either empty or ending with a '/' character. This is deliberate.
|
||||||
|
set_dir_from ()
|
||||||
|
{
|
||||||
|
case $1 in
|
||||||
|
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||||
|
*) dir=;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the suffix-stripped basename of the given path, and save it the
|
||||||
|
# global variable '$base'.
|
||||||
|
set_base_from ()
|
||||||
|
{
|
||||||
|
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||||
|
}
|
||||||
|
|
||||||
|
# If no dependency file was actually created by the compiler invocation,
|
||||||
|
# we still have to create a dummy depfile, to avoid errors with the
|
||||||
|
# Makefile "include basename.Plo" scheme.
|
||||||
|
make_dummy_depfile ()
|
||||||
|
{
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Factor out some common post-processing of the generated depfile.
|
||||||
|
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||||
|
aix_post_process_depfile ()
|
||||||
|
{
|
||||||
|
# If the compiler actually managed to produce a dependency file,
|
||||||
|
# post-process it.
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
# Each line is of the form 'foo.o: dependency.h'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# $object: dependency.h
|
||||||
|
# and one to simply output
|
||||||
|
# dependency.h:
|
||||||
|
# which is needed to avoid the deleted-header problem.
|
||||||
|
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||||
|
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||||
|
} > "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
else
|
||||||
|
make_dummy_depfile
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# A tabulation character.
|
||||||
|
tab=' '
|
||||||
|
# A newline character.
|
||||||
|
nl='
|
||||||
|
'
|
||||||
|
# Character ranges might be problematic outside the C locale.
|
||||||
|
# These definitions help.
|
||||||
|
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||||
|
lower=abcdefghijklmnopqrstuvwxyz
|
||||||
|
digits=0123456789
|
||||||
|
alpha=${upper}${lower}
|
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||||
|
depfile=${depfile-`echo "$object" |
|
||||||
|
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||||
|
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
|
||||||
|
# Avoid interferences from the environment.
|
||||||
|
gccflag= dashmflag=
|
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We
|
||||||
|
# parameterize here, but still list the modes in the big case below,
|
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||||
|
# here, because this file can only contain one case statement.
|
||||||
|
if test "$depmode" = hp; then
|
||||||
|
# HP compiler uses -M and no extra arg.
|
||||||
|
gccflag=-M
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then
|
||||||
|
# This is just like dashmstdout with a different argument.
|
||||||
|
dashmflag=-xM
|
||||||
|
depmode=dashmstdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
cygpath_u="cygpath -u -f -"
|
||||||
|
if test "$depmode" = msvcmsys; then
|
||||||
|
# This is just like msvisualcpp but w/o cygpath translation.
|
||||||
|
# Just convert the backslash-escaped backslashes to single forward
|
||||||
|
# slashes to satisfy depend.m4
|
||||||
|
cygpath_u='sed s,\\\\,/,g'
|
||||||
|
depmode=msvisualcpp
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = msvc7msys; then
|
||||||
|
# This is just like msvc7 but w/o cygpath translation.
|
||||||
|
# Just convert the backslash-escaped backslashes to single forward
|
||||||
|
# slashes to satisfy depend.m4
|
||||||
|
cygpath_u='sed s,\\\\,/,g'
|
||||||
|
depmode=msvc7
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = xlc; then
|
||||||
|
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||||
|
gccflag=-qmakedep=gcc,-MF
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$depmode" in
|
||||||
|
gcc3)
|
||||||
|
## gcc 3 implements dependency tracking that does exactly what
|
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||||
|
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||||
|
## the command line argument order; so add the flags where they
|
||||||
|
## appear in depend2.am. Note that the slowdown incurred here
|
||||||
|
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||||
|
*) set fnord "$@" "$arg" ;;
|
||||||
|
esac
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
done
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
mv "$tmpdepfile" "$depfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
gcc)
|
||||||
|
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||||
|
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||||
|
## (see the conditional assignment to $gccflag above).
|
||||||
|
## There are various ways to get dependency output from gcc. Here's
|
||||||
|
## why we pick this rather obscure method:
|
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end
|
||||||
|
## up in a subdir. Having to rename by hand is ugly.
|
||||||
|
## (We might end up doing this anyway to support other compilers.)
|
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||||
|
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||||
|
## supported by the other compilers which use the 'gcc' depmode.
|
||||||
|
## - Using -M directly means running the compiler twice (even worse
|
||||||
|
## than renaming).
|
||||||
|
if test -z "$gccflag"; then
|
||||||
|
gccflag=-MD,
|
||||||
|
fi
|
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
# The second -e expression handles DOS-style file names with drive
|
||||||
|
# letters.
|
||||||
|
sed -e 's/^[^:]*: / /' \
|
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||||
|
## This next piece of magic avoids the "deleted header file" problem.
|
||||||
|
## The problem is that when a header file which appears in a .P file
|
||||||
|
## is deleted, the dependency causes make to die (because there is
|
||||||
|
## typically no way to rebuild the header). We avoid this by adding
|
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||||
|
## this for us directly.
|
||||||
|
## Some versions of gcc put a space before the ':'. On the theory
|
||||||
|
## that the space means something, we add a space to the output as
|
||||||
|
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||||
|
## to the object. Take care to not repeat it in the output.
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
sgi)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||||
|
else
|
||||||
|
"$@" -MDupdate "$tmpdepfile"
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
# Clip off the initial element (the dependent). Don't try to be
|
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle
|
||||||
|
# lines with more than a fixed number of characters (4096 in
|
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||||
|
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||||
|
# dependency line.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||||
|
| tr "$nl" ' ' >> "$depfile"
|
||||||
|
echo >> "$depfile"
|
||||||
|
# The second pass generates a dummy entry for each header file.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||||
|
>> "$depfile"
|
||||||
|
else
|
||||||
|
make_dummy_depfile
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
xlc)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
aix)
|
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||||
|
# in a .u file. In older versions, this file always lives in the
|
||||||
|
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||||
|
# start of each line; $object doesn't have directory information.
|
||||||
|
# Version 6 uses the directory in both cases.
|
||||||
|
set_dir_from "$object"
|
||||||
|
set_base_from "$object"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
tmpdepfile1=$dir$base.u
|
||||||
|
tmpdepfile2=$base.u
|
||||||
|
tmpdepfile3=$dir.libs/$base.u
|
||||||
|
"$@" -Wc,-M
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.u
|
||||||
|
tmpdepfile2=$dir$base.u
|
||||||
|
tmpdepfile3=$dir$base.u
|
||||||
|
"$@" -M
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
aix_post_process_depfile
|
||||||
|
;;
|
||||||
|
|
||||||
|
tcc)
|
||||||
|
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||||
|
# FIXME: That version still under development at the moment of writing.
|
||||||
|
# Make that this statement remains true also for stable, released
|
||||||
|
# versions.
|
||||||
|
# It will wrap lines (doesn't matter whether long or short) with a
|
||||||
|
# trailing '\', as in:
|
||||||
|
#
|
||||||
|
# foo.o : \
|
||||||
|
# foo.c \
|
||||||
|
# foo.h \
|
||||||
|
#
|
||||||
|
# It will put a trailing '\' even on the last line, and will use leading
|
||||||
|
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||||
|
# "Emit spaces for -MD").
|
||||||
|
"$@" -MD -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||||
|
# We have to change lines of the first kind to '$object: \'.
|
||||||
|
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||||
|
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||||
|
# dummy dependency, to avoid the deleted-header problem.
|
||||||
|
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
## The order of this option in the case statement is important, since the
|
||||||
|
## shell code in configure will try each of these formats in the order
|
||||||
|
## listed in this file. A plain '-MD' option would be understood by many
|
||||||
|
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||||
|
pgcc)
|
||||||
|
# Portland's C compiler understands '-MD'.
|
||||||
|
# Will always output deps to 'file.d' where file is the root name of the
|
||||||
|
# source file under compilation, even if file resides in a subdirectory.
|
||||||
|
# The object file name does not affect the name of the '.d' file.
|
||||||
|
# pgcc 10.2 will output
|
||||||
|
# foo.o: sub/foo.c sub/foo.h
|
||||||
|
# and will wrap long lines using '\' :
|
||||||
|
# foo.o: sub/foo.c ... \
|
||||||
|
# sub/foo.h ... \
|
||||||
|
# ...
|
||||||
|
set_dir_from "$object"
|
||||||
|
# Use the source, not the object, to determine the base name, since
|
||||||
|
# that's sadly what pgcc will do too.
|
||||||
|
set_base_from "$source"
|
||||||
|
tmpdepfile=$base.d
|
||||||
|
|
||||||
|
# For projects that build the same source file twice into different object
|
||||||
|
# files, the pgcc approach of using the *source* file root name can cause
|
||||||
|
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||||
|
# the same $tmpdepfile.
|
||||||
|
lockdir=$base.d-lock
|
||||||
|
trap "
|
||||||
|
echo '$0: caught signal, cleaning up...' >&2
|
||||||
|
rmdir '$lockdir'
|
||||||
|
exit 1
|
||||||
|
" 1 2 13 15
|
||||||
|
numtries=100
|
||||||
|
i=$numtries
|
||||||
|
while test $i -gt 0; do
|
||||||
|
# mkdir is a portable test-and-set.
|
||||||
|
if mkdir "$lockdir" 2>/dev/null; then
|
||||||
|
# This process acquired the lock.
|
||||||
|
"$@" -MD
|
||||||
|
stat=$?
|
||||||
|
# Release the lock.
|
||||||
|
rmdir "$lockdir"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
# If the lock is being held by a different process, wait
|
||||||
|
# until the winning process is done or we timeout.
|
||||||
|
while test -d "$lockdir" && test $i -gt 0; do
|
||||||
|
sleep 1
|
||||||
|
i=`expr $i - 1`
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
i=`expr $i - 1`
|
||||||
|
done
|
||||||
|
trap - 1 2 13 15
|
||||||
|
if test $i -le 0; then
|
||||||
|
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||||
|
echo "$0: check lockdir '$lockdir'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
# Each line is of the form `foo.o: dependent.h',
|
||||||
|
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp2)
|
||||||
|
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||||
|
# compilers, which have integrated preprocessors. The correct option
|
||||||
|
# to use with these is +Maked; it writes dependencies to a file named
|
||||||
|
# 'foo.d', which lands next to the object file, wherever that
|
||||||
|
# happens to be.
|
||||||
|
# Much of this is similar to the tru64 case; see comments there.
|
||||||
|
set_dir_from "$object"
|
||||||
|
set_base_from "$object"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
tmpdepfile1=$dir$base.d
|
||||||
|
tmpdepfile2=$dir.libs/$base.d
|
||||||
|
"$@" -Wc,+Maked
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.d
|
||||||
|
tmpdepfile2=$dir$base.d
|
||||||
|
"$@" +Maked
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||||
|
# Add 'dependent.h:' lines.
|
||||||
|
sed -ne '2,${
|
||||||
|
s/^ *//
|
||||||
|
s/ \\*$//
|
||||||
|
s/$/:/
|
||||||
|
p
|
||||||
|
}' "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
make_dummy_depfile
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||||
|
;;
|
||||||
|
|
||||||
|
tru64)
|
||||||
|
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||||
|
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||||
|
# dependencies in 'foo.d' instead, so we check for that too.
|
||||||
|
# Subdirectories are respected.
|
||||||
|
set_dir_from "$object"
|
||||||
|
set_base_from "$object"
|
||||||
|
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||||
|
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||||
|
# in $dir$base.o.d. We have to check for both files, because
|
||||||
|
# one of the two compilations can be disabled. We should prefer
|
||||||
|
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||||
|
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||||
|
# the former would cause a distcleancheck panic.
|
||||||
|
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||||
|
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||||
|
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||||
|
"$@" -Wc,-MD
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.d
|
||||||
|
tmpdepfile2=$dir$base.d
|
||||||
|
tmpdepfile3=$dir$base.d
|
||||||
|
"$@" -MD
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
# Same post-processing that is required for AIX mode.
|
||||||
|
aix_post_process_depfile
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvc7)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
showIncludes=-Wc,-showIncludes
|
||||||
|
else
|
||||||
|
showIncludes=-showIncludes
|
||||||
|
fi
|
||||||
|
"$@" $showIncludes > "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
# The first sed program below extracts the file names and escapes
|
||||||
|
# backslashes for cygpath. The second sed program outputs the file
|
||||||
|
# name when reading, but also accumulates all include files in the
|
||||||
|
# hold buffer in order to output them again at the end. This only
|
||||||
|
# works with sed implementations that can handle large buffers.
|
||||||
|
sed < "$tmpdepfile" -n '
|
||||||
|
/^Note: including file: *\(.*\)/ {
|
||||||
|
s//\1/
|
||||||
|
s/\\/\\\\/g
|
||||||
|
p
|
||||||
|
}' | $cygpath_u | sort -u | sed -n '
|
||||||
|
s/ /\\ /g
|
||||||
|
s/\(.*\)/'"$tab"'\1 \\/p
|
||||||
|
s/.\(.*\) \\/\1:/
|
||||||
|
H
|
||||||
|
$ {
|
||||||
|
s/.*/'"$tab"'/
|
||||||
|
G
|
||||||
|
p
|
||||||
|
}' >> "$depfile"
|
||||||
|
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvc7msys)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
#nosideeffect)
|
||||||
|
# This comment above is used by automake to tell side-effect
|
||||||
|
# dependency tracking mechanisms from slower ones.
|
||||||
|
|
||||||
|
dashmstdout)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout, regardless of -o.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove '-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
test -z "$dashmflag" && dashmflag=-M
|
||||||
|
# Require at least two characters before searching for ':'
|
||||||
|
# in the target name. This is to cope with DOS-style filenames:
|
||||||
|
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||||
|
"$@" $dashmflag |
|
||||||
|
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
dashXmstdout)
|
||||||
|
# This case only exists to satisfy depend.m4. It is never actually
|
||||||
|
# run, as this mode is specially recognized in the preamble.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
makedepend)
|
||||||
|
"$@" || exit $?
|
||||||
|
# Remove any Libtool call
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
# X makedepend
|
||||||
|
shift
|
||||||
|
cleared=no eat=no
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $cleared in
|
||||||
|
no)
|
||||||
|
set ""; shift
|
||||||
|
cleared=yes ;;
|
||||||
|
esac
|
||||||
|
if test $eat = yes; then
|
||||||
|
eat=no
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
case "$arg" in
|
||||||
|
-D*|-I*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
# Strip any option that makedepend may not understand. Remove
|
||||||
|
# the object too, otherwise makedepend will parse it as a source file.
|
||||||
|
-arch)
|
||||||
|
eat=yes ;;
|
||||||
|
-*|$object)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||||
|
touch "$tmpdepfile"
|
||||||
|
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||||
|
rm -f "$depfile"
|
||||||
|
# makedepend may prepend the VPATH from the source file name to the object.
|
||||||
|
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||||
|
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed '1,2d' "$tmpdepfile" \
|
||||||
|
| tr ' ' "$nl" \
|
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||||
|
;;
|
||||||
|
|
||||||
|
cpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove '-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
"$@" -E \
|
||||||
|
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||||
|
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||||
|
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
cat < "$tmpdepfile" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvisualcpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||||
|
set fnord "$@"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
"$@" -E 2>/dev/null |
|
||||||
|
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||||
|
echo "$tab" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvcmsys)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
none)
|
||||||
|
exec "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown depmode $depmode" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
|
@ -0,0 +1,378 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
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)
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
|
||||||
|
fLooper = new(std::nothrow) RosterLooper(this);
|
||||||
|
if (fLooper == NULL || ((RosterLooper*)fLooper)->InitCheck() == false)
|
||||||
|
return LIBUSB_ERROR_OTHER;
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
USBRoster::Stop()
|
||||||
|
{
|
||||||
|
if(!fLooper)
|
||||||
|
return;
|
||||||
|
|
||||||
|
((RosterLooper *)fLooper)->Stop();
|
||||||
|
fLooper = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,550 @@
|
||||||
|
/*
|
||||||
|
* 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=0;
|
||||||
|
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&(1<<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|=(1<<inumber);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
USBDeviceHandle::ReleaseInterface(int inumber)
|
||||||
|
{
|
||||||
|
fUSBDevice->ReleaseInterface(inumber);
|
||||||
|
fClaimedInterfaces&=(!(1<<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, //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY
|
||||||
|
sizeof(command)) || command.alternate.status!=B_USB_RAW_STATUS_SUCCESS) {
|
||||||
|
usbi_err(NULL,"Error setting alternate interface");
|
||||||
|
return _errno_to_libusb(command.alternate.status);
|
||||||
|
}
|
||||||
|
usbi_dbg("Setting alternate interface successful");
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 & (1<<interface)) !=0 )
|
||||||
|
return LIBUSB_ERROR_BUSY;
|
||||||
|
fClaimedInterfaces|=(1<<interface);
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBDevice::ReleaseInterface(int interface)
|
||||||
|
{
|
||||||
|
fClaimedInterfaces&=(!(1<<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;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
size=0;
|
||||||
|
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.control.request_type=128;
|
||||||
|
command.control.request=6;
|
||||||
|
command.control.value=(2<<8)|i;
|
||||||
|
command.control.index=0;
|
||||||
|
command.control.length=tmp_config.total_length;
|
||||||
|
command.control.data=fConfigurationDescriptors[i];
|
||||||
|
if(ioctl(fRawFD,B_USB_RAW_COMMAND_CONTROL_TRANSFER,&command,
|
||||||
|
sizeof(command)) || command.control.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;
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* 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_init(struct libusb_context* ctx)
|
||||||
|
{
|
||||||
|
if (atomic_add(&gInitCount, 1) == 0)
|
||||||
|
{
|
||||||
|
return gUsbRoster.Start();
|
||||||
|
}
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
haiku_exit(void)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
const usb_configuration_descriptor* act_config = dev->ActiveConfiguration();
|
||||||
|
if(len>act_config->total_length)
|
||||||
|
{
|
||||||
|
return LIBUSB_ERROR_OVERFLOW;
|
||||||
|
}
|
||||||
|
memcpy(buffer,act_config,len);
|
||||||
|
*host_endian=0;
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,(unsigned char*)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_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 haiku_usb_raw_backend = {
|
||||||
|
/*.name =*/ "Haiku usbfs",
|
||||||
|
/*.caps =*/ 0,
|
||||||
|
/*.init =*/ haiku_init,
|
||||||
|
/*.exit =*/ haiku_exit,
|
||||||
|
/*.get_device_list =*/ NULL,
|
||||||
|
/*.hotplug_poll =*/ 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 =*/ NULL,
|
||||||
|
/*.reset_device =*/ NULL,
|
||||||
|
|
||||||
|
/*.alloc_streams =*/ NULL,
|
||||||
|
/*.free_streams =*/ 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
|
||||||
|
|
||||||
|
/*.device_priv_size =*/ sizeof(USBDevice*),
|
||||||
|
/*.device_handle_priv_size =*/ sizeof(USBDeviceHandle*),
|
||||||
|
/*.transfer_priv_size =*/ sizeof(USBTransfer*),
|
||||||
|
};
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* 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_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;
|
||||||
|
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_
|
|
@ -0,0 +1,501 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
|
scriptversion=2013-12-25.23; # UTC
|
||||||
|
|
||||||
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
|
# following copyright and license.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1994 X Consortium
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||||
|
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# Except as contained in this notice, the name of the X Consortium shall not
|
||||||
|
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||||
|
# ings in this Software without prior written authorization from the X Consor-
|
||||||
|
# tium.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FSF changes to this file are in the public domain.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# 'make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch.
|
||||||
|
|
||||||
|
tab=' '
|
||||||
|
nl='
|
||||||
|
'
|
||||||
|
IFS=" $tab$nl"
|
||||||
|
|
||||||
|
# Set DOITPROG to "echo" to test this script.
|
||||||
|
|
||||||
|
doit=${DOITPROG-}
|
||||||
|
doit_exec=${doit:-exec}
|
||||||
|
|
||||||
|
# Put in absolute file names if you don't have them in your path;
|
||||||
|
# or use environment vars.
|
||||||
|
|
||||||
|
chgrpprog=${CHGRPPROG-chgrp}
|
||||||
|
chmodprog=${CHMODPROG-chmod}
|
||||||
|
chownprog=${CHOWNPROG-chown}
|
||||||
|
cmpprog=${CMPPROG-cmp}
|
||||||
|
cpprog=${CPPROG-cp}
|
||||||
|
mkdirprog=${MKDIRPROG-mkdir}
|
||||||
|
mvprog=${MVPROG-mv}
|
||||||
|
rmprog=${RMPROG-rm}
|
||||||
|
stripprog=${STRIPPROG-strip}
|
||||||
|
|
||||||
|
posix_mkdir=
|
||||||
|
|
||||||
|
# Desired mode of installed file.
|
||||||
|
mode=0755
|
||||||
|
|
||||||
|
chgrpcmd=
|
||||||
|
chmodcmd=$chmodprog
|
||||||
|
chowncmd=
|
||||||
|
mvcmd=$mvprog
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
stripcmd=
|
||||||
|
|
||||||
|
src=
|
||||||
|
dst=
|
||||||
|
dir_arg=
|
||||||
|
dst_arg=
|
||||||
|
|
||||||
|
copy_on_change=false
|
||||||
|
is_target_a_directory=possibly
|
||||||
|
|
||||||
|
usage="\
|
||||||
|
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||||
|
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||||
|
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||||
|
or: $0 [OPTION]... -d DIRECTORIES...
|
||||||
|
|
||||||
|
In the 1st form, copy SRCFILE to DSTFILE.
|
||||||
|
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||||
|
In the 4th, create DIRECTORIES.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help display this help and exit.
|
||||||
|
--version display version info and exit.
|
||||||
|
|
||||||
|
-c (ignored)
|
||||||
|
-C install only if different (preserve the last data modification time)
|
||||||
|
-d create directories instead of installing files.
|
||||||
|
-g GROUP $chgrpprog installed files to GROUP.
|
||||||
|
-m MODE $chmodprog installed files to MODE.
|
||||||
|
-o USER $chownprog installed files to USER.
|
||||||
|
-s $stripprog installed files.
|
||||||
|
-t DIRECTORY install into DIRECTORY.
|
||||||
|
-T report an error if DSTFILE is a directory.
|
||||||
|
|
||||||
|
Environment variables override the default commands:
|
||||||
|
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||||
|
RMPROG STRIPPROG
|
||||||
|
"
|
||||||
|
|
||||||
|
while test $# -ne 0; do
|
||||||
|
case $1 in
|
||||||
|
-c) ;;
|
||||||
|
|
||||||
|
-C) copy_on_change=true;;
|
||||||
|
|
||||||
|
-d) dir_arg=true;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
--help) echo "$usage"; exit $?;;
|
||||||
|
|
||||||
|
-m) mode=$2
|
||||||
|
case $mode in
|
||||||
|
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||||
|
echo "$0: invalid mode: $mode" >&2
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
-s) stripcmd=$stripprog;;
|
||||||
|
|
||||||
|
-t)
|
||||||
|
is_target_a_directory=always
|
||||||
|
dst_arg=$2
|
||||||
|
# Protect names problematic for 'test' and other utilities.
|
||||||
|
case $dst_arg in
|
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||||
|
esac
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
-T) is_target_a_directory=never;;
|
||||||
|
|
||||||
|
--version) echo "$0 $scriptversion"; exit $?;;
|
||||||
|
|
||||||
|
--) shift
|
||||||
|
break;;
|
||||||
|
|
||||||
|
-*) echo "$0: invalid option: $1" >&2
|
||||||
|
exit 1;;
|
||||||
|
|
||||||
|
*) break;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# We allow the use of options -d and -T together, by making -d
|
||||||
|
# take the precedence; this is for compatibility with GNU install.
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
if test -n "$dst_arg"; then
|
||||||
|
echo "$0: target directory not allowed when installing a directory." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||||
|
# When -d is used, all remaining arguments are directories to create.
|
||||||
|
# When -t is used, the destination is already specified.
|
||||||
|
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$dst_arg"; then
|
||||||
|
# $@ is not empty: it contains at least $arg.
|
||||||
|
set fnord "$@" "$dst_arg"
|
||||||
|
shift # fnord
|
||||||
|
fi
|
||||||
|
shift # arg
|
||||||
|
dst_arg=$arg
|
||||||
|
# Protect names problematic for 'test' and other utilities.
|
||||||
|
case $dst_arg in
|
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
echo "$0: no input file specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# It's OK to call 'install-sh -d' without argument.
|
||||||
|
# This can happen when creating conditional directories.
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||||
|
if test ! -d "$dst_arg"; then
|
||||||
|
echo "$0: $dst_arg: Is not a directory." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
do_exit='(exit $ret); exit $ret'
|
||||||
|
trap "ret=129; $do_exit" 1
|
||||||
|
trap "ret=130; $do_exit" 2
|
||||||
|
trap "ret=141; $do_exit" 13
|
||||||
|
trap "ret=143; $do_exit" 15
|
||||||
|
|
||||||
|
# Set umask so as not to create temps with too-generous modes.
|
||||||
|
# However, 'strip' requires both read and write access to temps.
|
||||||
|
case $mode in
|
||||||
|
# Optimize common cases.
|
||||||
|
*644) cp_umask=133;;
|
||||||
|
*755) cp_umask=22;;
|
||||||
|
|
||||||
|
*[0-7])
|
||||||
|
if test -z "$stripcmd"; then
|
||||||
|
u_plus_rw=
|
||||||
|
else
|
||||||
|
u_plus_rw='% 200'
|
||||||
|
fi
|
||||||
|
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||||
|
*)
|
||||||
|
if test -z "$stripcmd"; then
|
||||||
|
u_plus_rw=
|
||||||
|
else
|
||||||
|
u_plus_rw=,u+rw
|
||||||
|
fi
|
||||||
|
cp_umask=$mode$u_plus_rw;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
for src
|
||||||
|
do
|
||||||
|
# Protect names problematic for 'test' and other utilities.
|
||||||
|
case $src in
|
||||||
|
-* | [=\(\)!]) src=./$src;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
dst=$src
|
||||||
|
dstdir=$dst
|
||||||
|
test -d "$dstdir"
|
||||||
|
dstdir_status=$?
|
||||||
|
else
|
||||||
|
|
||||||
|
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
if test ! -f "$src" && test ! -d "$src"; then
|
||||||
|
echo "$0: $src does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dst_arg"; then
|
||||||
|
echo "$0: no destination specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
dst=$dst_arg
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; won't work
|
||||||
|
# if double slashes aren't ignored.
|
||||||
|
if test -d "$dst"; then
|
||||||
|
if test "$is_target_a_directory" = never; then
|
||||||
|
echo "$0: $dst_arg: Is a directory" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
dstdir=$dst
|
||||||
|
dst=$dstdir/`basename "$src"`
|
||||||
|
dstdir_status=0
|
||||||
|
else
|
||||||
|
dstdir=`dirname "$dst"`
|
||||||
|
test -d "$dstdir"
|
||||||
|
dstdir_status=$?
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
obsolete_mkdir_used=false
|
||||||
|
|
||||||
|
if test $dstdir_status != 0; then
|
||||||
|
case $posix_mkdir in
|
||||||
|
'')
|
||||||
|
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||||
|
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||||
|
umask=`umask`
|
||||||
|
case $stripcmd.$umask in
|
||||||
|
# Optimize common cases.
|
||||||
|
*[2367][2367]) mkdir_umask=$umask;;
|
||||||
|
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||||
|
|
||||||
|
*[0-7])
|
||||||
|
mkdir_umask=`expr $umask + 22 \
|
||||||
|
- $umask % 100 % 40 + $umask % 20 \
|
||||||
|
- $umask % 10 % 4 + $umask % 2
|
||||||
|
`;;
|
||||||
|
*) mkdir_umask=$umask,go-w;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# With -d, create the new directory with the user-specified mode.
|
||||||
|
# Otherwise, rely on $mkdir_umask.
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
mkdir_mode=-m$mode
|
||||||
|
else
|
||||||
|
mkdir_mode=
|
||||||
|
fi
|
||||||
|
|
||||||
|
posix_mkdir=false
|
||||||
|
case $umask in
|
||||||
|
*[123567][0-7][0-7])
|
||||||
|
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||||
|
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||||
|
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||||
|
|
||||||
|
if (umask $mkdir_umask &&
|
||||||
|
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
if test -z "$dir_arg" || {
|
||||||
|
# Check for POSIX incompatibilities with -m.
|
||||||
|
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||||
|
# other-writable bit of parent directory when it shouldn't.
|
||||||
|
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||||
|
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||||
|
case $ls_ld_tmpdir in
|
||||||
|
d????-?r-*) different_mode=700;;
|
||||||
|
d????-?--*) different_mode=755;;
|
||||||
|
*) false;;
|
||||||
|
esac &&
|
||||||
|
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||||
|
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||||
|
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
then posix_mkdir=:
|
||||||
|
fi
|
||||||
|
rmdir "$tmpdir/d" "$tmpdir"
|
||||||
|
else
|
||||||
|
# Remove any dirs left behind by ancient mkdir implementations.
|
||||||
|
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||||
|
fi
|
||||||
|
trap '' 0;;
|
||||||
|
esac;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if
|
||||||
|
$posix_mkdir && (
|
||||||
|
umask $mkdir_umask &&
|
||||||
|
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||||
|
)
|
||||||
|
then :
|
||||||
|
else
|
||||||
|
|
||||||
|
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||||
|
# or it failed possibly due to a race condition. Create the
|
||||||
|
# directory the slow way, step by step, checking for races as we go.
|
||||||
|
|
||||||
|
case $dstdir in
|
||||||
|
/*) prefix='/';;
|
||||||
|
[-=\(\)!]*) prefix='./';;
|
||||||
|
*) prefix='';;
|
||||||
|
esac
|
||||||
|
|
||||||
|
oIFS=$IFS
|
||||||
|
IFS=/
|
||||||
|
set -f
|
||||||
|
set fnord $dstdir
|
||||||
|
shift
|
||||||
|
set +f
|
||||||
|
IFS=$oIFS
|
||||||
|
|
||||||
|
prefixes=
|
||||||
|
|
||||||
|
for d
|
||||||
|
do
|
||||||
|
test X"$d" = X && continue
|
||||||
|
|
||||||
|
prefix=$prefix$d
|
||||||
|
if test -d "$prefix"; then
|
||||||
|
prefixes=
|
||||||
|
else
|
||||||
|
if $posix_mkdir; then
|
||||||
|
(umask=$mkdir_umask &&
|
||||||
|
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||||
|
# Don't fail if two instances are running concurrently.
|
||||||
|
test -d "$prefix" || exit 1
|
||||||
|
else
|
||||||
|
case $prefix in
|
||||||
|
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||||
|
*) qprefix=$prefix;;
|
||||||
|
esac
|
||||||
|
prefixes="$prefixes '$qprefix'"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
prefix=$prefix/
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -n "$prefixes"; then
|
||||||
|
# Don't fail if two instances are running concurrently.
|
||||||
|
(umask $mkdir_umask &&
|
||||||
|
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||||
|
test -d "$dstdir" || exit 1
|
||||||
|
obsolete_mkdir_used=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||||
|
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||||
|
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||||
|
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||||
|
else
|
||||||
|
|
||||||
|
# Make a couple of temp file names in the proper directory.
|
||||||
|
dsttmp=$dstdir/_inst.$$_
|
||||||
|
rmtmp=$dstdir/_rm.$$_
|
||||||
|
|
||||||
|
# Trap to clean up those temp files at exit.
|
||||||
|
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||||
|
|
||||||
|
# Copy the file name to the temp name.
|
||||||
|
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits.
|
||||||
|
#
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||||
|
#
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||||
|
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||||
|
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||||
|
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||||
|
|
||||||
|
# If -C, don't bother to copy if it wouldn't change the file.
|
||||||
|
if $copy_on_change &&
|
||||||
|
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||||
|
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||||
|
set -f &&
|
||||||
|
set X $old && old=:$2:$4:$5:$6 &&
|
||||||
|
set X $new && new=:$2:$4:$5:$6 &&
|
||||||
|
set +f &&
|
||||||
|
test "$old" = "$new" &&
|
||||||
|
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
rm -f "$dsttmp"
|
||||||
|
else
|
||||||
|
# Rename the file to the real destination.
|
||||||
|
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||||
|
|
||||||
|
# The rename failed, perhaps because mv can't rename something else
|
||||||
|
# to itself, or perhaps because mv is so ancient that it does not
|
||||||
|
# support -f.
|
||||||
|
{
|
||||||
|
# Now remove or move aside any old file at destination location.
|
||||||
|
# We try this two ways since rm can't unlink itself on some
|
||||||
|
# systems and the destination file might be busy for other
|
||||||
|
# reasons. In this case, the final cleanup might fail but the new
|
||||||
|
# file should still install successfully.
|
||||||
|
{
|
||||||
|
test ! -f "$dst" ||
|
||||||
|
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||||
|
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||||
|
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||||
|
} ||
|
||||||
|
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||||
|
(exit 1); exit 1
|
||||||
|
}
|
||||||
|
} &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
$doit $mvcmd "$dsttmp" "$dst"
|
||||||
|
}
|
||||||
|
fi || exit 1
|
||||||
|
|
||||||
|
trap '' 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,384 @@
|
||||||
|
# Helper functions for option handling. -*- Autoconf -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
|
||||||
|
# Inc.
|
||||||
|
# Written by Gary V. Vaughan, 2004
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 7 ltoptions.m4
|
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||||
|
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
|
||||||
|
# ------------------------------------------
|
||||||
|
m4_define([_LT_MANGLE_OPTION],
|
||||||
|
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
|
||||||
|
# ---------------------------------------
|
||||||
|
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
|
||||||
|
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
|
||||||
|
# saved as a flag.
|
||||||
|
m4_define([_LT_SET_OPTION],
|
||||||
|
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
|
||||||
|
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
|
||||||
|
_LT_MANGLE_DEFUN([$1], [$2]),
|
||||||
|
[m4_warning([Unknown $1 option `$2'])])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||||
|
m4_define([_LT_IF_OPTION],
|
||||||
|
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
|
||||||
|
# are set.
|
||||||
|
m4_define([_LT_UNLESS_OPTIONS],
|
||||||
|
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||||
|
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
|
||||||
|
[m4_define([$0_found])])])[]dnl
|
||||||
|
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
|
||||||
|
])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
|
||||||
|
# ----------------------------------------
|
||||||
|
# OPTION-LIST is a space-separated list of Libtool options associated
|
||||||
|
# with MACRO-NAME. If any OPTION has a matching handler declared with
|
||||||
|
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
|
||||||
|
# the unknown option and exit.
|
||||||
|
m4_defun([_LT_SET_OPTIONS],
|
||||||
|
[# Set options
|
||||||
|
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||||
|
[_LT_SET_OPTION([$1], _LT_Option)])
|
||||||
|
|
||||||
|
m4_if([$1],[LT_INIT],[
|
||||||
|
dnl
|
||||||
|
dnl Simply set some default values (i.e off) if boolean options were not
|
||||||
|
dnl specified:
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
|
||||||
|
])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
|
||||||
|
])
|
||||||
|
dnl
|
||||||
|
dnl If no reference was made to various pairs of opposing options, then
|
||||||
|
dnl we run the default mode handler for the pair. For example, if neither
|
||||||
|
dnl `shared' nor `disable-shared' was passed, we enable building of shared
|
||||||
|
dnl archives by default:
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
|
||||||
|
[_LT_ENABLE_FAST_INSTALL])
|
||||||
|
])
|
||||||
|
])# _LT_SET_OPTIONS
|
||||||
|
|
||||||
|
|
||||||
|
## --------------------------------- ##
|
||||||
|
## Macros to handle LT_INIT options. ##
|
||||||
|
## --------------------------------- ##
|
||||||
|
|
||||||
|
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
|
||||||
|
# -----------------------------------------
|
||||||
|
m4_define([_LT_MANGLE_DEFUN],
|
||||||
|
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
|
||||||
|
|
||||||
|
|
||||||
|
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
|
||||||
|
# -----------------------------------------------
|
||||||
|
m4_define([LT_OPTION_DEFINE],
|
||||||
|
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
|
||||||
|
])# LT_OPTION_DEFINE
|
||||||
|
|
||||||
|
|
||||||
|
# dlopen
|
||||||
|
# ------
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AC_LIBTOOL_DLOPEN],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [dlopen])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||||
|
put the `dlopen' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
|
||||||
|
|
||||||
|
|
||||||
|
# win32-dll
|
||||||
|
# ---------
|
||||||
|
# Declare package support for building win32 dll's.
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
|
||||||
|
[enable_win32_dll=yes
|
||||||
|
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
|
||||||
|
AC_CHECK_TOOL(AS, as, false)
|
||||||
|
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||||
|
AC_CHECK_TOOL(OBJDUMP, objdump, false)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
test -z "$AS" && AS=as
|
||||||
|
_LT_DECL([], [AS], [1], [Assembler program])dnl
|
||||||
|
|
||||||
|
test -z "$DLLTOOL" && DLLTOOL=dlltool
|
||||||
|
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
|
||||||
|
|
||||||
|
test -z "$OBJDUMP" && OBJDUMP=objdump
|
||||||
|
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
|
||||||
|
])# win32-dll
|
||||||
|
|
||||||
|
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
|
||||||
|
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||||
|
_LT_SET_OPTION([LT_INIT], [win32-dll])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||||
|
put the `win32-dll' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_SHARED([DEFAULT])
|
||||||
|
# ----------------------------
|
||||||
|
# implement the --enable-shared flag, and supports the `shared' and
|
||||||
|
# `disable-shared' LT_INIT options.
|
||||||
|
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||||
|
m4_define([_LT_ENABLE_SHARED],
|
||||||
|
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||||
|
AC_ARG_ENABLE([shared],
|
||||||
|
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
|
||||||
|
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
|
||||||
|
[p=${PACKAGE-default}
|
||||||
|
case $enableval in
|
||||||
|
yes) enable_shared=yes ;;
|
||||||
|
no) enable_shared=no ;;
|
||||||
|
*)
|
||||||
|
enable_shared=no
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for pkg in $enableval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$pkg" = "X$p"; then
|
||||||
|
enable_shared=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
|
||||||
|
|
||||||
|
_LT_DECL([build_libtool_libs], [enable_shared], [0],
|
||||||
|
[Whether or not to build shared libraries])
|
||||||
|
])# _LT_ENABLE_SHARED
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
|
||||||
|
|
||||||
|
# Old names:
|
||||||
|
AC_DEFUN([AC_ENABLE_SHARED],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AC_DISABLE_SHARED],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-shared])
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
|
||||||
|
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
|
||||||
|
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_STATIC([DEFAULT])
|
||||||
|
# ----------------------------
|
||||||
|
# implement the --enable-static flag, and support the `static' and
|
||||||
|
# `disable-static' LT_INIT options.
|
||||||
|
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||||
|
m4_define([_LT_ENABLE_STATIC],
|
||||||
|
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||||
|
AC_ARG_ENABLE([static],
|
||||||
|
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
|
||||||
|
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
|
||||||
|
[p=${PACKAGE-default}
|
||||||
|
case $enableval in
|
||||||
|
yes) enable_static=yes ;;
|
||||||
|
no) enable_static=no ;;
|
||||||
|
*)
|
||||||
|
enable_static=no
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for pkg in $enableval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$pkg" = "X$p"; then
|
||||||
|
enable_static=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
|
||||||
|
|
||||||
|
_LT_DECL([build_old_libs], [enable_static], [0],
|
||||||
|
[Whether or not to build static libraries])
|
||||||
|
])# _LT_ENABLE_STATIC
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
|
||||||
|
|
||||||
|
# Old names:
|
||||||
|
AC_DEFUN([AC_ENABLE_STATIC],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AC_DISABLE_STATIC],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-static])
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
|
||||||
|
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
|
||||||
|
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
|
||||||
|
# ----------------------------------
|
||||||
|
# implement the --enable-fast-install flag, and support the `fast-install'
|
||||||
|
# and `disable-fast-install' LT_INIT options.
|
||||||
|
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||||
|
m4_define([_LT_ENABLE_FAST_INSTALL],
|
||||||
|
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||||
|
AC_ARG_ENABLE([fast-install],
|
||||||
|
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
|
||||||
|
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
|
||||||
|
[p=${PACKAGE-default}
|
||||||
|
case $enableval in
|
||||||
|
yes) enable_fast_install=yes ;;
|
||||||
|
no) enable_fast_install=no ;;
|
||||||
|
*)
|
||||||
|
enable_fast_install=no
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for pkg in $enableval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$pkg" = "X$p"; then
|
||||||
|
enable_fast_install=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
|
||||||
|
|
||||||
|
_LT_DECL([fast_install], [enable_fast_install], [0],
|
||||||
|
[Whether or not to optimize for fast installation])dnl
|
||||||
|
])# _LT_ENABLE_FAST_INSTALL
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
|
||||||
|
|
||||||
|
# Old names:
|
||||||
|
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||||
|
the `fast-install' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||||
|
the `disable-fast-install' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
|
||||||
|
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_WITH_PIC([MODE])
|
||||||
|
# --------------------
|
||||||
|
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
|
||||||
|
# LT_INIT options.
|
||||||
|
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
|
||||||
|
m4_define([_LT_WITH_PIC],
|
||||||
|
[AC_ARG_WITH([pic],
|
||||||
|
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
|
||||||
|
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
|
||||||
|
[lt_p=${PACKAGE-default}
|
||||||
|
case $withval in
|
||||||
|
yes|no) pic_mode=$withval ;;
|
||||||
|
*)
|
||||||
|
pic_mode=default
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for lt_pkg in $withval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$lt_pkg" = "X$lt_p"; then
|
||||||
|
pic_mode=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[pic_mode=default])
|
||||||
|
|
||||||
|
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
|
||||||
|
|
||||||
|
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
|
||||||
|
])# _LT_WITH_PIC
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
|
||||||
|
|
||||||
|
# Old name:
|
||||||
|
AU_DEFUN([AC_LIBTOOL_PICMODE],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [pic-only])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||||
|
put the `pic-only' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
|
||||||
|
|
||||||
|
## ----------------- ##
|
||||||
|
## LTDL_INIT Options ##
|
||||||
|
## ----------------- ##
|
||||||
|
|
||||||
|
m4_define([_LTDL_MODE], [])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
|
||||||
|
[m4_define([_LTDL_MODE], [nonrecursive])])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
|
||||||
|
[m4_define([_LTDL_MODE], [recursive])])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
|
||||||
|
[m4_define([_LTDL_MODE], [subproject])])
|
||||||
|
|
||||||
|
m4_define([_LTDL_TYPE], [])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [installable],
|
||||||
|
[m4_define([_LTDL_TYPE], [installable])])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||||
|
[m4_define([_LTDL_TYPE], [convenience])])
|
|
@ -0,0 +1,123 @@
|
||||||
|
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
# Written by Gary V. Vaughan, 2004
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 6 ltsugar.m4
|
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||||
|
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_join(SEP, ARG1, [ARG2...])
|
||||||
|
# -----------------------------
|
||||||
|
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
|
||||||
|
# associated separator.
|
||||||
|
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
|
||||||
|
# versions in m4sugar had bugs.
|
||||||
|
m4_define([lt_join],
|
||||||
|
[m4_if([$#], [1], [],
|
||||||
|
[$#], [2], [[$2]],
|
||||||
|
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
|
||||||
|
m4_define([_lt_join],
|
||||||
|
[m4_if([$#$2], [2], [],
|
||||||
|
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_car(LIST)
|
||||||
|
# lt_cdr(LIST)
|
||||||
|
# ------------
|
||||||
|
# Manipulate m4 lists.
|
||||||
|
# These macros are necessary as long as will still need to support
|
||||||
|
# Autoconf-2.59 which quotes differently.
|
||||||
|
m4_define([lt_car], [[$1]])
|
||||||
|
m4_define([lt_cdr],
|
||||||
|
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
|
||||||
|
[$#], 1, [],
|
||||||
|
[m4_dquote(m4_shift($@))])])
|
||||||
|
m4_define([lt_unquote], $1)
|
||||||
|
|
||||||
|
|
||||||
|
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||||
|
# ------------------------------------------
|
||||||
|
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
|
||||||
|
# Note that neither SEPARATOR nor STRING are expanded; they are appended
|
||||||
|
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
|
||||||
|
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
|
||||||
|
# than defined and empty).
|
||||||
|
#
|
||||||
|
# This macro is needed until we can rely on Autoconf 2.62, since earlier
|
||||||
|
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
|
||||||
|
m4_define([lt_append],
|
||||||
|
[m4_define([$1],
|
||||||
|
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Produce a SEP delimited list of all paired combinations of elements of
|
||||||
|
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
|
||||||
|
# has the form PREFIXmINFIXSUFFIXn.
|
||||||
|
# Needed until we can rely on m4_combine added in Autoconf 2.62.
|
||||||
|
m4_define([lt_combine],
|
||||||
|
[m4_if(m4_eval([$# > 3]), [1],
|
||||||
|
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
|
||||||
|
[[m4_foreach([_Lt_prefix], [$2],
|
||||||
|
[m4_foreach([_Lt_suffix],
|
||||||
|
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
|
||||||
|
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
|
||||||
|
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
|
||||||
|
m4_define([lt_if_append_uniq],
|
||||||
|
[m4_ifdef([$1],
|
||||||
|
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
|
||||||
|
[lt_append([$1], [$2], [$3])$4],
|
||||||
|
[$5])],
|
||||||
|
[lt_append([$1], [$2], [$3])$4])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_add(DICT, KEY, VALUE)
|
||||||
|
# -----------------------------
|
||||||
|
m4_define([lt_dict_add],
|
||||||
|
[m4_define([$1($2)], [$3])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
|
||||||
|
# --------------------------------------------
|
||||||
|
m4_define([lt_dict_add_subkey],
|
||||||
|
[m4_define([$1($2:$3)], [$4])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_fetch(DICT, KEY, [SUBKEY])
|
||||||
|
# ----------------------------------
|
||||||
|
m4_define([lt_dict_fetch],
|
||||||
|
[m4_ifval([$3],
|
||||||
|
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
|
||||||
|
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
m4_define([lt_if_dict_fetch],
|
||||||
|
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
|
||||||
|
[$5],
|
||||||
|
[$6])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
m4_define([lt_dict_filter],
|
||||||
|
[m4_if([$5], [], [],
|
||||||
|
[lt_join(m4_quote(m4_default([$4], [[, ]])),
|
||||||
|
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
|
||||||
|
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
|
||||||
|
])
|
|
@ -0,0 +1,23 @@
|
||||||
|
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
# Written by Scott James Remnant, 2004
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# serial 3337 ltversion.m4
|
||||||
|
# This file is part of GNU Libtool
|
||||||
|
|
||||||
|
m4_define([LT_PACKAGE_VERSION], [2.4.2])
|
||||||
|
m4_define([LT_PACKAGE_REVISION], [1.3337])
|
||||||
|
|
||||||
|
AC_DEFUN([LTVERSION_VERSION],
|
||||||
|
[macro_version='2.4.2'
|
||||||
|
macro_revision='1.3337'
|
||||||
|
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||||
|
_LT_DECL(, macro_revision, 0)
|
||||||
|
])
|
|
@ -0,0 +1,98 @@
|
||||||
|
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||||
|
# Written by Scott James Remnant, 2004.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 5 lt~obsolete.m4
|
||||||
|
|
||||||
|
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||||
|
#
|
||||||
|
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
|
||||||
|
# which have later been changed to m4_define as they aren't part of the
|
||||||
|
# exported API, or moved to Autoconf or Automake where they belong.
|
||||||
|
#
|
||||||
|
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||||
|
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||||
|
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||||
|
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||||
|
# and doesn't know about Autoconf macros at all.)
|
||||||
|
#
|
||||||
|
# So we provide this file, which has a silly filename so it's always
|
||||||
|
# included after everything else. This provides aclocal with the
|
||||||
|
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||||
|
# because those macros already exist, or will be overwritten later.
|
||||||
|
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||||
|
#
|
||||||
|
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||||
|
# Yes, that means every name once taken will need to remain here until
|
||||||
|
# we give up compatibility with versions before 1.7, at which point
|
||||||
|
# we need to keep only those names which we still refer to.
|
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||||
|
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||||
|
|
||||||
|
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||||
|
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||||
|
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||||
|
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||||
|
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||||
|
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||||
|
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||||
|
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||||
|
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||||
|
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||||
|
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||||
|
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||||
|
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||||
|
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||||
|
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||||
|
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||||
|
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||||
|
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||||
|
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||||
|
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||||
|
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||||
|
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||||
|
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||||
|
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||||
|
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||||
|
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||||
|
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||||
|
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||||
|
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||||
|
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||||
|
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||||
|
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||||
|
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
|
@ -0,0 +1,215 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Common wrapper for a few potentially missing GNU programs.
|
||||||
|
|
||||||
|
scriptversion=2013-10-28.13; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||||
|
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
echo 1>&2 "Try '$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
|
||||||
|
--is-lightweight)
|
||||||
|
# Used by our autoconf macros to check whether the available missing
|
||||||
|
# script is modern enough.
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--run)
|
||||||
|
# Back-compat with the calling convention used by older automake.
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
-h|--h|--he|--hel|--help)
|
||||||
|
echo "\
|
||||||
|
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||||
|
|
||||||
|
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||||
|
to PROGRAM being missing or too old.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help display this help and exit
|
||||||
|
-v, --version output version information and exit
|
||||||
|
|
||||||
|
Supported PROGRAM values:
|
||||||
|
aclocal autoconf autoheader autom4te automake makeinfo
|
||||||
|
bison yacc flex lex help2man
|
||||||
|
|
||||||
|
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||||
|
'g' are ignored when checking the name.
|
||||||
|
|
||||||
|
Send bug reports to <bug-automake@gnu.org>."
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||||
|
echo "missing $scriptversion (GNU Automake)"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo 1>&2 "$0: unknown '$1' option"
|
||||||
|
echo 1>&2 "Try '$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Run the given program, remember its exit status.
|
||||||
|
"$@"; st=$?
|
||||||
|
|
||||||
|
# If it succeeded, we are done.
|
||||||
|
test $st -eq 0 && exit 0
|
||||||
|
|
||||||
|
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||||
|
# passed; such an option is passed most likely to detect whether the
|
||||||
|
# program is present and works.
|
||||||
|
case $2 in --version|--help) exit $st;; esac
|
||||||
|
|
||||||
|
# Exit code 63 means version mismatch. This often happens when the user
|
||||||
|
# tries to use an ancient version of a tool on a file that requires a
|
||||||
|
# minimum version.
|
||||||
|
if test $st -eq 63; then
|
||||||
|
msg="probably too old"
|
||||||
|
elif test $st -eq 127; then
|
||||||
|
# Program was missing.
|
||||||
|
msg="missing on your system"
|
||||||
|
else
|
||||||
|
# Program was found and executed, but failed. Give up.
|
||||||
|
exit $st
|
||||||
|
fi
|
||||||
|
|
||||||
|
perl_URL=http://www.perl.org/
|
||||||
|
flex_URL=http://flex.sourceforge.net/
|
||||||
|
gnu_software_URL=http://www.gnu.org/software
|
||||||
|
|
||||||
|
program_details ()
|
||||||
|
{
|
||||||
|
case $1 in
|
||||||
|
aclocal|automake)
|
||||||
|
echo "The '$1' program is part of the GNU Automake package:"
|
||||||
|
echo "<$gnu_software_URL/automake>"
|
||||||
|
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||||
|
echo "<$gnu_software_URL/autoconf>"
|
||||||
|
echo "<$gnu_software_URL/m4/>"
|
||||||
|
echo "<$perl_URL>"
|
||||||
|
;;
|
||||||
|
autoconf|autom4te|autoheader)
|
||||||
|
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||||
|
echo "<$gnu_software_URL/autoconf/>"
|
||||||
|
echo "It also requires GNU m4 and Perl in order to run:"
|
||||||
|
echo "<$gnu_software_URL/m4/>"
|
||||||
|
echo "<$perl_URL>"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
give_advice ()
|
||||||
|
{
|
||||||
|
# Normalize program name to check for.
|
||||||
|
normalized_program=`echo "$1" | sed '
|
||||||
|
s/^gnu-//; t
|
||||||
|
s/^gnu//; t
|
||||||
|
s/^g//; t'`
|
||||||
|
|
||||||
|
printf '%s\n' "'$1' is $msg."
|
||||||
|
|
||||||
|
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||||
|
case $normalized_program in
|
||||||
|
autoconf*)
|
||||||
|
echo "You should only need it if you modified 'configure.ac',"
|
||||||
|
echo "or m4 files included by it."
|
||||||
|
program_details 'autoconf'
|
||||||
|
;;
|
||||||
|
autoheader*)
|
||||||
|
echo "You should only need it if you modified 'acconfig.h' or"
|
||||||
|
echo "$configure_deps."
|
||||||
|
program_details 'autoheader'
|
||||||
|
;;
|
||||||
|
automake*)
|
||||||
|
echo "You should only need it if you modified 'Makefile.am' or"
|
||||||
|
echo "$configure_deps."
|
||||||
|
program_details 'automake'
|
||||||
|
;;
|
||||||
|
aclocal*)
|
||||||
|
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||||
|
echo "$configure_deps."
|
||||||
|
program_details 'aclocal'
|
||||||
|
;;
|
||||||
|
autom4te*)
|
||||||
|
echo "You might have modified some maintainer files that require"
|
||||||
|
echo "the 'autom4te' program to be rebuilt."
|
||||||
|
program_details 'autom4te'
|
||||||
|
;;
|
||||||
|
bison*|yacc*)
|
||||||
|
echo "You should only need it if you modified a '.y' file."
|
||||||
|
echo "You may want to install the GNU Bison package:"
|
||||||
|
echo "<$gnu_software_URL/bison/>"
|
||||||
|
;;
|
||||||
|
lex*|flex*)
|
||||||
|
echo "You should only need it if you modified a '.l' file."
|
||||||
|
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||||
|
echo "<$flex_URL>"
|
||||||
|
;;
|
||||||
|
help2man*)
|
||||||
|
echo "You should only need it if you modified a dependency" \
|
||||||
|
"of a man page."
|
||||||
|
echo "You may want to install the GNU Help2man package:"
|
||||||
|
echo "<$gnu_software_URL/help2man/>"
|
||||||
|
;;
|
||||||
|
makeinfo*)
|
||||||
|
echo "You should only need it if you modified a '.texi' file, or"
|
||||||
|
echo "any other file indirectly affecting the aspect of the manual."
|
||||||
|
echo "You might want to install the Texinfo package:"
|
||||||
|
echo "<$gnu_software_URL/texinfo/>"
|
||||||
|
echo "The spurious makeinfo call might also be the consequence of"
|
||||||
|
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||||
|
echo "want to install GNU make:"
|
||||||
|
echo "<$gnu_software_URL/make/>"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "You might have modified some files without having the proper"
|
||||||
|
echo "tools for further handling them. Check the 'README' file, it"
|
||||||
|
echo "often tells you about the needed prerequisites for installing"
|
||||||
|
echo "this package. You may also peek at any GNU archive site, in"
|
||||||
|
echo "case some other package contains this missing '$1' program."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||||
|
-e '2,$s/^/ /' >&2
|
||||||
|
|
||||||
|
# Propagate the correct exit status (expected to be 127 for a program
|
||||||
|
# not found, 63 for a program that failed due to version mismatch).
|
||||||
|
exit $st
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
|
@ -20,10 +20,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include <config.h>
|
||||||
#include "libusb.h"
|
|
||||||
#include "libusbi.h"
|
|
||||||
#include "linux_usbfs.h"
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -53,6 +50,9 @@
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "libusbi.h"
|
||||||
|
#include "linux_usbfs.h"
|
||||||
|
|
||||||
#define KERNEL 1
|
#define KERNEL 1
|
||||||
|
|
||||||
static int linux_netlink_socket = -1;
|
static int linux_netlink_socket = -1;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include <config.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -39,7 +39,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libudev.h>
|
#include <libudev.h>
|
||||||
|
|
||||||
#include "libusb.h"
|
|
||||||
#include "libusbi.h"
|
#include "libusbi.h"
|
||||||
#include "linux_usbfs.h"
|
#include "linux_usbfs.h"
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "libusb.h"
|
|
||||||
#include "libusbi.h"
|
#include "libusbi.h"
|
||||||
#include "linux_usbfs.h"
|
#include "linux_usbfs.h"
|
||||||
|
|
||||||
|
@ -199,7 +198,7 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
||||||
|
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
usbi_err(ctx, "File doesn't exist, wait %d ms and try again\n", delay/1000);
|
usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000);
|
||||||
|
|
||||||
/* Wait 10ms for USB device path creation.*/
|
/* Wait 10ms for USB device path creation.*/
|
||||||
usleep(delay);
|
usleep(delay);
|
||||||
|
@ -308,6 +307,14 @@ static const char *find_usbfs_path(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On udev based systems without any usb-devices /dev/bus/usb will not
|
||||||
|
* exist. So if we've not found anything and we're using udev for hotplug
|
||||||
|
* simply assume /dev/bus/usb rather then making libusb_init fail. */
|
||||||
|
#if defined(USE_UDEV)
|
||||||
|
if (ret == NULL)
|
||||||
|
ret = "/dev/bus/usb";
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
usbi_dbg("found usbfs at %s", ret);
|
usbi_dbg("found usbfs at %s", ret);
|
||||||
|
|
||||||
|
@ -632,9 +639,9 @@ int linux_get_device_address (struct libusb_context *ctx, int detached,
|
||||||
|
|
||||||
/* will this work with all supported kernel versions? */
|
/* will this work with all supported kernel versions? */
|
||||||
if (!strncmp(dev_node, "/dev/bus/usb", 12)) {
|
if (!strncmp(dev_node, "/dev/bus/usb", 12)) {
|
||||||
sscanf (dev_node, "/dev/bus/usb/%hhd/%hhd", busnum, devaddr);
|
sscanf (dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr);
|
||||||
} else if (!strncmp(dev_node, "/proc/bus/usb", 13)) {
|
} else if (!strncmp(dev_node, "/proc/bus/usb", 13)) {
|
||||||
sscanf (dev_node, "/proc/bus/usb/%hhd/%hhd", busnum, devaddr);
|
sscanf (dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
|
@ -998,6 +1005,9 @@ static int linux_get_parent_info(struct libusb_device *dev, const char *sysfs_di
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_sysfs_dir = strdup(sysfs_dir);
|
parent_sysfs_dir = strdup(sysfs_dir);
|
||||||
|
if (NULL == parent_sysfs_dir) {
|
||||||
|
return LIBUSB_ERROR_NO_MEM;
|
||||||
|
}
|
||||||
if (NULL != (tmp = strrchr(parent_sysfs_dir, '.')) ||
|
if (NULL != (tmp = strrchr(parent_sysfs_dir, '.')) ||
|
||||||
NULL != (tmp = strrchr(parent_sysfs_dir, '-'))) {
|
NULL != (tmp = strrchr(parent_sysfs_dir, '-'))) {
|
||||||
dev->port_number = atoi(tmp + 1);
|
dev->port_number = atoi(tmp + 1);
|
||||||
|
@ -1765,10 +1775,6 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
||||||
int bulk_buffer_len, use_bulk_continuation;
|
int bulk_buffer_len, use_bulk_continuation;
|
||||||
int r;
|
int r;
|
||||||
int i;
|
int i;
|
||||||
size_t alloc_size;
|
|
||||||
|
|
||||||
if (tpriv->urbs)
|
|
||||||
return LIBUSB_ERROR_BUSY;
|
|
||||||
|
|
||||||
if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) &&
|
if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) &&
|
||||||
!(dpriv->caps & USBFS_CAP_ZERO_PACKET))
|
!(dpriv->caps & USBFS_CAP_ZERO_PACKET))
|
||||||
|
@ -1827,8 +1833,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
||||||
}
|
}
|
||||||
usbi_dbg("need %d urbs for new transfer with length %d", num_urbs,
|
usbi_dbg("need %d urbs for new transfer with length %d", num_urbs,
|
||||||
transfer->length);
|
transfer->length);
|
||||||
alloc_size = num_urbs * sizeof(struct usbfs_urb);
|
urbs = calloc(num_urbs, sizeof(struct usbfs_urb));
|
||||||
urbs = calloc(1, alloc_size);
|
|
||||||
if (!urbs)
|
if (!urbs)
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
return LIBUSB_ERROR_NO_MEM;
|
||||||
tpriv->urbs = urbs;
|
tpriv->urbs = urbs;
|
||||||
|
@ -1946,18 +1951,11 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
||||||
unsigned int packet_len;
|
unsigned int packet_len;
|
||||||
unsigned char *urb_buffer = transfer->buffer;
|
unsigned char *urb_buffer = transfer->buffer;
|
||||||
|
|
||||||
if (tpriv->iso_urbs)
|
/* usbfs places arbitrary limits on iso URBs. this limit has changed
|
||||||
return LIBUSB_ERROR_BUSY;
|
* at least three times, and it's difficult to accurately detect which
|
||||||
|
* limit this running kernel might impose. so we attempt to submit
|
||||||
/* usbfs places a 32kb limit on iso URBs. we divide up larger requests
|
* whatever the user has provided. if the kernel rejects the request
|
||||||
* into smaller units to meet such restriction, then fire off all the
|
* due to its size, we return an error indicating such to the user.
|
||||||
* units at once. it would be simpler if we just fired one unit at a time,
|
|
||||||
* but there is a big performance gain through doing it this way.
|
|
||||||
*
|
|
||||||
* Newer kernels lift the 32k limit (USBFS_CAP_NO_PACKET_SIZE_LIM),
|
|
||||||
* using arbritary large transfers is still be a bad idea though, as
|
|
||||||
* the kernel needs to allocate physical contiguous memory for this,
|
|
||||||
* which may fail for large buffers.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* calculate how many URBs we need */
|
/* calculate how many URBs we need */
|
||||||
|
@ -1968,14 +1966,16 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
||||||
if (packet_len > space_remaining) {
|
if (packet_len > space_remaining) {
|
||||||
num_urbs++;
|
num_urbs++;
|
||||||
this_urb_len = packet_len;
|
this_urb_len = packet_len;
|
||||||
|
/* check that we can actually support this packet length */
|
||||||
|
if (this_urb_len > MAX_ISO_BUFFER_LENGTH)
|
||||||
|
return LIBUSB_ERROR_INVALID_PARAM;
|
||||||
} else {
|
} else {
|
||||||
this_urb_len += packet_len;
|
this_urb_len += packet_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usbi_dbg("need %d 32k URBs for transfer", num_urbs);
|
usbi_dbg("need %d %dk URBs for transfer", num_urbs, MAX_ISO_BUFFER_LENGTH / 1024);
|
||||||
|
|
||||||
alloc_size = num_urbs * sizeof(*urbs);
|
urbs = calloc(num_urbs, sizeof(*urbs));
|
||||||
urbs = calloc(1, alloc_size);
|
|
||||||
if (!urbs)
|
if (!urbs)
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
return LIBUSB_ERROR_NO_MEM;
|
||||||
|
|
||||||
|
@ -2040,6 +2040,10 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (errno == ENODEV) {
|
if (errno == ENODEV) {
|
||||||
r = LIBUSB_ERROR_NO_DEVICE;
|
r = LIBUSB_ERROR_NO_DEVICE;
|
||||||
|
} else if (errno == EINVAL) {
|
||||||
|
usbi_warn(TRANSFER_CTX(transfer),
|
||||||
|
"submiturb failed, transfer too large");
|
||||||
|
r = LIBUSB_ERROR_INVALID_PARAM;
|
||||||
} else {
|
} else {
|
||||||
usbi_err(TRANSFER_CTX(transfer),
|
usbi_err(TRANSFER_CTX(transfer),
|
||||||
"submiturb failed error %d errno=%d", r, errno);
|
"submiturb failed error %d errno=%d", r, errno);
|
||||||
|
@ -2093,9 +2097,6 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
|
||||||
struct usbfs_urb *urb;
|
struct usbfs_urb *urb;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (tpriv->urbs)
|
|
||||||
return LIBUSB_ERROR_BUSY;
|
|
||||||
|
|
||||||
if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH)
|
if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH)
|
||||||
return LIBUSB_ERROR_INVALID_PARAM;
|
return LIBUSB_ERROR_INVALID_PARAM;
|
||||||
|
|
||||||
|
@ -2153,6 +2154,14 @@ static int op_cancel_transfer(struct usbi_transfer *itransfer)
|
||||||
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
||||||
struct libusb_transfer *transfer =
|
struct libusb_transfer *transfer =
|
||||||
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!tpriv->urbs)
|
||||||
|
return LIBUSB_ERROR_NOT_FOUND;
|
||||||
|
|
||||||
|
r = discard_urbs(itransfer, 0, tpriv->num_urbs);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
switch (transfer->type) {
|
switch (transfer->type) {
|
||||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||||
|
@ -2160,21 +2169,11 @@ static int op_cancel_transfer(struct usbi_transfer *itransfer)
|
||||||
if (tpriv->reap_action == ERROR)
|
if (tpriv->reap_action == ERROR)
|
||||||
break;
|
break;
|
||||||
/* else, fall through */
|
/* else, fall through */
|
||||||
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
||||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
||||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
||||||
tpriv->reap_action = CANCELLED;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
usbi_err(TRANSFER_CTX(transfer),
|
tpriv->reap_action = CANCELLED;
|
||||||
"unknown endpoint type %d", transfer->type);
|
|
||||||
return LIBUSB_ERROR_INVALID_PARAM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tpriv->urbs)
|
return 0;
|
||||||
return LIBUSB_ERROR_NOT_FOUND;
|
|
||||||
|
|
||||||
return discard_urbs(itransfer, 0, tpriv->num_urbs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||||
|
@ -2189,17 +2188,16 @@ static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||||
usbi_mutex_lock(&itransfer->lock);
|
if (tpriv->urbs) {
|
||||||
if (tpriv->urbs)
|
|
||||||
free(tpriv->urbs);
|
free(tpriv->urbs);
|
||||||
tpriv->urbs = NULL;
|
tpriv->urbs = NULL;
|
||||||
usbi_mutex_unlock(&itransfer->lock);
|
}
|
||||||
break;
|
break;
|
||||||
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
||||||
usbi_mutex_lock(&itransfer->lock);
|
if (tpriv->iso_urbs) {
|
||||||
if (tpriv->iso_urbs)
|
|
||||||
free_iso_urbs(tpriv);
|
free_iso_urbs(tpriv);
|
||||||
usbi_mutex_unlock(&itransfer->lock);
|
tpriv->iso_urbs = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usbi_err(TRANSFER_CTX(transfer),
|
usbi_err(TRANSFER_CTX(transfer),
|
||||||
|
@ -2591,7 +2589,7 @@ static int op_handle_events(struct libusb_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hpriv || hpriv->fd != pollfd->fd) {
|
if (!hpriv || hpriv->fd != pollfd->fd) {
|
||||||
usbi_err(ctx, "cannot find handle for fd %d\n",
|
usbi_err(ctx, "cannot find handle for fd %d",
|
||||||
pollfd->fd);
|
pollfd->fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2691,5 +2689,4 @@ const struct usbi_os_backend linux_usbfs_backend = {
|
||||||
.device_priv_size = sizeof(struct linux_device_priv),
|
.device_priv_size = sizeof(struct linux_device_priv),
|
||||||
.device_handle_priv_size = sizeof(struct linux_device_handle_priv),
|
.device_handle_priv_size = sizeof(struct linux_device_handle_priv),
|
||||||
.transfer_priv_size = sizeof(struct linux_transfer_priv),
|
.transfer_priv_size = sizeof(struct linux_transfer_priv),
|
||||||
.add_iso_packet_size = 0,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct usbfs_iso_packet_desc {
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_ISO_BUFFER_LENGTH 32768
|
#define MAX_ISO_BUFFER_LENGTH 49152 * 128
|
||||||
#define MAX_BULK_BUFFER_LENGTH 16384
|
#define MAX_BULK_BUFFER_LENGTH 16384
|
||||||
#define MAX_CTRL_BUFFER_LENGTH 4096
|
#define MAX_CTRL_BUFFER_LENGTH 4096
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -28,7 +30,6 @@
|
||||||
|
|
||||||
#include <dev/usb/usb.h>
|
#include <dev/usb/usb.h>
|
||||||
|
|
||||||
#include "libusb.h"
|
|
||||||
#include "libusbi.h"
|
#include "libusbi.h"
|
||||||
|
|
||||||
struct device_priv {
|
struct device_priv {
|
||||||
|
@ -40,7 +41,6 @@ struct device_priv {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct handle_priv {
|
struct handle_priv {
|
||||||
int pipe[2]; /* for event notification */
|
|
||||||
int endpoints[USB_MAX_ENDPOINTS];
|
int endpoints[USB_MAX_ENDPOINTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,8 +74,7 @@ static void netbsd_destroy_device(struct libusb_device *);
|
||||||
static int netbsd_submit_transfer(struct usbi_transfer *);
|
static int netbsd_submit_transfer(struct usbi_transfer *);
|
||||||
static int netbsd_cancel_transfer(struct usbi_transfer *);
|
static int netbsd_cancel_transfer(struct usbi_transfer *);
|
||||||
static void netbsd_clear_transfer_priv(struct usbi_transfer *);
|
static void netbsd_clear_transfer_priv(struct usbi_transfer *);
|
||||||
static int netbsd_handle_events(struct libusb_context *ctx, struct pollfd *,
|
static int netbsd_handle_transfer_completion(struct usbi_transfer *);
|
||||||
nfds_t, int);
|
|
||||||
static int netbsd_clock_gettime(int, struct timespec *);
|
static int netbsd_clock_gettime(int, struct timespec *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -125,13 +124,13 @@ const struct usbi_os_backend netbsd_backend = {
|
||||||
netbsd_cancel_transfer,
|
netbsd_cancel_transfer,
|
||||||
netbsd_clear_transfer_priv,
|
netbsd_clear_transfer_priv,
|
||||||
|
|
||||||
netbsd_handle_events,
|
NULL, /* handle_events() */
|
||||||
|
netbsd_handle_transfer_completion,
|
||||||
|
|
||||||
netbsd_clock_gettime,
|
netbsd_clock_gettime,
|
||||||
sizeof(struct device_priv),
|
sizeof(struct device_priv),
|
||||||
sizeof(struct handle_priv),
|
sizeof(struct handle_priv),
|
||||||
0, /* transfer_priv_size */
|
0, /* transfer_priv_size */
|
||||||
0, /* add_iso_packet_size */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -222,10 +221,7 @@ netbsd_open(struct libusb_device_handle *handle)
|
||||||
|
|
||||||
usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
|
usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
|
||||||
|
|
||||||
if (pipe(hpriv->pipe) < 0)
|
return (LIBUSB_SUCCESS);
|
||||||
return _errno_to_libusb(errno);
|
|
||||||
|
|
||||||
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -238,11 +234,6 @@ netbsd_close(struct libusb_device_handle *handle)
|
||||||
|
|
||||||
close(dpriv->fd);
|
close(dpriv->fd);
|
||||||
dpriv->fd = -1;
|
dpriv->fd = -1;
|
||||||
|
|
||||||
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
|
|
||||||
|
|
||||||
close(hpriv->pipe[0]);
|
|
||||||
close(hpriv->pipe[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -469,8 +460,7 @@ netbsd_submit_transfer(struct usbi_transfer *itransfer)
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
|
usbi_signal_transfer_completion(itransfer);
|
||||||
return _errno_to_libusb(errno);
|
|
||||||
|
|
||||||
return (LIBUSB_SUCCESS);
|
return (LIBUSB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -492,63 +482,9 @@ netbsd_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
netbsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
|
netbsd_handle_transfer_completion(struct usbi_transfer *itransfer)
|
||||||
int num_ready)
|
|
||||||
{
|
{
|
||||||
struct libusb_device_handle *handle;
|
return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
|
||||||
struct handle_priv *hpriv = NULL;
|
|
||||||
struct usbi_transfer *itransfer;
|
|
||||||
struct pollfd *pollfd;
|
|
||||||
int i, err = 0;
|
|
||||||
|
|
||||||
usbi_dbg("");
|
|
||||||
|
|
||||||
pthread_mutex_lock(&ctx->open_devs_lock);
|
|
||||||
for (i = 0; i < nfds && num_ready > 0; i++) {
|
|
||||||
pollfd = &fds[i];
|
|
||||||
|
|
||||||
if (!pollfd->revents)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
hpriv = NULL;
|
|
||||||
num_ready--;
|
|
||||||
list_for_each_entry(handle, &ctx->open_devs, list,
|
|
||||||
struct libusb_device_handle) {
|
|
||||||
hpriv = (struct handle_priv *)handle->os_priv;
|
|
||||||
|
|
||||||
if (hpriv->pipe[0] == pollfd->fd)
|
|
||||||
break;
|
|
||||||
|
|
||||||
hpriv = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == hpriv) {
|
|
||||||
usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
|
|
||||||
err = ENOENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pollfd->revents & POLLERR) {
|
|
||||||
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
|
|
||||||
usbi_handle_disconnect(handle);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
|
|
||||||
err = errno;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = usbi_handle_transfer_completion(itransfer,
|
|
||||||
LIBUSB_TRANSFER_COMPLETED)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&ctx->open_devs_lock);
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
return _errno_to_libusb(err);
|
|
||||||
|
|
||||||
return (LIBUSB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -28,7 +30,6 @@
|
||||||
|
|
||||||
#include <dev/usb/usb.h>
|
#include <dev/usb/usb.h>
|
||||||
|
|
||||||
#include "libusb.h"
|
|
||||||
#include "libusbi.h"
|
#include "libusbi.h"
|
||||||
|
|
||||||
struct device_priv {
|
struct device_priv {
|
||||||
|
@ -40,7 +41,6 @@ struct device_priv {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct handle_priv {
|
struct handle_priv {
|
||||||
int pipe[2]; /* for event notification */
|
|
||||||
int endpoints[USB_MAX_ENDPOINTS];
|
int endpoints[USB_MAX_ENDPOINTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,8 +74,7 @@ static void obsd_destroy_device(struct libusb_device *);
|
||||||
static int obsd_submit_transfer(struct usbi_transfer *);
|
static int obsd_submit_transfer(struct usbi_transfer *);
|
||||||
static int obsd_cancel_transfer(struct usbi_transfer *);
|
static int obsd_cancel_transfer(struct usbi_transfer *);
|
||||||
static void obsd_clear_transfer_priv(struct usbi_transfer *);
|
static void obsd_clear_transfer_priv(struct usbi_transfer *);
|
||||||
static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *,
|
static int obsd_handle_transfer_completion(struct usbi_transfer *);
|
||||||
nfds_t, int);
|
|
||||||
static int obsd_clock_gettime(int, struct timespec *);
|
static int obsd_clock_gettime(int, struct timespec *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -128,13 +127,13 @@ const struct usbi_os_backend openbsd_backend = {
|
||||||
obsd_cancel_transfer,
|
obsd_cancel_transfer,
|
||||||
obsd_clear_transfer_priv,
|
obsd_clear_transfer_priv,
|
||||||
|
|
||||||
obsd_handle_events,
|
NULL, /* handle_events() */
|
||||||
|
obsd_handle_transfer_completion,
|
||||||
|
|
||||||
obsd_clock_gettime,
|
obsd_clock_gettime,
|
||||||
sizeof(struct device_priv),
|
sizeof(struct device_priv),
|
||||||
sizeof(struct handle_priv),
|
sizeof(struct handle_priv),
|
||||||
0, /* transfer_priv_size */
|
0, /* transfer_priv_size */
|
||||||
0, /* add_iso_packet_size */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEVPATH "/dev/"
|
#define DEVPATH "/dev/"
|
||||||
|
@ -262,10 +261,7 @@ obsd_open(struct libusb_device_handle *handle)
|
||||||
usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
|
usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe(hpriv->pipe) < 0)
|
return (LIBUSB_SUCCESS);
|
||||||
return _errno_to_libusb(errno);
|
|
||||||
|
|
||||||
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -280,11 +276,6 @@ obsd_close(struct libusb_device_handle *handle)
|
||||||
close(dpriv->fd);
|
close(dpriv->fd);
|
||||||
dpriv->fd = -1;
|
dpriv->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
|
|
||||||
|
|
||||||
close(hpriv->pipe[0]);
|
|
||||||
close(hpriv->pipe[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -515,8 +506,7 @@ obsd_submit_transfer(struct usbi_transfer *itransfer)
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
|
usbi_signal_transfer_completion(itransfer);
|
||||||
return _errno_to_libusb(errno);
|
|
||||||
|
|
||||||
return (LIBUSB_SUCCESS);
|
return (LIBUSB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -538,63 +528,9 @@ obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
|
obsd_handle_transfer_completion(struct usbi_transfer *itransfer)
|
||||||
int num_ready)
|
|
||||||
{
|
{
|
||||||
struct libusb_device_handle *handle;
|
return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
|
||||||
struct handle_priv *hpriv = NULL;
|
|
||||||
struct usbi_transfer *itransfer;
|
|
||||||
struct pollfd *pollfd;
|
|
||||||
int i, err = 0;
|
|
||||||
|
|
||||||
usbi_dbg("");
|
|
||||||
|
|
||||||
pthread_mutex_lock(&ctx->open_devs_lock);
|
|
||||||
for (i = 0; i < nfds && num_ready > 0; i++) {
|
|
||||||
pollfd = &fds[i];
|
|
||||||
|
|
||||||
if (!pollfd->revents)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
hpriv = NULL;
|
|
||||||
num_ready--;
|
|
||||||
list_for_each_entry(handle, &ctx->open_devs, list,
|
|
||||||
struct libusb_device_handle) {
|
|
||||||
hpriv = (struct handle_priv *)handle->os_priv;
|
|
||||||
|
|
||||||
if (hpriv->pipe[0] == pollfd->fd)
|
|
||||||
break;
|
|
||||||
|
|
||||||
hpriv = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == hpriv) {
|
|
||||||
usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
|
|
||||||
err = ENOENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pollfd->revents & POLLERR) {
|
|
||||||
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
|
|
||||||
usbi_handle_disconnect(handle);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
|
|
||||||
err = errno;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = usbi_handle_transfer_completion(itransfer,
|
|
||||||
LIBUSB_TRANSFER_COMPLETED)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&ctx->open_devs_lock);
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
return _errno_to_libusb(err);
|
|
||||||
|
|
||||||
return (LIBUSB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
* with a fake pipe. The read/write functions are only meant to be used in that
|
* with a fake pipe. The read/write functions are only meant to be used in that
|
||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -331,7 +333,7 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer
|
||||||
wfd.cancel_fn = cancel_fn;
|
wfd.cancel_fn = cancel_fn;
|
||||||
|
|
||||||
if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
|
if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
|
||||||
usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
|
usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported. "
|
||||||
"If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
|
"If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
|
||||||
return INVALID_WINFD;
|
return INVALID_WINFD;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__OpenBSD__)
|
#if defined(__linux__) || defined(__OpenBSD__)
|
||||||
# if defined(__linux__)
|
# if defined(__OpenBSD__)
|
||||||
# define _GNU_SOURCE
|
|
||||||
# else
|
|
||||||
# define _BSD_SOURCE
|
# define _BSD_SOURCE
|
||||||
# endif
|
# endif
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -185,7 +186,8 @@ int usbi_cond_timedwait(usbi_cond_t *cond,
|
||||||
// GetSystemTimeAsFileTime() is not available on CE
|
// GetSystemTimeAsFileTime() is not available on CE
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
GetSystemTime(&st);
|
GetSystemTime(&st);
|
||||||
SystemTimeToFileTime(&st, &filetime);
|
if (!SystemTimeToFileTime(&st, &filetime))
|
||||||
|
return 0;
|
||||||
rtime.LowPart = filetime.dwLowDateTime;
|
rtime.LowPart = filetime.dwLowDateTime;
|
||||||
rtime.HighPart = filetime.dwHighDateTime;
|
rtime.HighPart = filetime.dwHighDateTime;
|
||||||
rtime.QuadPart -= epoch_time;
|
rtime.QuadPart -= epoch_time;
|
||||||
|
|
|
@ -22,32 +22,19 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libusbi.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "libusbi.h"
|
||||||
#include "wince_usb.h"
|
#include "wince_usb.h"
|
||||||
|
|
||||||
// Forward declares
|
|
||||||
static int wince_clock_gettime(int clk_id, struct timespec *tp);
|
|
||||||
unsigned __stdcall wince_clock_gettime_threaded(void* param);
|
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
uint64_t hires_frequency, hires_ticks_to_ps;
|
uint64_t hires_frequency, hires_ticks_to_ps;
|
||||||
int errno;
|
const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
|
||||||
const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
|
|
||||||
int windows_version = WINDOWS_CE;
|
int windows_version = WINDOWS_CE;
|
||||||
static int concurrent_usage = -1;
|
static int concurrent_usage = -1;
|
||||||
// Timer thread
|
|
||||||
// NB: index 0 is for monotonic and 1 is for the thread exit event
|
|
||||||
HANDLE timer_thread = NULL;
|
|
||||||
HANDLE timer_mutex = NULL;
|
|
||||||
struct timespec timer_tp;
|
|
||||||
volatile LONG request_count[2] = {0, 1}; // last one must be > 0
|
|
||||||
HANDLE timer_request[2] = { NULL, NULL };
|
|
||||||
HANDLE timer_response = NULL;
|
|
||||||
HANDLE driver_handle = INVALID_HANDLE_VALUE;
|
HANDLE driver_handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -94,7 +81,7 @@ static char* windows_error_str(uint32_t retval)
|
||||||
|
|
||||||
static struct wince_device_priv *_device_priv(struct libusb_device *dev)
|
static struct wince_device_priv *_device_priv(struct libusb_device *dev)
|
||||||
{
|
{
|
||||||
return (struct wince_device_priv *) dev->os_priv;
|
return (struct wince_device_priv *) dev->os_priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ceusbkwrapper to libusb error code mapping
|
// ceusbkwrapper to libusb error code mapping
|
||||||
|
@ -149,8 +136,9 @@ static int init_dllimports()
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_device(struct libusb_device *dev, UKW_DEVICE drv_dev,
|
static int init_device(
|
||||||
unsigned char bus_addr, unsigned char dev_addr)
|
struct libusb_device *dev, UKW_DEVICE drv_dev,
|
||||||
|
unsigned char bus_addr, unsigned char dev_addr)
|
||||||
{
|
{
|
||||||
struct wince_device_priv *priv = _device_priv(dev);
|
struct wince_device_priv *priv = _device_priv(dev);
|
||||||
int r = LIBUSB_SUCCESS;
|
int r = LIBUSB_SUCCESS;
|
||||||
|
@ -168,8 +156,9 @@ static int init_device(struct libusb_device *dev, UKW_DEVICE drv_dev,
|
||||||
// Internal API functions
|
// Internal API functions
|
||||||
static int wince_init(struct libusb_context *ctx)
|
static int wince_init(struct libusb_context *ctx)
|
||||||
{
|
{
|
||||||
int i, r = LIBUSB_ERROR_OTHER;
|
int r = LIBUSB_ERROR_OTHER;
|
||||||
HANDLE semaphore;
|
HANDLE semaphore;
|
||||||
|
LARGE_INTEGER li_frequency;
|
||||||
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
||||||
|
|
||||||
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
|
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
|
||||||
|
@ -208,37 +197,17 @@ static int wince_init(struct libusb_context *ctx)
|
||||||
goto init_exit;
|
goto init_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows CE doesn't have a way of specifying thread affinity, so this code
|
// find out if we have access to a monotonic (hires) timer
|
||||||
// just has to hope QueryPerformanceCounter doesn't report different values when
|
if (QueryPerformanceFrequency(&li_frequency)) {
|
||||||
// running on different cores.
|
hires_frequency = li_frequency.QuadPart;
|
||||||
r = LIBUSB_ERROR_NO_MEM;
|
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
|
||||||
for (i = 0; i < 2; i++) {
|
// to picoseconds to compute the tv_nsecs part in clock_gettime
|
||||||
timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
|
||||||
if (timer_request[i] == NULL) {
|
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
|
||||||
usbi_err(ctx, "could not create timer request event %d - aborting", i);
|
} else {
|
||||||
goto init_exit;
|
usbi_dbg("no hires timer available on this platform");
|
||||||
}
|
hires_frequency = 0;
|
||||||
}
|
hires_ticks_to_ps = UINT64_C(0);
|
||||||
timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
|
|
||||||
if (timer_response == NULL) {
|
|
||||||
usbi_err(ctx, "could not create timer response semaphore - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
|
||||||
timer_mutex = CreateMutex(NULL, FALSE, NULL);
|
|
||||||
if (timer_mutex == NULL) {
|
|
||||||
usbi_err(ctx, "could not create timer mutex - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
|
||||||
timer_thread = CreateThread(NULL, 0, wince_clock_gettime_threaded, NULL, 0, NULL);
|
|
||||||
if (timer_thread == NULL) {
|
|
||||||
usbi_err(ctx, "Unable to create timer thread - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for timer thread to init before continuing.
|
|
||||||
if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
|
|
||||||
usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// At this stage, either we went through full init successfully, or didn't need to
|
// At this stage, either we went through full init successfully, or didn't need to
|
||||||
|
@ -250,30 +219,6 @@ init_exit: // Holds semaphore here.
|
||||||
UkwCloseDriver(driver_handle);
|
UkwCloseDriver(driver_handle);
|
||||||
driver_handle = INVALID_HANDLE_VALUE;
|
driver_handle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if (timer_thread) {
|
|
||||||
SetEvent(timer_request[1]); // actually the signal to quit the thread.
|
|
||||||
if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
|
|
||||||
usbi_warn(ctx, "could not wait for timer thread to quit");
|
|
||||||
TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
|
|
||||||
// all objects it might have held anyway.
|
|
||||||
}
|
|
||||||
CloseHandle(timer_thread);
|
|
||||||
timer_thread = NULL;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (timer_request[i]) {
|
|
||||||
CloseHandle(timer_request[i]);
|
|
||||||
timer_request[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timer_response) {
|
|
||||||
CloseHandle(timer_response);
|
|
||||||
timer_response = NULL;
|
|
||||||
}
|
|
||||||
if (timer_mutex) {
|
|
||||||
CloseHandle(timer_mutex);
|
|
||||||
timer_mutex = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r != LIBUSB_SUCCESS)
|
if (r != LIBUSB_SUCCESS)
|
||||||
|
@ -286,7 +231,6 @@ init_exit: // Holds semaphore here.
|
||||||
|
|
||||||
static void wince_exit(void)
|
static void wince_exit(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
HANDLE semaphore;
|
HANDLE semaphore;
|
||||||
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
||||||
|
|
||||||
|
@ -307,29 +251,6 @@ static void wince_exit(void)
|
||||||
if (--concurrent_usage < 0) { // Last exit
|
if (--concurrent_usage < 0) { // Last exit
|
||||||
exit_polling();
|
exit_polling();
|
||||||
|
|
||||||
if (timer_thread) {
|
|
||||||
SetEvent(timer_request[1]); // actually the signal to quit the thread.
|
|
||||||
if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
|
|
||||||
usbi_dbg("could not wait for timer thread to quit");
|
|
||||||
TerminateThread(timer_thread, 1);
|
|
||||||
}
|
|
||||||
CloseHandle(timer_thread);
|
|
||||||
timer_thread = NULL;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (timer_request[i]) {
|
|
||||||
CloseHandle(timer_request[i]);
|
|
||||||
timer_request[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timer_response) {
|
|
||||||
CloseHandle(timer_response);
|
|
||||||
timer_response = NULL;
|
|
||||||
}
|
|
||||||
if (timer_mutex) {
|
|
||||||
CloseHandle(timer_mutex);
|
|
||||||
timer_mutex = NULL;
|
|
||||||
}
|
|
||||||
if (driver_handle != INVALID_HANDLE_VALUE) {
|
if (driver_handle != INVALID_HANDLE_VALUE) {
|
||||||
UkwCloseDriver(driver_handle);
|
UkwCloseDriver(driver_handle);
|
||||||
driver_handle = INVALID_HANDLE_VALUE;
|
driver_handle = INVALID_HANDLE_VALUE;
|
||||||
|
@ -423,8 +344,8 @@ static void wince_close(struct libusb_device_handle *handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wince_get_device_descriptor(
|
static int wince_get_device_descriptor(
|
||||||
struct libusb_device *device,
|
struct libusb_device *device,
|
||||||
unsigned char *buffer, int *host_endian)
|
unsigned char *buffer, int *host_endian)
|
||||||
{
|
{
|
||||||
struct wince_device_priv *priv = _device_priv(device);
|
struct wince_device_priv *priv = _device_priv(device);
|
||||||
|
|
||||||
|
@ -461,8 +382,8 @@ static int wince_get_config_descriptor(
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wince_get_configuration(
|
static int wince_get_configuration(
|
||||||
struct libusb_device_handle *handle,
|
struct libusb_device_handle *handle,
|
||||||
int *config)
|
int *config)
|
||||||
{
|
{
|
||||||
struct wince_device_priv *priv = _device_priv(handle->dev);
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
||||||
UCHAR cv = 0;
|
UCHAR cv = 0;
|
||||||
|
@ -582,15 +503,13 @@ static int wince_attach_kernel_driver(
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wince_destroy_device(
|
static void wince_destroy_device(struct libusb_device *dev)
|
||||||
struct libusb_device *dev)
|
|
||||||
{
|
{
|
||||||
struct wince_device_priv *priv = _device_priv(dev);
|
struct wince_device_priv *priv = _device_priv(dev);
|
||||||
UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
|
UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wince_clear_transfer_priv(
|
static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
|
||||||
struct usbi_transfer *itransfer)
|
|
||||||
{
|
{
|
||||||
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
|
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
|
||||||
struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
|
struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
|
||||||
|
@ -600,8 +519,7 @@ static void wince_clear_transfer_priv(
|
||||||
usbi_free_fd(&transfer_priv->pollable_fd);
|
usbi_free_fd(&transfer_priv->pollable_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wince_cancel_transfer(
|
static int wince_cancel_transfer(struct usbi_transfer *itransfer)
|
||||||
struct usbi_transfer *itransfer)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_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_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
||||||
|
@ -667,7 +585,6 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer
|
||||||
return libusbErr;
|
return libusbErr;
|
||||||
}
|
}
|
||||||
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
|
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
|
||||||
itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
|
|
||||||
|
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -677,8 +594,7 @@ static int wince_submit_iso_transfer(struct usbi_transfer *itransfer)
|
||||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wince_submit_transfer(
|
static int wince_submit_transfer(struct usbi_transfer *itransfer)
|
||||||
struct usbi_transfer *itransfer)
|
|
||||||
{
|
{
|
||||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||||
|
|
||||||
|
@ -697,7 +613,9 @@ static int wince_submit_transfer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
|
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 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_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
|
||||||
|
@ -792,7 +710,9 @@ static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wince_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size)
|
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);
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||||
|
|
||||||
|
@ -804,7 +724,7 @@ static void wince_handle_callback (struct usbi_transfer *itransfer, uint32_t io_
|
||||||
wince_transfer_callback (itransfer, io_result, io_size);
|
wince_transfer_callback (itransfer, io_result, io_size);
|
||||||
break;
|
break;
|
||||||
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
||||||
return LIBUSB_ERROR_NOT_SUPPORTED;
|
break;
|
||||||
default:
|
default:
|
||||||
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
||||||
}
|
}
|
||||||
|
@ -853,9 +773,11 @@ static int wince_handle_events(
|
||||||
wince_handle_callback(transfer, io_result, io_size);
|
wince_handle_callback(transfer, io_result, io_size);
|
||||||
} else if (found) {
|
} else if (found) {
|
||||||
usbi_err(ctx, "matching transfer for fd %x has not completed", fds[i]);
|
usbi_err(ctx, "matching transfer for fd %x has not completed", fds[i]);
|
||||||
|
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||||
return LIBUSB_ERROR_OTHER;
|
return LIBUSB_ERROR_OTHER;
|
||||||
} else {
|
} else {
|
||||||
usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
|
usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
|
||||||
|
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||||
return LIBUSB_ERROR_NOT_FOUND;
|
return LIBUSB_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -867,105 +789,20 @@ static int wince_handle_events(
|
||||||
/*
|
/*
|
||||||
* Monotonic and real time functions
|
* Monotonic and real time functions
|
||||||
*/
|
*/
|
||||||
unsigned __stdcall wince_clock_gettime_threaded(void* param)
|
|
||||||
{
|
|
||||||
LARGE_INTEGER hires_counter, li_frequency;
|
|
||||||
LONG nb_responses;
|
|
||||||
int timer_index;
|
|
||||||
|
|
||||||
// Init - find out if we have access to a monotonic (hires) timer
|
|
||||||
if (!QueryPerformanceFrequency(&li_frequency)) {
|
|
||||||
usbi_dbg("no hires timer available on this platform");
|
|
||||||
hires_frequency = 0;
|
|
||||||
hires_ticks_to_ps = UINT64_C(0);
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal wince_init() that we're ready to service requests
|
|
||||||
if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
|
|
||||||
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main loop - wait for requests
|
|
||||||
while (1) {
|
|
||||||
timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
|
|
||||||
if ( (timer_index != 0) && (timer_index != 1) ) {
|
|
||||||
usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (request_count[timer_index] == 0) {
|
|
||||||
// Request already handled
|
|
||||||
ResetEvent(timer_request[timer_index]);
|
|
||||||
// There's still a possiblity that a thread sends a request between the
|
|
||||||
// time we test request_count[] == 0 and we reset the event, in which case
|
|
||||||
// the request would be ignored. The simple solution to that is to test
|
|
||||||
// request_count again and process requests if non zero.
|
|
||||||
if (request_count[timer_index] == 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (timer_index) {
|
|
||||||
case 0:
|
|
||||||
WaitForSingleObject(timer_mutex, INFINITE);
|
|
||||||
// Requests to this thread are for hires always
|
|
||||||
if (QueryPerformanceCounter(&hires_counter) != 0) {
|
|
||||||
timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
|
||||||
timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
|
|
||||||
} else {
|
|
||||||
// Fallback to real-time if we can't get monotonic value
|
|
||||||
// Note that real-time clock does not wait on the mutex or this thread.
|
|
||||||
wince_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
|
|
||||||
}
|
|
||||||
ReleaseMutex(timer_mutex);
|
|
||||||
|
|
||||||
nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
|
|
||||||
if ( (nb_responses)
|
|
||||||
&& (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
|
|
||||||
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
case 1: // time to quit
|
|
||||||
usbi_dbg("timer thread quitting");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usbi_dbg("ERROR: broken timer thread");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wince_clock_gettime(int clk_id, struct timespec *tp)
|
static int wince_clock_gettime(int clk_id, struct timespec *tp)
|
||||||
{
|
{
|
||||||
FILETIME filetime;
|
LARGE_INTEGER hires_counter;
|
||||||
ULARGE_INTEGER rtime;
|
ULARGE_INTEGER rtime;
|
||||||
DWORD r;
|
FILETIME filetime;
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
switch(clk_id) {
|
switch(clk_id) {
|
||||||
case USBI_CLOCK_MONOTONIC:
|
case USBI_CLOCK_MONOTONIC:
|
||||||
if (hires_frequency != 0) {
|
if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
|
||||||
while (1) {
|
tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
||||||
InterlockedIncrement((LONG*)&request_count[0]);
|
tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
|
||||||
SetEvent(timer_request[0]);
|
return LIBUSB_SUCCESS;
|
||||||
r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
|
|
||||||
switch(r) {
|
|
||||||
case WAIT_OBJECT_0:
|
|
||||||
WaitForSingleObject(timer_mutex, INFINITE);
|
|
||||||
*tp = timer_tp;
|
|
||||||
ReleaseMutex(timer_mutex);
|
|
||||||
return LIBUSB_SUCCESS;
|
|
||||||
case WAIT_TIMEOUT:
|
|
||||||
usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
|
|
||||||
break; // Retry until successful
|
|
||||||
default:
|
|
||||||
usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
|
|
||||||
return LIBUSB_ERROR_OTHER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Fall through and return real-time if monotonic was not detected @ timer init
|
// Fall through and return real-time if monotonic read failed or was not detected @ init
|
||||||
case USBI_CLOCK_REALTIME:
|
case USBI_CLOCK_REALTIME:
|
||||||
// We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
|
// 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
|
// with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
|
||||||
|
@ -985,48 +822,48 @@ static int wince_clock_gettime(int clk_id, struct timespec *tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct usbi_os_backend wince_backend = {
|
const struct usbi_os_backend wince_backend = {
|
||||||
"Windows CE",
|
"Windows CE",
|
||||||
0,
|
0,
|
||||||
wince_init,
|
wince_init,
|
||||||
wince_exit,
|
wince_exit,
|
||||||
|
|
||||||
wince_get_device_list,
|
wince_get_device_list,
|
||||||
NULL, /* hotplug_poll */
|
NULL, /* hotplug_poll */
|
||||||
wince_open,
|
wince_open,
|
||||||
wince_close,
|
wince_close,
|
||||||
|
|
||||||
wince_get_device_descriptor,
|
wince_get_device_descriptor,
|
||||||
wince_get_active_config_descriptor,
|
wince_get_active_config_descriptor,
|
||||||
wince_get_config_descriptor,
|
wince_get_config_descriptor,
|
||||||
NULL, /* get_config_descriptor_by_value() */
|
NULL, /* get_config_descriptor_by_value() */
|
||||||
|
|
||||||
wince_get_configuration,
|
wince_get_configuration,
|
||||||
wince_set_configuration,
|
wince_set_configuration,
|
||||||
wince_claim_interface,
|
wince_claim_interface,
|
||||||
wince_release_interface,
|
wince_release_interface,
|
||||||
|
|
||||||
wince_set_interface_altsetting,
|
wince_set_interface_altsetting,
|
||||||
wince_clear_halt,
|
wince_clear_halt,
|
||||||
wince_reset_device,
|
wince_reset_device,
|
||||||
|
|
||||||
NULL, /* alloc_streams */
|
NULL, /* alloc_streams */
|
||||||
NULL, /* free_streams */
|
NULL, /* free_streams */
|
||||||
|
|
||||||
wince_kernel_driver_active,
|
wince_kernel_driver_active,
|
||||||
wince_detach_kernel_driver,
|
wince_detach_kernel_driver,
|
||||||
wince_attach_kernel_driver,
|
wince_attach_kernel_driver,
|
||||||
|
|
||||||
wince_destroy_device,
|
wince_destroy_device,
|
||||||
|
|
||||||
wince_submit_transfer,
|
wince_submit_transfer,
|
||||||
wince_cancel_transfer,
|
wince_cancel_transfer,
|
||||||
wince_clear_transfer_priv,
|
wince_clear_transfer_priv,
|
||||||
|
|
||||||
wince_handle_events,
|
wince_handle_events,
|
||||||
|
NULL, /* handle_transfer_completion() */
|
||||||
|
|
||||||
wince_clock_gettime,
|
wince_clock_gettime,
|
||||||
sizeof(struct wince_device_priv),
|
sizeof(struct wince_device_priv),
|
||||||
sizeof(struct wince_device_handle_priv),
|
sizeof(struct wince_device_handle_priv),
|
||||||
sizeof(struct wince_transfer_priv),
|
sizeof(struct wince_transfer_priv),
|
||||||
0,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
|
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
|
||||||
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
|
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
|
||||||
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
|
#define safe_min(a, b) MIN((size_t)(a), (size_t)(b))
|
||||||
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
|
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
|
||||||
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
|
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
|
||||||
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
|
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <setupapi.h>
|
#include <setupapi.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -106,13 +107,8 @@ static char windows_version_str[128] = "Windows Undefined";
|
||||||
static int concurrent_usage = -1;
|
static int concurrent_usage = -1;
|
||||||
usbi_mutex_t autoclaim_lock;
|
usbi_mutex_t autoclaim_lock;
|
||||||
// Timer thread
|
// Timer thread
|
||||||
// NB: index 0 is for monotonic and 1 is for the thread exit event
|
|
||||||
HANDLE timer_thread = NULL;
|
HANDLE timer_thread = NULL;
|
||||||
HANDLE timer_mutex = NULL;
|
DWORD timer_thread_id = 0;
|
||||||
struct timespec timer_tp;
|
|
||||||
volatile LONG request_count[2] = {0, 1}; // last one must be > 0
|
|
||||||
HANDLE timer_request[2] = { NULL, NULL };
|
|
||||||
HANDLE timer_response = NULL;
|
|
||||||
// API globals
|
// API globals
|
||||||
#define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
|
#define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \
|
||||||
if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
|
if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0)
|
||||||
|
@ -257,6 +253,9 @@ static int init_dlls(void)
|
||||||
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
|
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
|
||||||
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
|
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
|
||||||
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
|
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
|
||||||
|
DLL_LOAD_PREFIXED(User32.dll, p, GetMessageA, TRUE);
|
||||||
|
DLL_LOAD_PREFIXED(User32.dll, p, PeekMessageA, TRUE);
|
||||||
|
DLL_LOAD_PREFIXED(User32.dll, p, PostThreadMessageA, TRUE);
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,6 +660,32 @@ static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
|
||||||
return session_id;
|
return session_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine which interface the given endpoint address belongs to
|
||||||
|
*/
|
||||||
|
static int get_interface_by_endpoint(struct libusb_config_descriptor *conf_desc, uint8_t ep)
|
||||||
|
{
|
||||||
|
const struct libusb_interface *intf;
|
||||||
|
const struct libusb_interface_descriptor *intf_desc;
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
for (i = 0; i < conf_desc->bNumInterfaces; i++) {
|
||||||
|
intf = &conf_desc->interface[i];
|
||||||
|
for (j = 0; j < intf->num_altsetting; j++) {
|
||||||
|
intf_desc = &intf->altsetting[j];
|
||||||
|
for (k = 0; k < intf_desc->bNumEndpoints; k++) {
|
||||||
|
if (intf_desc->endpoint[k].bEndpointAddress == ep) {
|
||||||
|
usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber);
|
||||||
|
return intf_desc->bInterfaceNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usbi_dbg("endpoint %02X not found on any interface", ep);
|
||||||
|
return LIBUSB_ERROR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Populate the endpoints addresses of the device_priv interface helper structs
|
* Populate the endpoints addresses of the device_priv interface helper structs
|
||||||
*/
|
*/
|
||||||
|
@ -672,7 +697,7 @@ static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int
|
||||||
const struct libusb_interface_descriptor *if_desc;
|
const struct libusb_interface_descriptor *if_desc;
|
||||||
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
|
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
|
||||||
|
|
||||||
r = libusb_get_config_descriptor(dev_handle->dev, 0, &conf_desc);
|
r = libusb_get_config_descriptor(dev_handle->dev, (uint8_t)(priv->active_config-1), &conf_desc);
|
||||||
if (r != LIBUSB_SUCCESS) {
|
if (r != LIBUSB_SUCCESS) {
|
||||||
usbi_warn(ctx, "could not read config descriptor: error %d", r);
|
usbi_warn(ctx, "could not read config descriptor: error %d", r);
|
||||||
return r;
|
return r;
|
||||||
|
@ -889,13 +914,13 @@ static void get_windows_version(void)
|
||||||
break;
|
break;
|
||||||
case 0x63: w = (ws?"8.1":"2012_R2");
|
case 0x63: w = (ws?"8.1":"2012_R2");
|
||||||
break;
|
break;
|
||||||
case 0x64: w = (ws?"8.2":"2012_R3");
|
case 0x64: w = (ws?"10":"2015");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (windows_version < 0x50)
|
if (windows_version < 0x50)
|
||||||
windows_version = WINDOWS_UNSUPPORTED;
|
windows_version = WINDOWS_UNSUPPORTED;
|
||||||
else
|
else
|
||||||
w = "9 or later";
|
w = "11 or later";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -927,7 +952,10 @@ static void get_windows_version(void)
|
||||||
static int windows_init(struct libusb_context *ctx)
|
static int windows_init(struct libusb_context *ctx)
|
||||||
{
|
{
|
||||||
int i, r = LIBUSB_ERROR_OTHER;
|
int i, r = LIBUSB_ERROR_OTHER;
|
||||||
|
DWORD_PTR affinity, dummy;
|
||||||
|
HANDLE event = NULL;
|
||||||
HANDLE semaphore;
|
HANDLE semaphore;
|
||||||
|
LARGE_INTEGER li_frequency;
|
||||||
char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
||||||
|
|
||||||
sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
|
sprintf(sem_name, "libusb_init%08X", (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
|
||||||
|
@ -965,7 +993,7 @@ static int windows_init(struct libusb_context *ctx)
|
||||||
// Load DLL imports
|
// Load DLL imports
|
||||||
if (init_dlls() != LIBUSB_SUCCESS) {
|
if (init_dlls() != LIBUSB_SUCCESS) {
|
||||||
usbi_err(ctx, "could not resolve DLL functions");
|
usbi_err(ctx, "could not resolve DLL functions");
|
||||||
return LIBUSB_ERROR_NOT_FOUND;
|
goto init_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the low level APIs (we don't care about errors at this stage)
|
// Initialize the low level APIs (we don't care about errors at this stage)
|
||||||
|
@ -973,38 +1001,53 @@ static int windows_init(struct libusb_context *ctx)
|
||||||
usb_api_backend[i].init(SUB_API_NOTSET, ctx);
|
usb_api_backend[i].init(SUB_API_NOTSET, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Because QueryPerformanceCounter might report different values when
|
if (QueryPerformanceFrequency(&li_frequency)) {
|
||||||
// running on different cores, we create a separate thread for the timer
|
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
|
||||||
// calls, which we glue to the first core always to prevent timing discrepancies.
|
// to picoseconds to compute the tv_nsecs part in clock_gettime
|
||||||
r = LIBUSB_ERROR_NO_MEM;
|
hires_frequency = li_frequency.QuadPart;
|
||||||
for (i = 0; i < 2; i++) {
|
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
|
||||||
timer_request[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
|
||||||
if (timer_request[i] == NULL) {
|
|
||||||
usbi_err(ctx, "could not create timer request event %d - aborting", i);
|
// Because QueryPerformanceCounter might report different values when
|
||||||
|
// running on different cores, we create a separate thread for the timer
|
||||||
|
// calls, which we glue to the first available core always to prevent timing discrepancies.
|
||||||
|
if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) {
|
||||||
|
usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0));
|
||||||
|
goto init_exit;
|
||||||
|
}
|
||||||
|
// The process affinity mask is a bitmask where each set bit represents a core on
|
||||||
|
// which this process is allowed to run, so we find the first set bit
|
||||||
|
for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++);
|
||||||
|
affinity = (DWORD_PTR)(1 << i);
|
||||||
|
|
||||||
|
usbi_dbg("timer thread will run on core #%d", i);
|
||||||
|
|
||||||
|
r = LIBUSB_ERROR_NO_MEM;
|
||||||
|
event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
if (event == NULL) {
|
||||||
|
usbi_err(ctx, "could not create event: %s", windows_error_str(0));
|
||||||
|
goto init_exit;
|
||||||
|
}
|
||||||
|
timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event,
|
||||||
|
0, (unsigned int *)&timer_thread_id);
|
||||||
|
if (timer_thread == NULL) {
|
||||||
|
usbi_err(ctx, "unable to create timer thread - aborting");
|
||||||
|
goto init_exit;
|
||||||
|
}
|
||||||
|
if (!SetThreadAffinityMask(timer_thread, affinity)) {
|
||||||
|
usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for timer thread to init before continuing.
|
||||||
|
if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
|
||||||
|
usbi_err(ctx, "failed to wait for timer thread to become ready - aborting");
|
||||||
goto init_exit;
|
goto init_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
|
else {
|
||||||
if (timer_response == NULL) {
|
usbi_dbg("no hires timer available on this platform");
|
||||||
usbi_err(ctx, "could not create timer response semaphore - aborting");
|
hires_frequency = 0;
|
||||||
goto init_exit;
|
hires_ticks_to_ps = UINT64_C(0);
|
||||||
}
|
|
||||||
timer_mutex = CreateMutex(NULL, FALSE, NULL);
|
|
||||||
if (timer_mutex == NULL) {
|
|
||||||
usbi_err(ctx, "could not create timer mutex - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
|
||||||
timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
|
|
||||||
if (timer_thread == NULL) {
|
|
||||||
usbi_err(ctx, "Unable to create timer thread - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
|
||||||
SetThreadAffinityMask(timer_thread, 0);
|
|
||||||
|
|
||||||
// Wait for timer thread to init before continuing.
|
|
||||||
if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
|
|
||||||
usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
|
|
||||||
goto init_exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a hash table to store session ids. Second parameter is better if prime
|
// Create a hash table to store session ids. Second parameter is better if prime
|
||||||
|
@ -1016,35 +1059,27 @@ static int windows_init(struct libusb_context *ctx)
|
||||||
init_exit: // Holds semaphore here.
|
init_exit: // Holds semaphore here.
|
||||||
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
|
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
|
||||||
if (timer_thread) {
|
if (timer_thread) {
|
||||||
SetEvent(timer_request[1]); // actually the signal to quit the thread.
|
// actually the signal to quit the thread.
|
||||||
if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
|
if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0) ||
|
||||||
|
(WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
|
||||||
usbi_warn(ctx, "could not wait for timer thread to quit");
|
usbi_warn(ctx, "could not wait for timer thread to quit");
|
||||||
TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
|
TerminateThread(timer_thread, 1);
|
||||||
// all objects it might have held anyway.
|
// shouldn't happen, but we're destroying
|
||||||
|
// all objects it might have held anyway.
|
||||||
}
|
}
|
||||||
CloseHandle(timer_thread);
|
CloseHandle(timer_thread);
|
||||||
timer_thread = NULL;
|
timer_thread = NULL;
|
||||||
}
|
timer_thread_id = 0;
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (timer_request[i]) {
|
|
||||||
CloseHandle(timer_request[i]);
|
|
||||||
timer_request[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timer_response) {
|
|
||||||
CloseHandle(timer_response);
|
|
||||||
timer_response = NULL;
|
|
||||||
}
|
|
||||||
if (timer_mutex) {
|
|
||||||
CloseHandle(timer_mutex);
|
|
||||||
timer_mutex = NULL;
|
|
||||||
}
|
}
|
||||||
htab_destroy();
|
htab_destroy();
|
||||||
|
usbi_mutex_destroy(&autoclaim_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r != LIBUSB_SUCCESS)
|
if (r != LIBUSB_SUCCESS)
|
||||||
--concurrent_usage; // Not expected to call libusb_exit if we failed.
|
--concurrent_usage; // Not expected to call libusb_exit if we failed.
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
CloseHandle(event);
|
||||||
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
||||||
CloseHandle(semaphore);
|
CloseHandle(semaphore);
|
||||||
return r;
|
return r;
|
||||||
|
@ -1124,7 +1159,7 @@ static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle
|
||||||
cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
|
cd_buf_short.req.SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
|
||||||
cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
cd_buf_short.req.SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||||
cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
|
cd_buf_short.req.SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
|
||||||
cd_buf_short.req.SetupPacket.wIndex = i;
|
cd_buf_short.req.SetupPacket.wIndex = 0;
|
||||||
cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
|
cd_buf_short.req.SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
|
||||||
|
|
||||||
// Dummy call to get the required data size. Initial failures are reported as info rather
|
// Dummy call to get the required data size. Initial failures are reported as info rather
|
||||||
|
@ -1153,7 +1188,7 @@ static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle
|
||||||
cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
|
cd_buf_actual->SetupPacket.bmRequest = LIBUSB_ENDPOINT_IN;
|
||||||
cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
cd_buf_actual->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||||
cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
|
cd_buf_actual->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8) | i;
|
||||||
cd_buf_actual->SetupPacket.wIndex = i;
|
cd_buf_actual->SetupPacket.wIndex = 0;
|
||||||
cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
|
cd_buf_actual->SetupPacket.wLength = (USHORT)(size - sizeof(USB_DESCRIPTOR_REQUEST));
|
||||||
|
|
||||||
if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
|
if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, cd_buf_actual, size,
|
||||||
|
@ -1199,6 +1234,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
||||||
struct windows_device_priv *priv, *parent_priv;
|
struct windows_device_priv *priv, *parent_priv;
|
||||||
struct libusb_context *ctx;
|
struct libusb_context *ctx;
|
||||||
struct libusb_device* tmp_dev;
|
struct libusb_device* tmp_dev;
|
||||||
|
unsigned long tmp_id;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if ((dev == NULL) || (parent_dev == NULL)) {
|
if ((dev == NULL) || (parent_dev == NULL)) {
|
||||||
|
@ -1216,8 +1252,10 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
||||||
// If that's the case, lookup the ancestors to set the bus number
|
// If that's the case, lookup the ancestors to set the bus number
|
||||||
if (parent_dev->bus_number == 0) {
|
if (parent_dev->bus_number == 0) {
|
||||||
for (i=2; ; i++) {
|
for (i=2; ; i++) {
|
||||||
tmp_dev = usbi_get_device_by_session_id(ctx, get_ancestor_session_id(devinst, i));
|
tmp_id = get_ancestor_session_id(devinst, i);
|
||||||
if (tmp_dev == NULL) break;
|
if (tmp_id == 0) break;
|
||||||
|
tmp_dev = usbi_get_device_by_session_id(ctx, tmp_id);
|
||||||
|
if (tmp_dev == NULL) continue;
|
||||||
if (tmp_dev->bus_number != 0) {
|
if (tmp_dev->bus_number != 0) {
|
||||||
usbi_dbg("got bus number from ancestor #%d", i);
|
usbi_dbg("got bus number from ancestor #%d", i);
|
||||||
parent_dev->bus_number = tmp_dev->bus_number;
|
parent_dev->bus_number = tmp_dev->bus_number;
|
||||||
|
@ -1525,7 +1563,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
||||||
//#define ENUM_DEBUG
|
//#define ENUM_DEBUG
|
||||||
#ifdef ENUM_DEBUG
|
#ifdef ENUM_DEBUG
|
||||||
const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
|
const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" };
|
||||||
usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
|
usbi_dbg("#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1],
|
||||||
(pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
|
(pass!=GEN_PASS)?guid_to_string(guid[pass]):"");
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; ; i++) {
|
for (i = 0; ; i++) {
|
||||||
|
@ -1627,6 +1665,10 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
||||||
LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
|
LOOP_BREAK(LIBUSB_ERROR_OVERFLOW);
|
||||||
}
|
}
|
||||||
if_guid = (GUID*) calloc(1, sizeof(GUID));
|
if_guid = (GUID*) calloc(1, sizeof(GUID));
|
||||||
|
if (if_guid == NULL) {
|
||||||
|
usbi_err(ctx, "could not calloc for if_guid: not enough memory");
|
||||||
|
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
|
||||||
|
}
|
||||||
pCLSIDFromString(guid_string_w, if_guid);
|
pCLSIDFromString(guid_string_w, if_guid);
|
||||||
guid[nb_guids++] = if_guid;
|
guid[nb_guids++] = if_guid;
|
||||||
usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
|
usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
|
||||||
|
@ -1849,29 +1891,18 @@ static void windows_exit(void)
|
||||||
exit_polling();
|
exit_polling();
|
||||||
|
|
||||||
if (timer_thread) {
|
if (timer_thread) {
|
||||||
SetEvent(timer_request[1]); // actually the signal to quit the thread.
|
// actually the signal to quit the thread.
|
||||||
if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
|
if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_EXIT, 0, 0) ||
|
||||||
|
(WaitForSingleObject(timer_thread, INFINITE) != WAIT_OBJECT_0)) {
|
||||||
usbi_dbg("could not wait for timer thread to quit");
|
usbi_dbg("could not wait for timer thread to quit");
|
||||||
TerminateThread(timer_thread, 1);
|
TerminateThread(timer_thread, 1);
|
||||||
}
|
}
|
||||||
CloseHandle(timer_thread);
|
CloseHandle(timer_thread);
|
||||||
timer_thread = NULL;
|
timer_thread = NULL;
|
||||||
}
|
timer_thread_id = 0;
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (timer_request[i]) {
|
|
||||||
CloseHandle(timer_request[i]);
|
|
||||||
timer_request[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timer_response) {
|
|
||||||
CloseHandle(timer_response);
|
|
||||||
timer_response = NULL;
|
|
||||||
}
|
|
||||||
if (timer_mutex) {
|
|
||||||
CloseHandle(timer_mutex);
|
|
||||||
timer_mutex = NULL;
|
|
||||||
}
|
}
|
||||||
htab_destroy();
|
htab_destroy();
|
||||||
|
usbi_mutex_destroy(&autoclaim_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
|
||||||
|
@ -1903,7 +1934,7 @@ static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t conf
|
||||||
|
|
||||||
config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
|
config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptor[config_index];
|
||||||
|
|
||||||
size = min(config_header->wTotalLength, len);
|
size = MIN(config_header->wTotalLength, len);
|
||||||
memcpy(buffer, priv->config_descriptor[config_index], size);
|
memcpy(buffer, priv->config_descriptor[config_index], size);
|
||||||
*host_endian = 0;
|
*host_endian = 0;
|
||||||
|
|
||||||
|
@ -1986,9 +2017,6 @@ static int windows_claim_interface(struct libusb_device_handle *dev_handle, int
|
||||||
int r = LIBUSB_SUCCESS;
|
int r = LIBUSB_SUCCESS;
|
||||||
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
||||||
|
|
||||||
if (iface >= USB_MAXINTERFACES)
|
|
||||||
return LIBUSB_ERROR_INVALID_PARAM;
|
|
||||||
|
|
||||||
safe_free(priv->usb_interface[iface].endpoint);
|
safe_free(priv->usb_interface[iface].endpoint);
|
||||||
priv->usb_interface[iface].nb_endpoints= 0;
|
priv->usb_interface[iface].nb_endpoints= 0;
|
||||||
|
|
||||||
|
@ -2084,7 +2112,6 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
||||||
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
|
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
|
||||||
(short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
|
(short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
|
||||||
|
|
||||||
itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
|
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2104,7 +2131,6 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
||||||
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
|
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd,
|
||||||
(short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
|
(short)(IS_XFERIN(transfer) ? POLLIN : POLLOUT));
|
||||||
|
|
||||||
itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
|
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2123,7 +2149,6 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
|
||||||
|
|
||||||
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
|
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, POLLIN);
|
||||||
|
|
||||||
itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
|
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2251,7 +2276,7 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
|
||||||
{
|
{
|
||||||
struct windows_transfer_priv* transfer_priv = NULL;
|
struct windows_transfer_priv* transfer_priv = NULL;
|
||||||
POLL_NFDS_TYPE i = 0;
|
POLL_NFDS_TYPE i = 0;
|
||||||
bool found = false;
|
bool found;
|
||||||
struct usbi_transfer *transfer;
|
struct usbi_transfer *transfer;
|
||||||
DWORD io_size, io_result;
|
DWORD io_size, io_result;
|
||||||
|
|
||||||
|
@ -2269,6 +2294,7 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
|
||||||
// Because a Windows OVERLAPPED is used for poll emulation,
|
// Because a Windows OVERLAPPED is used for poll emulation,
|
||||||
// a pollable fd is created and stored with each transfer
|
// a pollable fd is created and stored with each transfer
|
||||||
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
||||||
|
found = false;
|
||||||
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
||||||
transfer_priv = usbi_transfer_get_os_priv(transfer);
|
transfer_priv = usbi_transfer_get_os_priv(transfer);
|
||||||
if (transfer_priv->pollable_fd.fd == fds[i].fd) {
|
if (transfer_priv->pollable_fd.fd == fds[i].fd) {
|
||||||
|
@ -2296,6 +2322,7 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
|
||||||
// newly allocated wfd that took the place of the one from the transfer.
|
// newly allocated wfd that took the place of the one from the transfer.
|
||||||
windows_handle_callback(transfer, io_result, io_size);
|
windows_handle_callback(transfer, io_result, io_size);
|
||||||
} else {
|
} else {
|
||||||
|
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||||
usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
|
usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
|
||||||
return LIBUSB_ERROR_NOT_FOUND;
|
return LIBUSB_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -2310,66 +2337,42 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
|
||||||
*/
|
*/
|
||||||
unsigned __stdcall windows_clock_gettime_threaded(void* param)
|
unsigned __stdcall windows_clock_gettime_threaded(void* param)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER hires_counter, li_frequency;
|
struct timer_request *request;
|
||||||
LONG nb_responses;
|
LARGE_INTEGER hires_counter;
|
||||||
int timer_index;
|
MSG msg;
|
||||||
|
|
||||||
// Init - find out if we have access to a monotonic (hires) timer
|
// The following call will create this thread's message queue
|
||||||
if (!QueryPerformanceFrequency(&li_frequency)) {
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644946.aspx
|
||||||
usbi_dbg("no hires timer available on this platform");
|
pPeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
||||||
hires_frequency = 0;
|
|
||||||
hires_ticks_to_ps = UINT64_C(0);
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal windows_init() that we're ready to service requests
|
// Signal windows_init() that we're ready to service requests
|
||||||
if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
|
if (!SetEvent((HANDLE)param)) {
|
||||||
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
usbi_dbg("SetEvent failed for timer init event: %s", windows_error_str(0));
|
||||||
}
|
}
|
||||||
|
param = NULL;
|
||||||
|
|
||||||
// Main loop - wait for requests
|
// Main loop - wait for requests
|
||||||
while (1) {
|
while (1) {
|
||||||
timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
|
if (pGetMessageA(&msg, NULL, WM_TIMER_REQUEST, WM_TIMER_EXIT) == -1) {
|
||||||
if ( (timer_index != 0) && (timer_index != 1) ) {
|
usbi_err(NULL, "GetMessage failed for timer thread: %s", windows_error_str(0));
|
||||||
usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
|
return 1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (request_count[timer_index] == 0) {
|
|
||||||
// Request already handled
|
|
||||||
ResetEvent(timer_request[timer_index]);
|
|
||||||
// There's still a possiblity that a thread sends a request between the
|
|
||||||
// time we test request_count[] == 0 and we reset the event, in which case
|
|
||||||
// the request would be ignored. The simple solution to that is to test
|
|
||||||
// request_count again and process requests if non zero.
|
|
||||||
if (request_count[timer_index] == 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (timer_index) {
|
|
||||||
case 0:
|
|
||||||
WaitForSingleObject(timer_mutex, INFINITE);
|
|
||||||
// Requests to this thread are for hires always
|
|
||||||
if ((QueryPerformanceCounter(&hires_counter) != 0) && (hires_frequency != 0)) {
|
|
||||||
timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
|
||||||
timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
|
|
||||||
} else {
|
|
||||||
// Fallback to real-time if we can't get monotonic value
|
|
||||||
// Note that real-time clock does not wait on the mutex or this thread.
|
|
||||||
windows_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
|
|
||||||
}
|
|
||||||
ReleaseMutex(timer_mutex);
|
|
||||||
|
|
||||||
nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
|
switch (msg.message) {
|
||||||
if ( (nb_responses)
|
case WM_TIMER_REQUEST:
|
||||||
&& (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
|
// Requests to this thread are for hires always
|
||||||
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
// Microsoft says that this function always succeeds on XP and later
|
||||||
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904.aspx
|
||||||
|
request = (struct timer_request *)msg.lParam;
|
||||||
|
QueryPerformanceCounter(&hires_counter);
|
||||||
|
request->tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
||||||
|
request->tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
|
||||||
|
if (!SetEvent(request->event)) {
|
||||||
|
usbi_err(NULL, "SetEvent failed for timer request: %s", windows_error_str(0));
|
||||||
}
|
}
|
||||||
continue;
|
break;
|
||||||
case 1: // time to quit
|
|
||||||
|
case WM_TIMER_EXIT:
|
||||||
usbi_dbg("timer thread quitting");
|
usbi_dbg("timer thread quitting");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2378,29 +2381,41 @@ unsigned __stdcall windows_clock_gettime_threaded(void* param)
|
||||||
|
|
||||||
static int windows_clock_gettime(int clk_id, struct timespec *tp)
|
static int windows_clock_gettime(int clk_id, struct timespec *tp)
|
||||||
{
|
{
|
||||||
|
struct timer_request request;
|
||||||
FILETIME filetime;
|
FILETIME filetime;
|
||||||
ULARGE_INTEGER rtime;
|
ULARGE_INTEGER rtime;
|
||||||
DWORD r;
|
DWORD r;
|
||||||
switch(clk_id) {
|
switch(clk_id) {
|
||||||
case USBI_CLOCK_MONOTONIC:
|
case USBI_CLOCK_MONOTONIC:
|
||||||
if (hires_frequency != 0) {
|
if (timer_thread) {
|
||||||
while (1) {
|
request.tp = tp;
|
||||||
InterlockedIncrement((LONG*)&request_count[0]);
|
request.event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
SetEvent(timer_request[0]);
|
if (request.event == NULL) {
|
||||||
r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
|
return LIBUSB_ERROR_NO_MEM;
|
||||||
switch(r) {
|
}
|
||||||
case WAIT_OBJECT_0:
|
|
||||||
WaitForSingleObject(timer_mutex, INFINITE);
|
if (!pPostThreadMessageA(timer_thread_id, WM_TIMER_REQUEST, 0, (LPARAM)&request)) {
|
||||||
*tp = timer_tp;
|
usbi_err(NULL, "PostThreadMessage failed for timer thread: %s", windows_error_str(0));
|
||||||
ReleaseMutex(timer_mutex);
|
CloseHandle(request.event);
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_ERROR_OTHER;
|
||||||
case WAIT_TIMEOUT:
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
r = WaitForSingleObject(request.event, TIMER_REQUEST_RETRY_MS);
|
||||||
|
if (r == WAIT_TIMEOUT) {
|
||||||
usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
|
usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
|
||||||
break; // Retry until successful
|
|
||||||
default:
|
|
||||||
usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
|
|
||||||
return LIBUSB_ERROR_OTHER;
|
|
||||||
}
|
}
|
||||||
|
else if (r == WAIT_FAILED) {
|
||||||
|
usbi_err(NULL, "WaitForSingleObject failed: %s", windows_error_str(0));
|
||||||
|
}
|
||||||
|
} while (r == WAIT_TIMEOUT);
|
||||||
|
CloseHandle(request.event);
|
||||||
|
|
||||||
|
if (r == WAIT_OBJECT_0) {
|
||||||
|
return LIBUSB_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return LIBUSB_ERROR_OTHER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fall through and return real-time if monotonic was not detected @ timer init
|
// Fall through and return real-time if monotonic was not detected @ timer init
|
||||||
|
@ -2462,6 +2477,7 @@ const struct usbi_os_backend windows_backend = {
|
||||||
windows_clear_transfer_priv,
|
windows_clear_transfer_priv,
|
||||||
|
|
||||||
windows_handle_events,
|
windows_handle_events,
|
||||||
|
NULL, /* handle_transfer_completion() */
|
||||||
|
|
||||||
windows_clock_gettime,
|
windows_clock_gettime,
|
||||||
#if defined(USBI_TIMERFD_AVAILABLE)
|
#if defined(USBI_TIMERFD_AVAILABLE)
|
||||||
|
@ -2470,7 +2486,6 @@ const struct usbi_os_backend windows_backend = {
|
||||||
sizeof(struct windows_device_priv),
|
sizeof(struct windows_device_priv),
|
||||||
sizeof(struct windows_device_handle_priv),
|
sizeof(struct windows_device_handle_priv),
|
||||||
sizeof(struct windows_transfer_priv),
|
sizeof(struct windows_transfer_priv),
|
||||||
0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2668,7 +2683,7 @@ static int winusbx_init(int sub_api, struct libusb_context *ctx)
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
h = LoadLibraryA("WinUSB");
|
h = LoadLibraryA("WinUSB");
|
||||||
} if (h == NULL) {
|
} if (h == NULL) {
|
||||||
usbi_warn(ctx, "WinUSB DLL is not available either,\n"
|
usbi_warn(ctx, "WinUSB DLL is not available either, "
|
||||||
"you will not be able to access devices outside of enumeration");
|
"you will not be able to access devices outside of enumeration");
|
||||||
return LIBUSB_ERROR_NOT_FOUND;
|
return LIBUSB_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -2769,7 +2784,7 @@ static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
|
||||||
{
|
{
|
||||||
struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
|
struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
|
||||||
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
||||||
HANDLE file_handle;
|
HANDLE handle;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (sub_api == SUB_API_NOTSET)
|
if (sub_api == SUB_API_NOTSET)
|
||||||
|
@ -2777,14 +2792,40 @@ static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
|
||||||
if (!WinUSBX[sub_api].initialized)
|
if (!WinUSBX[sub_api].initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < USB_MAXINTERFACES; i++) {
|
if (priv->apib->id == USB_API_COMPOSITE) {
|
||||||
if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
|
// If this is a composite device, just free and close all WinUSB-like
|
||||||
file_handle = handle_priv->interface_handle[i].dev_handle;
|
// interfaces directly (each is independent and not associated with another)
|
||||||
if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) {
|
for (i = 0; i < USB_MAXINTERFACES; i++) {
|
||||||
CloseHandle(file_handle);
|
if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) {
|
||||||
|
handle = handle_priv->interface_handle[i].api_handle;
|
||||||
|
if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
|
||||||
|
WinUSBX[sub_api].Free(handle);
|
||||||
|
}
|
||||||
|
handle = handle_priv->interface_handle[i].dev_handle;
|
||||||
|
if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// If this is a WinUSB device, free all interfaces above interface 0,
|
||||||
|
// then free and close interface 0 last
|
||||||
|
for (i = 1; i < USB_MAXINTERFACES; i++) {
|
||||||
|
handle = handle_priv->interface_handle[i].api_handle;
|
||||||
|
if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
|
||||||
|
WinUSBX[sub_api].Free(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handle = handle_priv->interface_handle[0].api_handle;
|
||||||
|
if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
|
||||||
|
WinUSBX[sub_api].Free(handle);
|
||||||
|
}
|
||||||
|
handle = handle_priv->interface_handle[0].dev_handle;
|
||||||
|
if ((handle != 0) && (handle != INVALID_HANDLE_VALUE)) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
|
static int winusbx_configure_endpoints(int sub_api, struct libusb_device_handle *dev_handle, int iface)
|
||||||
|
@ -3579,7 +3620,7 @@ static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, i
|
||||||
return LIBUSB_ERROR_OTHER;
|
return LIBUSB_ERROR_OTHER;
|
||||||
}
|
}
|
||||||
usbi_dbg("unsupported");
|
usbi_dbg("unsupported");
|
||||||
return LIBUSB_ERROR_INVALID_PARAM;
|
return LIBUSB_ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
|
static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data,
|
||||||
|
@ -4086,7 +4127,7 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans
|
||||||
r = LIBUSB_COMPLETED;
|
r = LIBUSB_COMPLETED;
|
||||||
} else {
|
} else {
|
||||||
usbi_warn(ctx, "cannot set configuration other than the default one");
|
usbi_warn(ctx, "cannot set configuration other than the default one");
|
||||||
r = LIBUSB_ERROR_INVALID_PARAM;
|
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LIBUSB_REQUEST_GET_INTERFACE:
|
case LIBUSB_REQUEST_GET_INTERFACE:
|
||||||
|
@ -4102,7 +4143,7 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usbi_warn(ctx, "unsupported HID control request");
|
usbi_warn(ctx, "unsupported HID control request");
|
||||||
r = LIBUSB_ERROR_INVALID_PARAM;
|
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -4113,7 +4154,7 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usbi_warn(ctx, "unsupported HID control request");
|
usbi_warn(ctx, "unsupported HID control request");
|
||||||
r = LIBUSB_ERROR_INVALID_PARAM;
|
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4387,24 +4428,31 @@ static void composite_close(int sub_api, struct libusb_device_handle *dev_handle
|
||||||
{
|
{
|
||||||
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
bool available[SUB_API_MAX];
|
// SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
|
||||||
|
bool available[SUB_API_MAX+1] = {0};
|
||||||
for (i = 0; i<SUB_API_MAX; i++) {
|
|
||||||
available[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<USB_MAXINTERFACES; i++) {
|
for (i=0; i<USB_MAXINTERFACES; i++) {
|
||||||
if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX)
|
switch (priv->usb_interface[i].apib->id) {
|
||||||
&& (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) {
|
case USB_API_WINUSBX:
|
||||||
available[priv->usb_interface[i].sub_api] = true;
|
if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
|
||||||
|
available[priv->usb_interface[i].sub_api] = true;
|
||||||
|
break;
|
||||||
|
case USB_API_HID:
|
||||||
|
available[SUB_API_MAX] = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<SUB_API_MAX; i++) {
|
for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
|
||||||
if (available[i]) {
|
if (available[i]) {
|
||||||
usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
|
usb_api_backend[USB_API_WINUSBX].close(i, dev_handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (available[SUB_API_MAX]) { // HID driver
|
||||||
|
hid_close(SUB_API_NOTSET, dev_handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
|
static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface)
|
||||||
|
@ -4433,19 +4481,57 @@ static int composite_submit_control_transfer(int sub_api, struct usbi_transfer *
|
||||||
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
||||||
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
|
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
|
||||||
struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
||||||
int i, pass;
|
struct libusb_config_descriptor *conf_desc;
|
||||||
|
WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer;
|
||||||
|
int iface, pass, r;
|
||||||
|
|
||||||
// Interface shouldn't matter for control, but it does in practice, with Windows'
|
// Interface shouldn't matter for control, but it does in practice, with Windows'
|
||||||
// restrictions with regards to accessing HID keyboards and mice. Try a 2 pass approach
|
// restrictions with regards to accessing HID keyboards and mice. Try to target
|
||||||
|
// a specific interface first, if possible.
|
||||||
|
switch (LIBUSB_REQ_RECIPIENT(setup->request_type)) {
|
||||||
|
case LIBUSB_RECIPIENT_INTERFACE:
|
||||||
|
iface = setup->index & 0xFF;
|
||||||
|
break;
|
||||||
|
case LIBUSB_RECIPIENT_ENDPOINT:
|
||||||
|
r = libusb_get_config_descriptor(transfer->dev_handle->dev, (uint8_t)(priv->active_config-1), &conf_desc);
|
||||||
|
if (r == LIBUSB_SUCCESS) {
|
||||||
|
iface = get_interface_by_endpoint(conf_desc, (setup->index & 0xFF));
|
||||||
|
libusb_free_config_descriptor(conf_desc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fall through if not able to determine interface
|
||||||
|
default:
|
||||||
|
iface = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try and target a specific interface if the control setup indicates such
|
||||||
|
if ((iface >= 0) && (iface < USB_MAXINTERFACES)) {
|
||||||
|
usbi_dbg("attempting control transfer targeted to interface %d", iface);
|
||||||
|
if (priv->usb_interface[iface].path != NULL) {
|
||||||
|
r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
|
||||||
|
if (r == LIBUSB_SUCCESS) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Either not targeted to a specific interface or no luck in doing so.
|
||||||
|
// Try a 2 pass approach with all interfaces.
|
||||||
for (pass = 0; pass < 2; pass++) {
|
for (pass = 0; pass < 2; pass++) {
|
||||||
for (i=0; i<USB_MAXINTERFACES; i++) {
|
for (iface = 0; iface < USB_MAXINTERFACES; iface++) {
|
||||||
if (priv->usb_interface[i].path != NULL) {
|
if (priv->usb_interface[iface].path != NULL) {
|
||||||
if ((pass == 0) && (priv->usb_interface[i].restricted_functionality)) {
|
if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) {
|
||||||
usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", i);
|
usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
usbi_dbg("using interface %d", i);
|
usbi_dbg("using interface %d", iface);
|
||||||
return priv->usb_interface[i].apib->submit_control_transfer(priv->usb_interface[i].sub_api, itransfer);
|
r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
|
||||||
|
// If not supported on this API, it may be supported on another, so don't give up yet!!
|
||||||
|
if (r == LIBUSB_ERROR_NOT_SUPPORTED) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,12 @@
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
// disable /W4 MSVC warnings that are benign
|
// disable /W4 MSVC warnings that are benign
|
||||||
#pragma warning(disable:4127) // conditional expression is constant
|
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
#pragma warning(disable:4127) // conditional expression is constant
|
||||||
#pragma warning(disable:4214) // bit field types other than int
|
#pragma warning(disable:4201) // nameless struct/union
|
||||||
#pragma warning(disable:4201) // nameless struct/union
|
#pragma warning(disable:4214) // bit field types other than int
|
||||||
|
#pragma warning(disable:4996) // deprecated API calls
|
||||||
|
#pragma warning(disable:28159) // more deprecated API calls
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Missing from MSVC6 setupapi.h
|
// Missing from MSVC6 setupapi.h
|
||||||
|
@ -47,9 +49,8 @@
|
||||||
|
|
||||||
#if defined(__CYGWIN__ )
|
#if defined(__CYGWIN__ )
|
||||||
#define _stricmp stricmp
|
#define _stricmp stricmp
|
||||||
// cygwin produces a warning unless these prototypes are defined
|
#define _snprintf snprintf
|
||||||
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
|
#define _strdup strdup
|
||||||
extern char *_strdup(const char *strSource);
|
|
||||||
// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
|
// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
|
||||||
#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f)
|
#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f)
|
||||||
#endif
|
#endif
|
||||||
|
@ -307,6 +308,15 @@ struct driver_lookup {
|
||||||
const char* designation; // internal designation (for debug output)
|
const char* designation; // internal designation (for debug output)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WM_TIMER_REQUEST (WM_USER + 1)
|
||||||
|
#define WM_TIMER_EXIT (WM_USER + 2)
|
||||||
|
|
||||||
|
// used for monotonic clock_gettime()
|
||||||
|
struct timer_request {
|
||||||
|
struct timespec *tp;
|
||||||
|
HANDLE event;
|
||||||
|
};
|
||||||
|
|
||||||
/* OLE32 dependency */
|
/* OLE32 dependency */
|
||||||
DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
|
DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
|
||||||
|
|
||||||
|
@ -328,6 +338,11 @@ DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINF
|
||||||
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
|
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
|
||||||
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
|
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
|
||||||
|
|
||||||
|
/* User32 dependencies */
|
||||||
|
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, GetMessageA, (LPMSG, HWND, UINT, UINT));
|
||||||
|
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, PeekMessageA, (LPMSG, HWND, UINT, UINT, UINT));
|
||||||
|
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, PostThreadMessageA, (DWORD, UINT, WPARAM, LPARAM));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Windows DDK API definitions. Most of it copied from MinGW's includes
|
* Windows DDK API definitions. Most of it copied from MinGW's includes
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,13 +16,16 @@
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#if defined(HAVE_STRINGS_H)
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libusb.h"
|
|
||||||
#include "libusbi.h"
|
#include "libusbi.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include <config.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define LIBUSB_MINOR 0
|
#define LIBUSB_MINOR 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef LIBUSB_MICRO
|
#ifndef LIBUSB_MICRO
|
||||||
#define LIBUSB_MICRO 19
|
#define LIBUSB_MICRO 20
|
||||||
#endif
|
#endif
|
||||||
#ifndef LIBUSB_NANO
|
#ifndef LIBUSB_NANO
|
||||||
#define LIBUSB_NANO 0
|
#define LIBUSB_NANO 0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define LIBUSB_NANO 10903
|
#define LIBUSB_NANO 11004
|
||||||
|
|
Loading…
Reference in New Issue