Internal change
PiperOrigin-RevId: 436035578
Change-Id: I688475bb66c5d961d17a4b9a414790602ad5b28b
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..219c387
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,551 @@
+libusb is covered by the LGPL:
+
+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 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., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+----
+
+Alternatively, the files usb.h.in and/or usb.h may be licensed under the
+BSD license:
+
+Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-----------------------------------------------------------------------------
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/libusb1/Makefile b/libusb1/Makefile
new file mode 100644
index 0000000..bd516be
--- /dev/null
+++ b/libusb1/Makefile
@@ -0,0 +1,1059 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# libusb/Makefile. Generated from Makefile.in by configure.
+
+# 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.
+
+
+
+
+
+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)/libusb
+pkgincludedir = $(includedir)/libusb
+pkglibdir = $(libdir)/libusb
+pkglibexecdir = $(libexecdir)/libusb
+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 = x86_64-pc-linux-gnu
+host_triplet = x86_64-pc-linux-gnu
+subdir = libusb
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(hdr_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+#libusb_1_0_la_DEPENDENCIES = libusb_haiku.la
+am__libusb_1_0_la_SOURCES_DIST = libusbi.h libusb.h version.h \
+ version_nano.h core.c descriptor.c hotplug.h hotplug.c io.c \
+ strerror.c sync.c os/poll_posix.h os/poll_posix.c \
+ os/poll_windows.h os/poll_windows.c os/threads_windows.h \
+ os/threads_windows.c os/threads_posix.h os/threads_posix.c \
+ os/darwin_usb.h os/darwin_usb.c os/linux_usbfs.h \
+ os/linux_usbfs.c os/linux_netlink.c os/linux_udev.c \
+ os/netbsd_usb.c os/openbsd_usb.c os/sunos_usb.c os/sunos_usb.h \
+ libusb-1.0.def libusb-1.0.rc os/windows_common.h \
+ os/windows_nt_common.h os/windows_nt_common.c \
+ os/windows_nt_shared_types.h os/windows_usbdk.h \
+ os/windows_usbdk.c os/windows_winusb.h os/windows_winusb.c
+am__dirstamp = $(am__leading_dot)dirstamp
+am__objects_1 = os/libusb_1_0_la-poll_posix.lo
+am__objects_2 = os/libusb_1_0_la-poll_windows.lo
+am__objects_3 = $(am__objects_1)
+#am__objects_3 = $(am__objects_2)
+am__objects_4 = os/libusb_1_0_la-threads_windows.lo
+am__objects_5 = os/libusb_1_0_la-threads_posix.lo
+#am__objects_6 = $(am__objects_4)
+am__objects_6 = $(am__objects_5)
+am__objects_7 = os/libusb_1_0_la-darwin_usb.lo
+am__objects_8 = os/libusb_1_0_la-linux_usbfs.lo
+am__objects_9 = os/libusb_1_0_la-netbsd_usb.lo
+am__objects_10 = os/libusb_1_0_la-openbsd_usb.lo
+am__objects_11 = os/libusb_1_0_la-sunos_usb.lo
+am__objects_12 = libusb-1.0.lo os/libusb_1_0_la-windows_nt_common.lo \
+ os/libusb_1_0_la-windows_usbdk.lo \
+ os/libusb_1_0_la-windows_winusb.lo
+##am__objects_13 = $(am__objects_12)
+##am__objects_13 = $(am__objects_11)
+##am__objects_13 = $(am__objects_10)
+##am__objects_13 = $(am__objects_9)
+#am__objects_13 = $(am__objects_8) \
+# os/libusb_1_0_la-linux_netlink.lo
+am__objects_13 = $(am__objects_8) \
+ os/libusb_1_0_la-linux_udev.lo
+#am__objects_13 = $(am__objects_7)
+am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
+ libusb_1_0_la-descriptor.lo libusb_1_0_la-hotplug.lo \
+ libusb_1_0_la-io.lo libusb_1_0_la-strerror.lo \
+ libusb_1_0_la-sync.lo $(am__objects_3) $(am__objects_6) \
+ $(am__objects_13)
+libusb_1_0_la_OBJECTS = $(am_libusb_1_0_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libusb_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libusb_1_0_la_CFLAGS) \
+ $(CFLAGS) $(libusb_1_0_la_LDFLAGS) $(LDFLAGS) -o $@
+libusb_haiku_la_LIBADD =
+am__libusb_haiku_la_SOURCES_DIST = os/haiku_usb.h \
+ os/haiku_usb_backend.cpp os/haiku_usb_raw.h \
+ os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
+am__objects_14 = os/haiku_usb_backend.lo os/haiku_usb_raw.lo \
+ os/haiku_pollfs.lo
+#am_libusb_haiku_la_OBJECTS = $(am__objects_14)
+libusb_haiku_la_OBJECTS = $(am_libusb_haiku_la_OBJECTS)
+#am_libusb_haiku_la_rpath =
+AM_V_P = $(am__v_P_$(V))
+am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I. -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+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_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+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_$(V))
+am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
+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_$(V))
+am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(libusb_1_0_la_SOURCES) $(libusb_haiku_la_SOURCES)
+DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST) \
+ $(am__libusb_haiku_la_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(hdr_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = ${SHELL} /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/missing aclocal-1.15
+AMTAR = $${TAR-tar}
+AM_CFLAGS = -std=gnu99 -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow -pthread -fvisibility=hidden
+AM_DEFAULT_VERBOSITY = 0
+AR = ar
+AUTOCONF = ${SHELL} /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/missing autoconf
+AUTOHEADER = ${SHELL} /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/missing autoheader
+AUTOMAKE = ${SHELL} /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/missing automake-1.15
+AWK = gawk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -g -O2
+CPP = gcc -E
+CPPFLAGS =
+CXX = g++
+CXXCPP = g++ -E
+CXXDEPMODE = depmode=gcc3
+CXXFLAGS = -g -O2
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+DLLTOOL = false
+DSYMUTIL =
+DUMPBIN =
+ECHO_C =
+ECHO_N = -n
+ECHO_T =
+EGREP = /usr/bin/grep -E
+EXEEXT =
+FGREP = /usr/bin/grep -F
+GREP = /usr/bin/grep
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LD = /usr/bin/ld -m elf_x86_64
+LDFLAGS =
+LIBOBJS =
+LIBS = -ludev -pthread
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIPO =
+LN_S = ln -s
+LTLDFLAGS = -version-info 2:0:2 -no-undefined
+LTLIBOBJS =
+LT_SYS_LIBRARY_PATH =
+MAKEINFO = ${SHELL} /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/missing makeinfo
+MANIFEST_TOOL = :
+MKDIR_P = /usr/bin/mkdir -p
+NM = /usr/bin/nm -B
+NMEDIT =
+OBJDUMP = objdump
+OBJEXT = o
+OS_DARWIN =
+OS_HAIKU =
+OS_LINUX =
+OS_NETBSD =
+OS_OPENBSD =
+OS_SUNOS =
+OS_WINDOWS =
+OTOOL =
+OTOOL64 =
+PACKAGE = libusb
+PACKAGE_BUGREPORT = libusb-devel@lists.sourceforge.net
+PACKAGE_NAME = libusb
+PACKAGE_STRING = libusb 1.0.23-rc2
+PACKAGE_TARNAME = libusb
+PACKAGE_URL = http://libusb.info
+PACKAGE_VERSION = 1.0.23-rc2
+PATH_SEPARATOR = :
+RANLIB = ranlib
+RC =
+SED = /usr/bin/sed
+SET_MAKE =
+SHELL = /bin/sh
+STRIP = strip
+USE_UDEV =
+VERSION = 1.0.23-rc2
+abs_builddir = /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/libusb
+abs_srcdir = /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/libusb
+abs_top_builddir = /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2
+abs_top_srcdir = /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2
+ac_ct_AR = ar
+ac_ct_CC = gcc
+ac_ct_CXX = g++
+ac_ct_DUMPBIN =
+am__include = include
+am__leading_dot = .
+am__quote =
+am__tar = $${TAR-tar} chof - "$$tardir"
+am__untar = $${TAR-tar} xf -
+bindir = ${exec_prefix}/bin
+build = x86_64-pc-linux-gnu
+build_alias =
+build_cpu = x86_64
+build_os = linux-gnu
+build_vendor = pc
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = x86_64-pc-linux-gnu
+host_alias =
+host_cpu = x86_64
+host_os = linux-gnu
+host_vendor = pc
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = ${SHELL} /usr/local/google/home/saintmac/Downloads/libusb-1.0.23-rc2/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+mandir = ${datarootdir}/man
+mkdir_p = $(MKDIR_P)
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+runstatedir = ${localstatedir}/run
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target_alias =
+top_build_prefix = ../
+top_builddir = ..
+top_srcdir = ..
+AUTOMAKE_OPTIONS = subdir-objects
+lib_LTLIBRARIES = libusb-1.0.la
+POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
+POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
+WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
+WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
+LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
+DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
+OPENBSD_USB_SRC = os/openbsd_usb.c
+NETBSD_USB_SRC = os/netbsd_usb.c
+SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
+WINDOWS_USB_SRC = libusb-1.0.def libusb-1.0.rc \
+ os/windows_common.h \
+ os/windows_nt_common.h os/windows_nt_common.c \
+ os/windows_nt_shared_types.h \
+ os/windows_usbdk.h os/windows_usbdk.c \
+ os/windows_winusb.h os/windows_winusb.c
+
+WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
+HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
+ os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
+
+EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
+ $(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
+ $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
+ $(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
+ $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
+ $(HAIKU_USB_SRC) \
+ os/linux_udev.c os/linux_netlink.c
+
+#OS_SRC = $(DARWIN_USB_SRC)
+#OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
+OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
+#OS_SRC = $(NETBSD_USB_SRC)
+#OS_SRC = $(OPENBSD_USB_SRC)
+#OS_SRC = $(SUNOS_USB_SRC)
+#OS_SRC = $(WINDOWS_USB_SRC)
+#AM_CFLAGS_EXT = -no-cpp-precomp
+#noinst_LTLIBRARIES = libusb_haiku.la
+#libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
+#libusb_1_0_la_LIBADD = libusb_haiku.la
+POLL_SRC = $(POSIX_POLL_SRC)
+#POLL_SRC = $(WINDOWS_POLL_SRC)
+#THREADS_SRC = $(WINDOWS_THREADS_SRC)
+THREADS_SRC = $(POSIX_THREADS_SRC)
+libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
+libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
+libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
+ core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
+ $(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
+
+hdrdir = $(includedir)/libusb-1.0
+hdr_HEADERS = libusb.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .o .obj .rc
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu libusb/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+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}; \
+ }
+os/$(am__dirstamp):
+ @$(MKDIR_P) os
+ @: > os/$(am__dirstamp)
+os/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) os/$(DEPDIR)
+ @: > os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-poll_posix.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-poll_windows.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-threads_windows.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-threads_posix.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-darwin_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-linux_usbfs.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-linux_netlink.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-linux_udev.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-netbsd_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-openbsd_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-sunos_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-windows_nt_common.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-windows_usbdk.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-windows_winusb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+
+libusb-1.0.la: $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_DEPENDENCIES) $(EXTRA_libusb_1_0_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libusb_1_0_la_LINK) -rpath $(libdir) $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_LIBADD) $(LIBS)
+os/haiku_usb_backend.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/haiku_usb_raw.lo: os/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
+os/haiku_pollfs.lo: os/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
+
+libusb_haiku.la: $(libusb_haiku_la_OBJECTS) $(libusb_haiku_la_DEPENDENCIES) $(EXTRA_libusb_haiku_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(am_libusb_haiku_la_rpath) $(libusb_haiku_la_OBJECTS) $(libusb_haiku_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f os/*.$(OBJEXT)
+ -rm -f os/*.lo
+
+distclean-compile:
+ -rm -f *.tab.c
+
+include ./$(DEPDIR)/libusb_1_0_la-core.Plo
+include ./$(DEPDIR)/libusb_1_0_la-descriptor.Plo
+include ./$(DEPDIR)/libusb_1_0_la-hotplug.Plo
+include ./$(DEPDIR)/libusb_1_0_la-io.Plo
+include ./$(DEPDIR)/libusb_1_0_la-strerror.Plo
+include ./$(DEPDIR)/libusb_1_0_la-sync.Plo
+include os/$(DEPDIR)/haiku_pollfs.Plo
+include os/$(DEPDIR)/haiku_usb_backend.Plo
+include os/$(DEPDIR)/haiku_usb_raw.Plo
+include os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo
+include os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo
+include os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo
+include os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo
+include os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Plo
+include os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo
+include os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo
+include os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo
+include os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Plo
+include os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo
+include os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo
+include os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Plo
+include os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Plo
+include os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Plo
+
+.c.o:
+ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ $(am__mv) $$depbase.Tpo $$depbase.Po
+# $(AM_V_CC)source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ $(am__mv) $$depbase.Tpo $$depbase.Po
+# $(AM_V_CC)source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ $(am__mv) $$depbase.Tpo $$depbase.Plo
+# $(AM_V_CC)source='$<' object='$@' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LTCOMPILE) -c -o $@ $<
+
+libusb_1_0_la-core.lo: core.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-core.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-core.Tpo -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-core.Tpo $(DEPDIR)/libusb_1_0_la-core.Plo
+# $(AM_V_CC)source='core.c' object='libusb_1_0_la-core.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
+
+libusb_1_0_la-descriptor.lo: descriptor.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-descriptor.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-descriptor.Tpo -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-descriptor.Tpo $(DEPDIR)/libusb_1_0_la-descriptor.Plo
+# $(AM_V_CC)source='descriptor.c' object='libusb_1_0_la-descriptor.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
+
+libusb_1_0_la-hotplug.lo: hotplug.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-hotplug.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-hotplug.Tpo -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-hotplug.Tpo $(DEPDIR)/libusb_1_0_la-hotplug.Plo
+# $(AM_V_CC)source='hotplug.c' object='libusb_1_0_la-hotplug.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
+
+libusb_1_0_la-io.lo: io.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-io.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-io.Tpo -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-io.Tpo $(DEPDIR)/libusb_1_0_la-io.Plo
+# $(AM_V_CC)source='io.c' object='libusb_1_0_la-io.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
+
+libusb_1_0_la-strerror.lo: strerror.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-strerror.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-strerror.Tpo -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-strerror.Tpo $(DEPDIR)/libusb_1_0_la-strerror.Plo
+# $(AM_V_CC)source='strerror.c' object='libusb_1_0_la-strerror.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
+
+libusb_1_0_la-sync.lo: sync.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-sync.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-sync.Tpo -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
+ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-sync.Tpo $(DEPDIR)/libusb_1_0_la-sync.Plo
+# $(AM_V_CC)source='sync.c' object='libusb_1_0_la-sync.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
+
+os/libusb_1_0_la-poll_posix.lo: os/poll_posix.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo
+# $(AM_V_CC)source='os/poll_posix.c' object='os/libusb_1_0_la-poll_posix.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
+
+os/libusb_1_0_la-poll_windows.lo: os/poll_windows.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo
+# $(AM_V_CC)source='os/poll_windows.c' object='os/libusb_1_0_la-poll_windows.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
+
+os/libusb_1_0_la-threads_windows.lo: os/threads_windows.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo
+# $(AM_V_CC)source='os/threads_windows.c' object='os/libusb_1_0_la-threads_windows.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
+
+os/libusb_1_0_la-threads_posix.lo: os/threads_posix.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_posix.Tpo -c -o os/libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-threads_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo
+# $(AM_V_CC)source='os/threads_posix.c' object='os/libusb_1_0_la-threads_posix.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
+
+os/libusb_1_0_la-darwin_usb.lo: os/darwin_usb.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-darwin_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo
+# $(AM_V_CC)source='os/darwin_usb.c' object='os/libusb_1_0_la-darwin_usb.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
+
+os/libusb_1_0_la-linux_usbfs.lo: os/linux_usbfs.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_usbfs.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo
+# $(AM_V_CC)source='os/linux_usbfs.c' object='os/libusb_1_0_la-linux_usbfs.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
+
+os/libusb_1_0_la-linux_netlink.lo: os/linux_netlink.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_netlink.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo -c -o os/libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo
+# $(AM_V_CC)source='os/linux_netlink.c' object='os/libusb_1_0_la-linux_netlink.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
+
+os/libusb_1_0_la-linux_udev.lo: os/linux_udev.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_udev.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_udev.Tpo -c -o os/libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_udev.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo
+# $(AM_V_CC)source='os/linux_udev.c' object='os/libusb_1_0_la-linux_udev.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
+
+os/libusb_1_0_la-netbsd_usb.lo: os/netbsd_usb.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-netbsd_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Tpo -c -o os/libusb_1_0_la-netbsd_usb.lo `test -f 'os/netbsd_usb.c' || echo '$(srcdir)/'`os/netbsd_usb.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Plo
+# $(AM_V_CC)source='os/netbsd_usb.c' object='os/libusb_1_0_la-netbsd_usb.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-netbsd_usb.lo `test -f 'os/netbsd_usb.c' || echo '$(srcdir)/'`os/netbsd_usb.c
+
+os/libusb_1_0_la-openbsd_usb.lo: os/openbsd_usb.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-openbsd_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo
+# $(AM_V_CC)source='os/openbsd_usb.c' object='os/libusb_1_0_la-openbsd_usb.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
+
+os/libusb_1_0_la-sunos_usb.lo: os/sunos_usb.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-sunos_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Tpo -c -o os/libusb_1_0_la-sunos_usb.lo `test -f 'os/sunos_usb.c' || echo '$(srcdir)/'`os/sunos_usb.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Plo
+# $(AM_V_CC)source='os/sunos_usb.c' object='os/libusb_1_0_la-sunos_usb.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-sunos_usb.lo `test -f 'os/sunos_usb.c' || echo '$(srcdir)/'`os/sunos_usb.c
+
+os/libusb_1_0_la-windows_nt_common.lo: os/windows_nt_common.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_nt_common.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Tpo -c -o os/libusb_1_0_la-windows_nt_common.lo `test -f 'os/windows_nt_common.c' || echo '$(srcdir)/'`os/windows_nt_common.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Plo
+# $(AM_V_CC)source='os/windows_nt_common.c' object='os/libusb_1_0_la-windows_nt_common.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_nt_common.lo `test -f 'os/windows_nt_common.c' || echo '$(srcdir)/'`os/windows_nt_common.c
+
+os/libusb_1_0_la-windows_usbdk.lo: os/windows_usbdk.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_usbdk.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Tpo -c -o os/libusb_1_0_la-windows_usbdk.lo `test -f 'os/windows_usbdk.c' || echo '$(srcdir)/'`os/windows_usbdk.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Plo
+# $(AM_V_CC)source='os/windows_usbdk.c' object='os/libusb_1_0_la-windows_usbdk.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_usbdk.lo `test -f 'os/windows_usbdk.c' || echo '$(srcdir)/'`os/windows_usbdk.c
+
+os/libusb_1_0_la-windows_winusb.lo: os/windows_winusb.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_winusb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Tpo -c -o os/libusb_1_0_la-windows_winusb.lo `test -f 'os/windows_winusb.c' || echo '$(srcdir)/'`os/windows_winusb.c
+ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Plo
+# $(AM_V_CC)source='os/windows_winusb.c' object='os/libusb_1_0_la-windows_winusb.lo' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
+# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_winusb.lo `test -f 'os/windows_winusb.c' || echo '$(srcdir)/'`os/windows_winusb.c
+
+.cpp.o:
+ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ $(am__mv) $$depbase.Tpo $$depbase.Po
+# $(AM_V_CXX)source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ $(am__mv) $$depbase.Tpo $$depbase.Po
+# $(AM_V_CXX)source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ $(am__mv) $$depbase.Tpo $$depbase.Plo
+# $(AM_V_CXX)source='$<' object='$@' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(AM_V_CXX_no)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf os/.libs os/_libs
+install-hdrHEADERS: $(hdr_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(hdrdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(hdrdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(hdrdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(hdrdir)" || exit $$?; \
+ done
+
+uninstall-hdrHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f os/$(DEPDIR)/$(am__dirstamp)
+ -rm -f os/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR) os/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-hdrHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR) os/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-hdrHEADERS install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
+ uninstall-libLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+all: libusb-1.0.la libusb-1.0.dll
+
+#.rc.lo:
+# $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
+
+#libusb-1.0.rc: version.h version_nano.h
+
+libusb-1.0.dll: libusb-1.0.def libusb-1.0.la
+# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
+# $(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
+
+# 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:
diff --git a/libusb1/Makefile.am b/libusb1/Makefile.am
new file mode 100644
index 0000000..e4da62e
--- /dev/null
+++ b/libusb1/Makefile.am
@@ -0,0 +1,101 @@
+all: libusb-1.0.la libusb-1.0.dll
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+lib_LTLIBRARIES = libusb-1.0.la
+
+POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
+POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
+WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
+WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
+LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
+DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
+OPENBSD_USB_SRC = os/openbsd_usb.c
+NETBSD_USB_SRC = os/netbsd_usb.c
+SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
+WINDOWS_USB_SRC = libusb-1.0.def libusb-1.0.rc \
+ os/windows_common.h \
+ os/windows_nt_common.h os/windows_nt_common.c \
+ os/windows_nt_shared_types.h \
+ os/windows_usbdk.h os/windows_usbdk.c \
+ os/windows_winusb.h os/windows_winusb.c
+WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
+HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
+ os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
+
+EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
+ $(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
+ $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
+ $(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
+ $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
+ $(HAIKU_USB_SRC) \
+ os/linux_udev.c os/linux_netlink.c
+
+if OS_LINUX
+
+if USE_UDEV
+OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
+else
+OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
+endif
+
+endif
+
+if OS_DARWIN
+OS_SRC = $(DARWIN_USB_SRC)
+AM_CFLAGS_EXT = -no-cpp-precomp
+endif
+
+if OS_OPENBSD
+OS_SRC = $(OPENBSD_USB_SRC)
+endif
+
+if OS_NETBSD
+OS_SRC = $(NETBSD_USB_SRC)
+endif
+
+if OS_SUNOS
+OS_SRC = $(SUNOS_USB_SRC)
+endif
+
+if OS_HAIKU
+noinst_LTLIBRARIES = libusb_haiku.la
+libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
+libusb_1_0_la_LIBADD = libusb_haiku.la
+endif
+
+if OS_WINDOWS
+OS_SRC = $(WINDOWS_USB_SRC)
+
+.rc.lo:
+ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
+
+libusb-1.0.rc: version.h version_nano.h
+endif
+
+libusb-1.0.dll: libusb-1.0.def libusb-1.0.la
+if CREATE_IMPORT_LIB
+# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
+ $(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
+endif
+
+if OS_WINDOWS
+POLL_SRC = $(WINDOWS_POLL_SRC)
+else
+POLL_SRC = $(POSIX_POLL_SRC)
+endif
+
+if THREADS_POSIX
+THREADS_SRC = $(POSIX_THREADS_SRC)
+else
+THREADS_SRC = $(WINDOWS_THREADS_SRC)
+endif
+
+libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
+libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
+libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
+ core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
+ $(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
+
+hdrdir = $(includedir)/libusb-1.0
+hdr_HEADERS = libusb.h
diff --git a/libusb1/Makefile.in b/libusb1/Makefile.in
new file mode 100644
index 0000000..b626124
--- /dev/null
+++ b/libusb1/Makefile.in
@@ -0,0 +1,1059 @@
+# 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 = libusb
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(hdr_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+@OS_HAIKU_TRUE@libusb_1_0_la_DEPENDENCIES = libusb_haiku.la
+am__libusb_1_0_la_SOURCES_DIST = libusbi.h libusb.h version.h \
+ version_nano.h core.c descriptor.c hotplug.h hotplug.c io.c \
+ strerror.c sync.c os/poll_posix.h os/poll_posix.c \
+ os/poll_windows.h os/poll_windows.c os/threads_windows.h \
+ os/threads_windows.c os/threads_posix.h os/threads_posix.c \
+ os/darwin_usb.h os/darwin_usb.c os/linux_usbfs.h \
+ os/linux_usbfs.c os/linux_netlink.c os/linux_udev.c \
+ os/netbsd_usb.c os/openbsd_usb.c os/sunos_usb.c os/sunos_usb.h \
+ libusb-1.0.def libusb-1.0.rc os/windows_common.h \
+ os/windows_nt_common.h os/windows_nt_common.c \
+ os/windows_nt_shared_types.h os/windows_usbdk.h \
+ os/windows_usbdk.c os/windows_winusb.h os/windows_winusb.c
+am__dirstamp = $(am__leading_dot)dirstamp
+am__objects_1 = os/libusb_1_0_la-poll_posix.lo
+am__objects_2 = os/libusb_1_0_la-poll_windows.lo
+@OS_WINDOWS_FALSE@am__objects_3 = $(am__objects_1)
+@OS_WINDOWS_TRUE@am__objects_3 = $(am__objects_2)
+am__objects_4 = os/libusb_1_0_la-threads_windows.lo
+am__objects_5 = os/libusb_1_0_la-threads_posix.lo
+@THREADS_POSIX_FALSE@am__objects_6 = $(am__objects_4)
+@THREADS_POSIX_TRUE@am__objects_6 = $(am__objects_5)
+am__objects_7 = os/libusb_1_0_la-darwin_usb.lo
+am__objects_8 = os/libusb_1_0_la-linux_usbfs.lo
+am__objects_9 = os/libusb_1_0_la-netbsd_usb.lo
+am__objects_10 = os/libusb_1_0_la-openbsd_usb.lo
+am__objects_11 = os/libusb_1_0_la-sunos_usb.lo
+am__objects_12 = libusb-1.0.lo os/libusb_1_0_la-windows_nt_common.lo \
+ os/libusb_1_0_la-windows_usbdk.lo \
+ os/libusb_1_0_la-windows_winusb.lo
+@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_FALSE@@OS_WINDOWS_TRUE@am__objects_13 = $(am__objects_12)
+@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_SUNOS_TRUE@am__objects_13 = $(am__objects_11)
+@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@am__objects_13 = $(am__objects_10)
+@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@am__objects_13 = $(am__objects_9)
+@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_13 = $(am__objects_8) \
+@OS_DARWIN_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_13 = $(am__objects_8) \
+@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/libusb_1_0_la-linux_udev.lo
+@OS_DARWIN_TRUE@am__objects_13 = $(am__objects_7)
+am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
+ libusb_1_0_la-descriptor.lo libusb_1_0_la-hotplug.lo \
+ libusb_1_0_la-io.lo libusb_1_0_la-strerror.lo \
+ libusb_1_0_la-sync.lo $(am__objects_3) $(am__objects_6) \
+ $(am__objects_13)
+libusb_1_0_la_OBJECTS = $(am_libusb_1_0_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libusb_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libusb_1_0_la_CFLAGS) \
+ $(CFLAGS) $(libusb_1_0_la_LDFLAGS) $(LDFLAGS) -o $@
+libusb_haiku_la_LIBADD =
+am__libusb_haiku_la_SOURCES_DIST = os/haiku_usb.h \
+ os/haiku_usb_backend.cpp os/haiku_usb_raw.h \
+ os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
+am__objects_14 = os/haiku_usb_backend.lo os/haiku_usb_raw.lo \
+ os/haiku_pollfs.lo
+@OS_HAIKU_TRUE@am_libusb_haiku_la_OBJECTS = $(am__objects_14)
+libusb_haiku_la_OBJECTS = $(am_libusb_haiku_la_OBJECTS)
+@OS_HAIKU_TRUE@am_libusb_haiku_la_rpath =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+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 =
+SOURCES = $(libusb_1_0_la_SOURCES) $(libusb_haiku_la_SOURCES)
+DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST) \
+ $(am__libusb_haiku_la_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(hdr_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+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@
+LTLDFLAGS = @LTLDFLAGS@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OS_DARWIN = @OS_DARWIN@
+OS_HAIKU = @OS_HAIKU@
+OS_LINUX = @OS_LINUX@
+OS_NETBSD = @OS_NETBSD@
+OS_OPENBSD = @OS_OPENBSD@
+OS_SUNOS = @OS_SUNOS@
+OS_WINDOWS = @OS_WINDOWS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_UDEV = @USE_UDEV@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_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@
+runstatedir = @runstatedir@
+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@
+AUTOMAKE_OPTIONS = subdir-objects
+lib_LTLIBRARIES = libusb-1.0.la
+POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
+POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
+WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
+WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
+LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
+DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
+OPENBSD_USB_SRC = os/openbsd_usb.c
+NETBSD_USB_SRC = os/netbsd_usb.c
+SUNOS_USB_SRC = os/sunos_usb.c os/sunos_usb.h
+WINDOWS_USB_SRC = libusb-1.0.def libusb-1.0.rc \
+ os/windows_common.h \
+ os/windows_nt_common.h os/windows_nt_common.c \
+ os/windows_nt_shared_types.h \
+ os/windows_usbdk.h os/windows_usbdk.c \
+ os/windows_winusb.h os/windows_winusb.c
+
+WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
+HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
+ os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
+
+EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
+ $(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
+ $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
+ $(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
+ $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
+ $(HAIKU_USB_SRC) \
+ os/linux_udev.c os/linux_netlink.c
+
+@OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC)
+@OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
+@OS_LINUX_TRUE@@USE_UDEV_TRUE@OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
+@OS_NETBSD_TRUE@OS_SRC = $(NETBSD_USB_SRC)
+@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC)
+@OS_SUNOS_TRUE@OS_SRC = $(SUNOS_USB_SRC)
+@OS_WINDOWS_TRUE@OS_SRC = $(WINDOWS_USB_SRC)
+@OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp
+@OS_HAIKU_TRUE@noinst_LTLIBRARIES = libusb_haiku.la
+@OS_HAIKU_TRUE@libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
+@OS_HAIKU_TRUE@libusb_1_0_la_LIBADD = libusb_haiku.la
+@OS_WINDOWS_FALSE@POLL_SRC = $(POSIX_POLL_SRC)
+@OS_WINDOWS_TRUE@POLL_SRC = $(WINDOWS_POLL_SRC)
+@THREADS_POSIX_FALSE@THREADS_SRC = $(WINDOWS_THREADS_SRC)
+@THREADS_POSIX_TRUE@THREADS_SRC = $(POSIX_THREADS_SRC)
+libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
+libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
+libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
+ core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
+ $(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
+
+hdrdir = $(includedir)/libusb-1.0
+hdr_HEADERS = libusb.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .o .obj .rc
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu libusb/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+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}; \
+ }
+os/$(am__dirstamp):
+ @$(MKDIR_P) os
+ @: > os/$(am__dirstamp)
+os/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) os/$(DEPDIR)
+ @: > os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-poll_posix.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-poll_windows.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-threads_windows.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-threads_posix.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-darwin_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-linux_usbfs.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-linux_netlink.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-linux_udev.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-netbsd_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-openbsd_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-sunos_usb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-windows_nt_common.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-windows_usbdk.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/libusb_1_0_la-windows_winusb.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+
+libusb-1.0.la: $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_DEPENDENCIES) $(EXTRA_libusb_1_0_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libusb_1_0_la_LINK) -rpath $(libdir) $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_LIBADD) $(LIBS)
+os/haiku_usb_backend.lo: os/$(am__dirstamp) \
+ os/$(DEPDIR)/$(am__dirstamp)
+os/haiku_usb_raw.lo: os/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
+os/haiku_pollfs.lo: os/$(am__dirstamp) os/$(DEPDIR)/$(am__dirstamp)
+
+libusb_haiku.la: $(libusb_haiku_la_OBJECTS) $(libusb_haiku_la_DEPENDENCIES) $(EXTRA_libusb_haiku_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(am_libusb_haiku_la_rpath) $(libusb_haiku_la_OBJECTS) $(libusb_haiku_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f os/*.$(OBJEXT)
+ -rm -f os/*.lo
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-descriptor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-hotplug.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-io.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-strerror.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-sync.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/haiku_pollfs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/haiku_usb_backend.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/haiku_usb_raw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libusb_1_0_la-core.lo: core.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-core.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-core.Tpo -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-core.Tpo $(DEPDIR)/libusb_1_0_la-core.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='core.c' object='libusb_1_0_la-core.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
+
+libusb_1_0_la-descriptor.lo: descriptor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-descriptor.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-descriptor.Tpo -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-descriptor.Tpo $(DEPDIR)/libusb_1_0_la-descriptor.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='descriptor.c' object='libusb_1_0_la-descriptor.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
+
+libusb_1_0_la-hotplug.lo: hotplug.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-hotplug.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-hotplug.Tpo -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-hotplug.Tpo $(DEPDIR)/libusb_1_0_la-hotplug.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hotplug.c' object='libusb_1_0_la-hotplug.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
+
+libusb_1_0_la-io.lo: io.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-io.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-io.Tpo -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-io.Tpo $(DEPDIR)/libusb_1_0_la-io.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='libusb_1_0_la-io.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
+
+libusb_1_0_la-strerror.lo: strerror.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-strerror.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-strerror.Tpo -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-strerror.Tpo $(DEPDIR)/libusb_1_0_la-strerror.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libusb_1_0_la-strerror.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
+
+libusb_1_0_la-sync.lo: sync.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-sync.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-sync.Tpo -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-sync.Tpo $(DEPDIR)/libusb_1_0_la-sync.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='libusb_1_0_la-sync.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
+
+os/libusb_1_0_la-poll_posix.lo: os/poll_posix.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_posix.c' object='os/libusb_1_0_la-poll_posix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
+
+os/libusb_1_0_la-poll_windows.lo: os/poll_windows.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_windows.c' object='os/libusb_1_0_la-poll_windows.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
+
+os/libusb_1_0_la-threads_windows.lo: os/threads_windows.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/threads_windows.c' object='os/libusb_1_0_la-threads_windows.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
+
+os/libusb_1_0_la-threads_posix.lo: os/threads_posix.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_posix.Tpo -c -o os/libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-threads_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/threads_posix.c' object='os/libusb_1_0_la-threads_posix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
+
+os/libusb_1_0_la-darwin_usb.lo: os/darwin_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-darwin_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/darwin_usb.c' object='os/libusb_1_0_la-darwin_usb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
+
+os/libusb_1_0_la-linux_usbfs.lo: os/linux_usbfs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_usbfs.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_usbfs.c' object='os/libusb_1_0_la-linux_usbfs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
+
+os/libusb_1_0_la-linux_netlink.lo: os/linux_netlink.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_netlink.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo -c -o os/libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_netlink.c' object='os/libusb_1_0_la-linux_netlink.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
+
+os/libusb_1_0_la-linux_udev.lo: os/linux_udev.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_udev.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_udev.Tpo -c -o os/libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_udev.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_udev.c' object='os/libusb_1_0_la-linux_udev.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
+
+os/libusb_1_0_la-netbsd_usb.lo: os/netbsd_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-netbsd_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Tpo -c -o os/libusb_1_0_la-netbsd_usb.lo `test -f 'os/netbsd_usb.c' || echo '$(srcdir)/'`os/netbsd_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/netbsd_usb.c' object='os/libusb_1_0_la-netbsd_usb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-netbsd_usb.lo `test -f 'os/netbsd_usb.c' || echo '$(srcdir)/'`os/netbsd_usb.c
+
+os/libusb_1_0_la-openbsd_usb.lo: os/openbsd_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-openbsd_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/openbsd_usb.c' object='os/libusb_1_0_la-openbsd_usb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
+
+os/libusb_1_0_la-sunos_usb.lo: os/sunos_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-sunos_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Tpo -c -o os/libusb_1_0_la-sunos_usb.lo `test -f 'os/sunos_usb.c' || echo '$(srcdir)/'`os/sunos_usb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-sunos_usb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/sunos_usb.c' object='os/libusb_1_0_la-sunos_usb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-sunos_usb.lo `test -f 'os/sunos_usb.c' || echo '$(srcdir)/'`os/sunos_usb.c
+
+os/libusb_1_0_la-windows_nt_common.lo: os/windows_nt_common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_nt_common.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Tpo -c -o os/libusb_1_0_la-windows_nt_common.lo `test -f 'os/windows_nt_common.c' || echo '$(srcdir)/'`os/windows_nt_common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_nt_common.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_nt_common.c' object='os/libusb_1_0_la-windows_nt_common.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_nt_common.lo `test -f 'os/windows_nt_common.c' || echo '$(srcdir)/'`os/windows_nt_common.c
+
+os/libusb_1_0_la-windows_usbdk.lo: os/windows_usbdk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_usbdk.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Tpo -c -o os/libusb_1_0_la-windows_usbdk.lo `test -f 'os/windows_usbdk.c' || echo '$(srcdir)/'`os/windows_usbdk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_usbdk.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_usbdk.c' object='os/libusb_1_0_la-windows_usbdk.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_usbdk.lo `test -f 'os/windows_usbdk.c' || echo '$(srcdir)/'`os/windows_usbdk.c
+
+os/libusb_1_0_la-windows_winusb.lo: os/windows_winusb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_winusb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Tpo -c -o os/libusb_1_0_la-windows_winusb.lo `test -f 'os/windows_winusb.c' || echo '$(srcdir)/'`os/windows_winusb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_winusb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_winusb.c' object='os/libusb_1_0_la-windows_winusb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_winusb.lo `test -f 'os/windows_winusb.c' || echo '$(srcdir)/'`os/windows_winusb.c
+
+.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 $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf os/.libs os/_libs
+install-hdrHEADERS: $(hdr_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(hdrdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(hdrdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(hdrdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(hdrdir)" || exit $$?; \
+ done
+
+uninstall-hdrHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f os/$(DEPDIR)/$(am__dirstamp)
+ -rm -f os/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR) os/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-hdrHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR) os/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-hdrHEADERS install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
+ uninstall-libLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+all: libusb-1.0.la libusb-1.0.dll
+
+@OS_WINDOWS_TRUE@.rc.lo:
+@OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
+
+@OS_WINDOWS_TRUE@libusb-1.0.rc: version.h version_nano.h
+
+libusb-1.0.dll: libusb-1.0.def libusb-1.0.la
+# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
+@CREATE_IMPORT_LIB_TRUE@ $(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libusb1/android/config.h b/libusb1/android/config.h
new file mode 100644
index 0000000..0dd35e2
--- /dev/null
+++ b/libusb1/android/config.h
@@ -0,0 +1,75 @@
+/*
+ * Android build config for libusb
+ * Copyright © 2012-2013 RealVNC Ltd. <toby.gray@realvnc.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Start with debug message logging enabled */
+/* #undef ENABLE_DEBUG_LOGGING */
+
+/* Message logging */
+#define ENABLE_LOGGING
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Linux backend */
+#define OS_LINUX 1
+
+/* Enable output to system log */
+#define USE_SYSTEM_LOGGING_FACILITY 1
+
+/* type of second poll() argument */
+#define POLL_NFDS_TYPE nfds_t
+
+/* Use POSIX Threads */
+#define THREADS_POSIX 1
+
+/* Default visibility */
+#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <linux/filter.h> header file. */
+#define HAVE_LINUX_FILTER_H 1
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#define HAVE_LINUX_NETLINK_H 1
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+#define HAVE_ASM_TYPES_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
diff --git a/libusb1/config.h b/libusb1/config.h
new file mode 100644
index 0000000..55f82b8
--- /dev/null
+++ b/libusb1/config.h
@@ -0,0 +1,14 @@
+#ifndef THIRD_PARTY_LIBUSB_LIBUSB1_CONFIG_H_
+#define THIRD_PARTY_LIBUSB_LIBUSB1_CONFIG_H_
+
+#if defined(__ANDROID__)
+#include "third_party/libusb/libusb1/android/config.h"
+#elif defined(__APPLE__)
+#include "third_party/libusb/libusb1/darwin/config.h"
+#elif defined(_MSC_VER)
+#include "third_party/libusb/libusb1/msvc/config.h"
+#else
+#include "third_party/libusb/libusb1/linux/config.h"
+#endif
+
+#endif // THIRD_PARTY_LIBUSB_LIBUSB1_CONFIG_H_
diff --git a/libusb1/core.c b/libusb1/core.c
new file mode 100644
index 0000000..741bf99
--- /dev/null
+++ b/libusb1/core.c
@@ -0,0 +1,2740 @@
+/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
+/*
+ * Core functions for libusb
+ * Copyright © 2012-2013 Nathan Hjelm <hjelmn@cs.unm.edu>
+ * Copyright © 2007-2008 Daniel Drake <dsd@gentoo.org>
+ * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#ifdef __ANDROID__
+#include <android/log.h>
+#endif
+
+#include "libusbi.h"
+#include "hotplug.h"
+
+struct libusb_context *usbi_default_context = NULL;
+static const struct libusb_version libusb_version_internal =
+ { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO,
+ LIBUSB_RC, "http://libusb.info" };
+static int default_context_refcnt = 0;
+static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
+static struct timespec timestamp_origin = { 0, 0 };
+#ifndef USE_SYSTEM_LOGGING_FACILITY
+static libusb_log_cb log_handler = NULL;
+#endif
+
+usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER;
+struct list_head active_contexts_list;
+
+/**
+ * \mainpage libusb-1.0 API Reference
+ *
+ * \section intro Introduction
+ *
+ * libusb is an open source library that allows you to communicate with USB
+ * devices from userspace. For more info, see the
+ * <a href="http://libusb.info">libusb homepage</a>.
+ *
+ * This documentation is aimed at application developers wishing to
+ * communicate with USB peripherals from their own software. After reviewing
+ * this documentation, feedback and questions can be sent to the
+ * <a href="http://mailing-list.libusb.info">libusb-devel mailing list</a>.
+ *
+ * This documentation assumes knowledge of how to operate USB devices from
+ * a software standpoint (descriptors, configurations, interfaces, endpoints,
+ * control/bulk/interrupt/isochronous transfers, etc). Full information
+ * can be found in the <a href="http://www.usb.org/developers/docs/">USB 3.0
+ * Specification</a> which is available for free download. You can probably
+ * find less verbose introductions by searching the web.
+ *
+ * \section API Application Programming Interface (API)
+ *
+ * See the \ref libusb_api page for a complete list of the libusb functions.
+ *
+ * \section features Library features
+ *
+ * - All transfer types supported (control/bulk/interrupt/isochronous)
+ * - 2 transfer interfaces:
+ * -# Synchronous (simple)
+ * -# Asynchronous (more complicated, but more powerful)
+ * - Thread safe (although the asynchronous interface means that you
+ * usually won't need to thread)
+ * - Lightweight with lean API
+ * - Compatible with libusb-0.1 through the libusb-compat-0.1 translation layer
+ * - Hotplug support (on some platforms). See \ref libusb_hotplug.
+ *
+ * \section gettingstarted Getting Started
+ *
+ * To begin reading the API documentation, start with the Modules page which
+ * links to the different categories of libusb's functionality.
+ *
+ * One decision you will have to make is whether to use the synchronous
+ * or the asynchronous data transfer interface. The \ref libusb_io documentation
+ * provides some insight into this topic.
+ *
+ * Some example programs can be found in the libusb source distribution under
+ * the "examples" subdirectory. The libusb homepage includes a list of
+ * real-life project examples which use libusb.
+ *
+ * \section errorhandling Error handling
+ *
+ * libusb functions typically return 0 on success or a negative error code
+ * on failure. These negative error codes relate to LIBUSB_ERROR constants
+ * which are listed on the \ref libusb_misc "miscellaneous" documentation page.
+ *
+ * \section msglog Debug message logging
+ *
+ * libusb uses stderr for all logging. By default, logging is set to NONE,
+ * which means that no output will be produced. However, unless the library
+ * has been compiled with logging disabled, then any application calls to
+ * libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level), or the setting of the
+ * environmental variable LIBUSB_DEBUG outside of the application, can result
+ * in logging being produced. Your application should therefore not close
+ * stderr, but instead direct it to the null device if its output is
+ * undesirable.
+ *
+ * The libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) function can be
+ * used to enable logging of certain messages. Under standard configuration,
+ * libusb doesn't really log much so you are advised to use this function
+ * to enable all error/warning/ informational messages. It will help debug
+ * problems with your software.
+ *
+ * The logged messages are unstructured. There is no one-to-one correspondence
+ * between messages being logged and success or failure return codes from
+ * libusb functions. There is no format to the messages, so you should not
+ * try to capture or parse them. They are not and will not be localized.
+ * These messages are not intended to being passed to your application user;
+ * instead, you should interpret the error codes returned from libusb functions
+ * and provide appropriate notification to the user. The messages are simply
+ * there to aid you as a programmer, and if you're confused because you're
+ * getting a strange error code from a libusb function, enabling message
+ * logging may give you a suitable explanation.
+ *
+ * The LIBUSB_DEBUG environment variable can be used to enable message logging
+ * at run-time. This environment variable should be set to a log level number,
+ * which is interpreted the same as the
+ * libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) parameter. When this
+ * environment variable is set, the message logging verbosity level is fixed
+ * and libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) effectively does
+ * nothing.
+ *
+ * libusb can be compiled without any logging functions, useful for embedded
+ * systems. In this case, libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level)
+ * and the LIBUSB_DEBUG environment variable have no effects.
+ *
+ * libusb can also be compiled with verbose debugging messages always. When
+ * the library is compiled in this way, all messages of all verbosities are
+ * always logged. libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) and
+ * the LIBUSB_DEBUG environment variable have no effects.
+ *
+ * \section remarks Other remarks
+ *
+ * libusb does have imperfections. The \ref libusb_caveats "caveats" page attempts
+ * to document these.
+ */
+
+/**
+ * \page libusb_caveats Caveats
+ *
+ * \section fork Fork considerations
+ *
+ * libusb is <em>not</em> designed to work across fork() calls. Depending on
+ * the platform, there may be resources in the parent process that are not
+ * available to the child (e.g. the hotplug monitor thread on Linux). In
+ * addition, since the parent and child will share libusb's internal file
+ * descriptors, using libusb in any way from the child could cause the parent
+ * process's \ref libusb_context to get into an inconsistent state.
+ *
+ * On Linux, libusb's file descriptors will be marked as CLOEXEC, which means
+ * that it is safe to fork() and exec() without worrying about the child
+ * process needing to clean up state or having access to these file descriptors.
+ * Other platforms may not be so forgiving, so consider yourself warned!
+ *
+ * \section devresets Device resets
+ *
+ * The libusb_reset_device() function allows you to reset a device. If your
+ * program has to call such a function, it should obviously be aware that
+ * the reset will cause device state to change (e.g. register values may be
+ * reset).
+ *
+ * The problem is that any other program could reset the device your program
+ * is working with, at any time. libusb does not offer a mechanism to inform
+ * you when this has happened, so if someone else resets your device it will
+ * not be clear to your own program why the device state has changed.
+ *
+ * Ultimately, this is a limitation of writing drivers in userspace.
+ * Separation from the USB stack in the underlying kernel makes it difficult
+ * for the operating system to deliver such notifications to your program.
+ * The Linux kernel USB stack allows such reset notifications to be delivered
+ * to in-kernel USB drivers, but it is not clear how such notifications could
+ * be delivered to second-class drivers that live in userspace.
+ *
+ * \section blockonly Blocking-only functionality
+ *
+ * The functionality listed below is only available through synchronous,
+ * blocking functions. There are no asynchronous/non-blocking alternatives,
+ * and no clear ways of implementing these.
+ *
+ * - Configuration activation (libusb_set_configuration())
+ * - Interface/alternate setting activation (libusb_set_interface_alt_setting())
+ * - Releasing of interfaces (libusb_release_interface())
+ * - Clearing of halt/stall condition (libusb_clear_halt())
+ * - Device resets (libusb_reset_device())
+ *
+ * \section configsel Configuration selection and handling
+ *
+ * When libusb presents a device handle to an application, there is a chance
+ * that the corresponding device may be in unconfigured state. For devices
+ * with multiple configurations, there is also a chance that the configuration
+ * currently selected is not the one that the application wants to use.
+ *
+ * The obvious solution is to add a call to libusb_set_configuration() early
+ * on during your device initialization routines, but there are caveats to
+ * be aware of:
+ * -# If the device is already in the desired configuration, calling
+ * libusb_set_configuration() using the same configuration value will cause
+ * a lightweight device reset. This may not be desirable behaviour.
+ * -# In the case where the desired configuration is already active, libusb
+ * 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
+ * the fingerprint reader interface through libusb, but the kernel's
+ * USB-HID driver will almost always have claimed the keyboard interface.
+ * Because the kernel has claimed an interface, it is not even possible to
+ * perform the lightweight device reset, so libusb_set_configuration() will
+ * 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
+ * active configuration. If the configuration we want is already active, then
+ * we don't have to select any configuration:
+\code
+cfg = -1;
+libusb_get_configuration(dev, &cfg);
+if (cfg != desired)
+ libusb_set_configuration(dev, desired);
+\endcode
+ *
+ * This is probably suitable for most scenarios, but is inherently racy:
+ * another application or driver may change the selected configuration
+ * <em>after</em> the libusb_get_configuration() call.
+ *
+ * Even in cases where libusb_set_configuration() succeeds, consider that other
+ * applications or drivers may change configuration after your application
+ * calls libusb_set_configuration().
+ *
+ * One possible way to lock your device into a specific configuration is as
+ * follows:
+ * -# Set the desired configuration (or use the logic above to realise that
+ * it is already in the desired configuration)
+ * -# Claim the interface that you wish to use
+ * -# Check that the currently active configuration is the one that you want
+ * to use.
+ *
+ * The above method works because once an interface is claimed, no application
+ * or driver is able to select another configuration.
+ *
+ * \section earlycomp Early transfer completion
+ *
+ * NOTE: This section is currently Linux-centric. I am not sure if any of these
+ * considerations apply to Darwin or other platforms.
+ *
+ * When a transfer completes early (i.e. when less data is received/sent in
+ * any one packet than the transfer buffer allows for) then libusb is designed
+ * to terminate the transfer immediately, not transferring or receiving any
+ * more data unless other transfers have been queued by the user.
+ *
+ * On legacy platforms, libusb is unable to do this in all situations. After
+ * the incomplete packet occurs, "surplus" data may be transferred. For recent
+ * versions of libusb, this information is kept (the data length of the
+ * transfer is updated) and, for device-to-host transfers, any surplus data was
+ * added to the buffer. Still, this is not a nice solution because it loses the
+ * information about the end of the short packet, and the user probably wanted
+ * that surplus data to arrive in the next logical transfer.
+ *
+ * \section zlp Zero length packets
+ *
+ * - libusb is able to send a packet of zero length to an endpoint simply by
+ * submitting a transfer of zero length.
+ * - The \ref libusb_transfer_flags::LIBUSB_TRANSFER_ADD_ZERO_PACKET
+ * "LIBUSB_TRANSFER_ADD_ZERO_PACKET" flag is currently only supported on Linux.
+ */
+
+/**
+ * \page libusb_contexts Contexts
+ *
+ * It is possible that libusb may be used simultaneously from two independent
+ * libraries linked into the same executable. For example, if your application
+ * has a plugin-like system which allows the user to dynamically load a range
+ * of modules into your program, it is feasible that two independently
+ * developed modules may both use libusb.
+ *
+ * libusb is written to allow for these multiple user scenarios. The two
+ * "instances" of libusb will not interfere: libusb_set_option() calls
+ * from one user will not affect the same settings for other users, other
+ * users can continue using libusb after one of them calls libusb_exit(), etc.
+ *
+ * This is made possible through libusb's <em>context</em> concept. When you
+ * call libusb_init(), you are (optionally) given a context. You can then pass
+ * this context pointer back into future libusb functions.
+ *
+ * In order to keep things simple for more simplistic applications, it is
+ * legal to pass NULL to all functions requiring a context pointer (as long as
+ * you're sure no other code will attempt to use libusb from the same process).
+ * When you pass NULL, the default context will be used. The default context
+ * is created the first time a process calls libusb_init() when no other
+ * context is alive. Contexts are destroyed during libusb_exit().
+ *
+ * The default context is reference-counted and can be shared. That means that
+ * if libusb_init(NULL) is called twice within the same process, the two
+ * users end up sharing the same context. The deinitialization and freeing of
+ * the default context will only happen when the last user calls libusb_exit().
+ * In other words, the default context is created and initialized when its
+ * reference count goes from 0 to 1, and is deinitialized and destroyed when
+ * its reference count goes from 1 to 0.
+ *
+ * You may be wondering why only a subset of libusb functions require a
+ * context pointer in their function definition. Internally, libusb stores
+ * context pointers in other objects (e.g. libusb_device instances) and hence
+ * can infer the context from those objects.
+ */
+
+ /**
+ * \page libusb_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_dev_mem_alloc()
+ * - libusb_dev_mem_free()
+ * - 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_pollfds()
+ * - 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_pollfds()
+ * - libusb_get_port_number()
+ * - libusb_get_port_numbers()
+ * - libusb_get_port_path()
+ * - 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_event_handler()
+ * - 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_log_cb()
+ * - libusb_set_interface_alt_setting()
+ * - libusb_set_iso_packet_lengths()
+ * - libusb_set_option()
+ * - 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_option
+ * - \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 libusb_lib Library initialization/deinitialization
+ * This page details how to initialize and deinitialize libusb. Initialization
+ * must be performed before using any libusb functionality, and similarly you
+ * must not call any libusb functions after deinitialization.
+ */
+
+/**
+ * @defgroup libusb_dev Device handling and enumeration
+ * The functionality documented below is designed to help with the following
+ * operations:
+ * - Enumerating the USB devices currently attached to the system
+ * - Choosing a device to operate from your software
+ * - Opening and closing the chosen device
+ *
+ * \section nutshell In a nutshell...
+ *
+ * The description below really makes things sound more complicated than they
+ * actually are. The following sequence of function calls will be suitable
+ * for almost all scenarios and does not require you to have such a deep
+ * understanding of the resource management issues:
+ * \code
+// discover devices
+libusb_device **list;
+libusb_device *found = NULL;
+ssize_t cnt = libusb_get_device_list(NULL, &list);
+ssize_t i = 0;
+int err = 0;
+if (cnt < 0)
+ error();
+
+for (i = 0; i < cnt; i++) {
+ libusb_device *device = list[i];
+ if (is_interesting(device)) {
+ found = device;
+ break;
+ }
+}
+
+if (found) {
+ libusb_device_handle *handle;
+
+ err = libusb_open(found, &handle);
+ if (err)
+ error();
+ // etc
+}
+
+libusb_free_device_list(list, 1);
+\endcode
+ *
+ * The two important points:
+ * - You asked libusb_free_device_list() to unreference the devices (2nd
+ * parameter)
+ * - You opened the device before freeing the list and unreferencing the
+ * devices
+ *
+ * If you ended up with a handle, you can now proceed to perform I/O on the
+ * device.
+ *
+ * \section devshandles Devices and device handles
+ * libusb has a concept of a USB device, represented by the
+ * \ref libusb_device opaque type. A device represents a USB device that
+ * is currently or was previously connected to the system. Using a reference
+ * to a device, you can determine certain information about the device (e.g.
+ * you can read the descriptor data).
+ *
+ * The libusb_get_device_list() function can be used to obtain a list of
+ * devices currently connected to the system. This is known as device
+ * discovery.
+ *
+ * Just because you have a reference to a device does not mean it is
+ * necessarily usable. The device may have been unplugged, you may not have
+ * permission to operate such device, or another program or driver may be
+ * using the device.
+ *
+ * When you've found a device that you'd like to operate, you must ask
+ * libusb to open the device using the libusb_open() function. Assuming
+ * success, libusb then returns you a <em>device handle</em>
+ * (a \ref libusb_device_handle pointer). All "real" I/O operations then
+ * operate on the handle rather than the original device pointer.
+ *
+ * \section devref Device discovery and reference counting
+ *
+ * Device discovery (i.e. calling libusb_get_device_list()) returns a
+ * freshly-allocated list of devices. The list itself must be freed when
+ * you are done with it. libusb also needs to know when it is OK to free
+ * the contents of the list - the devices themselves.
+ *
+ * To handle these issues, libusb provides you with two separate items:
+ * - A function to free the list itself
+ * - A reference counting system for the devices inside
+ *
+ * New devices presented by the libusb_get_device_list() function all have a
+ * reference count of 1. You can increase and decrease reference count using
+ * libusb_ref_device() and libusb_unref_device(). A device is destroyed when
+ * its reference count reaches 0.
+ *
+ * With the above information in mind, the process of opening a device can
+ * be viewed as follows:
+ * -# Discover devices using libusb_get_device_list().
+ * -# Choose the device that you want to operate, and call libusb_open().
+ * -# Unref all devices in the discovered device list.
+ * -# Free the discovered device list.
+ *
+ * The order is important - you must not unreference the device before
+ * attempting to open it, because unreferencing it may destroy the device.
+ *
+ * For convenience, the libusb_free_device_list() function includes a
+ * parameter to optionally unreference all the devices in the list before
+ * freeing the list itself. This combines steps 3 and 4 above.
+ *
+ * As an implementation detail, libusb_open() actually adds a reference to
+ * the device in question. This is because the device remains available
+ * through the handle via libusb_get_device(). The reference is deleted during
+ * libusb_close().
+ */
+
+/** @defgroup libusb_misc Miscellaneous */
+
+/* we traverse usbfs without knowing how many devices we are going to find.
+ * so we create this discovered_devs model which is similar to a linked-list
+ * which grows when required. it can be freed once discovery has completed,
+ * eliminating the need for a list node in the libusb_device structure
+ * itself. */
+#define DISCOVERED_DEVICES_SIZE_STEP 8
+
+static struct discovered_devs *discovered_devs_alloc(void)
+{
+ struct discovered_devs *ret =
+ malloc(sizeof(*ret) + (sizeof(void *) * DISCOVERED_DEVICES_SIZE_STEP));
+
+ if (ret) {
+ ret->len = 0;
+ ret->capacity = DISCOVERED_DEVICES_SIZE_STEP;
+ }
+ return ret;
+}
+
+static void discovered_devs_free(struct discovered_devs *discdevs)
+{
+ size_t i;
+
+ for (i = 0; i < discdevs->len; i++)
+ libusb_unref_device(discdevs->devices[i]);
+
+ free(discdevs);
+}
+
+/* append a device to the discovered devices collection. may realloc itself,
+ * returning new discdevs. returns NULL on realloc failure. */
+struct discovered_devs *discovered_devs_append(
+ struct discovered_devs *discdevs, struct libusb_device *dev)
+{
+ size_t len = discdevs->len;
+ size_t capacity;
+ struct discovered_devs *new_discdevs;
+
+ /* if there is space, just append the device */
+ if (len < discdevs->capacity) {
+ discdevs->devices[len] = libusb_ref_device(dev);
+ discdevs->len++;
+ return discdevs;
+ }
+
+ /* exceeded capacity, need to grow */
+ usbi_dbg("need to increase capacity");
+ capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP;
+ /* can't use usbi_reallocf here because in failure cases it would
+ * free the existing discdevs without unreferencing its devices. */
+ new_discdevs = realloc(discdevs,
+ sizeof(*discdevs) + (sizeof(void *) * capacity));
+ if (!new_discdevs) {
+ discovered_devs_free(discdevs);
+ return NULL;
+ }
+
+ discdevs = new_discdevs;
+ discdevs->capacity = capacity;
+ discdevs->devices[len] = libusb_ref_device(dev);
+ discdevs->len++;
+
+ return discdevs;
+}
+
+/* Allocate a new device with a specific session ID. The returned device has
+ * a reference count of 1. */
+struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
+ unsigned long session_id)
+{
+ size_t priv_size = usbi_backend.device_priv_size;
+ struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size);
+ int r;
+
+ if (!dev)
+ return NULL;
+
+ r = usbi_mutex_init(&dev->lock);
+ if (r) {
+ free(dev);
+ return NULL;
+ }
+
+ dev->ctx = ctx;
+ dev->refcnt = 1;
+ dev->session_data = session_id;
+ dev->speed = LIBUSB_SPEED_UNKNOWN;
+
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
+ usbi_connect_device (dev);
+ }
+
+ return dev;
+}
+
+void usbi_connect_device(struct libusb_device *dev)
+{
+ struct libusb_context *ctx = DEVICE_CTX(dev);
+
+ dev->attached = 1;
+
+ usbi_mutex_lock(&dev->ctx->usb_devs_lock);
+ list_add(&dev->list, &dev->ctx->usb_devs);
+ usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
+
+ /* Signal that an event has occurred for this device if we support hotplug AND
+ * the hotplug message list is ready. This prevents an event from getting raised
+ * during initial enumeration. */
+ if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) {
+ usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
+ }
+}
+
+void usbi_disconnect_device(struct libusb_device *dev)
+{
+ struct libusb_context *ctx = DEVICE_CTX(dev);
+
+ usbi_mutex_lock(&dev->lock);
+ dev->attached = 0;
+ usbi_mutex_unlock(&dev->lock);
+
+ usbi_mutex_lock(&ctx->usb_devs_lock);
+ list_del(&dev->list);
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
+
+ /* Signal that an event has occurred for this device if we support hotplug AND
+ * the hotplug message list is ready. This prevents an event from getting raised
+ * during initial enumeration. libusb_handle_events will take care of dereferencing
+ * the device. */
+ if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) {
+ usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
+ }
+}
+
+/* Perform some final sanity checks on a newly discovered device. If this
+ * function fails (negative return code), the device should not be added
+ * to the discovered device list. */
+int usbi_sanitize_device(struct libusb_device *dev)
+{
+ int r;
+ uint8_t num_configurations;
+
+ r = usbi_device_cache_descriptor(dev);
+ if (r < 0)
+ return r;
+
+ num_configurations = dev->device_descriptor.bNumConfigurations;
+ if (num_configurations > USB_MAXCONFIG) {
+ usbi_err(DEVICE_CTX(dev), "too many configurations");
+ return LIBUSB_ERROR_IO;
+ } else if (0 == num_configurations)
+ usbi_dbg("zero configurations, maybe an unauthorized device");
+
+ dev->num_configurations = num_configurations;
+ return 0;
+}
+
+/* Examine libusb's internal list of known devices, looking for one with
+ * a specific session ID. Returns the matching device if it was found, and
+ * NULL otherwise. */
+struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
+ unsigned long session_id)
+{
+ struct libusb_device *dev;
+ struct libusb_device *ret = NULL;
+
+ usbi_mutex_lock(&ctx->usb_devs_lock);
+ list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device)
+ if (dev->session_data == session_id) {
+ ret = libusb_ref_device(dev);
+ break;
+ }
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
+
+ return ret;
+}
+
+/** @ingroup libusb_dev
+ * Returns a list of USB devices currently attached to the system. This is
+ * your entry point into finding a USB device to operate.
+ *
+ * You are expected to unreference all the devices when you are done with
+ * them, and then free the list with libusb_free_device_list(). Note that
+ * libusb_free_device_list() can unref all the devices for you. Be careful
+ * not to unreference a device you are about to open until after you have
+ * opened it.
+ *
+ * This return value of this function indicates the number of devices in
+ * the resultant list. The list is actually one element larger, as it is
+ * NULL-terminated.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param list output location for a list of devices. Must be later freed with
+ * libusb_free_device_list().
+ * \returns the number of devices in the outputted list, or any
+ * \ref libusb_error according to errors encountered by the backend.
+ */
+ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
+ libusb_device ***list)
+{
+ struct discovered_devs *discdevs = discovered_devs_alloc();
+ struct libusb_device **ret;
+ int r = 0;
+ ssize_t i, len;
+ USBI_GET_CONTEXT(ctx);
+ usbi_dbg("");
+
+ if (!discdevs)
+ return LIBUSB_ERROR_NO_MEM;
+
+ if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
+ /* backend provides hotplug support */
+ struct libusb_device *dev;
+
+ if (usbi_backend.hotplug_poll)
+ usbi_backend.hotplug_poll();
+
+ usbi_mutex_lock(&ctx->usb_devs_lock);
+ list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) {
+ discdevs = discovered_devs_append(discdevs, dev);
+
+ if (!discdevs) {
+ r = LIBUSB_ERROR_NO_MEM;
+ break;
+ }
+ }
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
+ } else {
+ /* backend does not provide hotplug support */
+ r = usbi_backend.get_device_list(ctx, &discdevs);
+ }
+
+ if (r < 0) {
+ len = r;
+ goto out;
+ }
+
+ /* convert discovered_devs into a list */
+ len = (ssize_t)discdevs->len;
+ ret = calloc((size_t)len + 1, sizeof(struct libusb_device *));
+ if (!ret) {
+ len = LIBUSB_ERROR_NO_MEM;
+ goto out;
+ }
+
+ ret[len] = NULL;
+ for (i = 0; i < len; i++) {
+ struct libusb_device *dev = discdevs->devices[i];
+ ret[i] = libusb_ref_device(dev);
+ }
+ *list = ret;
+
+out:
+ if (discdevs)
+ discovered_devs_free(discdevs);
+ return len;
+}
+
+/** \ingroup libusb_dev
+ * Frees a list of devices previously discovered using
+ * libusb_get_device_list(). If the unref_devices parameter is set, the
+ * reference count of each device in the list is decremented by 1.
+ * \param list the list to free
+ * \param unref_devices whether to unref the devices in the list
+ */
+void API_EXPORTED libusb_free_device_list(libusb_device **list,
+ int unref_devices)
+{
+ if (!list)
+ return;
+
+ if (unref_devices) {
+ int i = 0;
+ struct libusb_device *dev;
+
+ while ((dev = list[i++]) != NULL)
+ libusb_unref_device(dev);
+ }
+ free(list);
+}
+
+/** \ingroup libusb_dev
+ * Get the number of the bus that a device is connected to.
+ * \param dev a device
+ * \returns the bus number
+ */
+uint8_t API_EXPORTED libusb_get_bus_number(libusb_device *dev)
+{
+ return dev->bus_number;
+}
+
+/** \ingroup libusb_dev
+ * Get the number of the port that a device is connected to.
+ * Unless the OS does something funky, or you are hot-plugging USB extension cards,
+ * the port number returned by this call is usually guaranteed to be uniquely tied
+ * to a physical port, meaning that different devices plugged on the same physical
+ * port should return the same port number.
+ *
+ * But outside of this, there is no guarantee that the port number returned by this
+ * call will remain the same, or even match the order in which ports have been
+ * numbered by the HUB/HCD manufacturer.
+ *
+ * \param dev a device
+ * \returns the port number (0 if not available)
+ */
+uint8_t API_EXPORTED libusb_get_port_number(libusb_device *dev)
+{
+ return dev->port_number;
+}
+
+/** \ingroup libusb_dev
+ * Get the list of all port numbers from root for the specified device
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ * \param dev a device
+ * \param port_numbers the array that should contain the port numbers
+ * \param port_numbers_len the maximum length of the array. As per the USB 3.0
+ * specs, the current maximum limit for the depth is 7.
+ * \returns the number of elements filled
+ * \returns LIBUSB_ERROR_OVERFLOW if the array is too small
+ */
+int API_EXPORTED libusb_get_port_numbers(libusb_device *dev,
+ uint8_t* port_numbers, int port_numbers_len)
+{
+ int i = port_numbers_len;
+ struct libusb_context *ctx = DEVICE_CTX(dev);
+
+ if (port_numbers_len <= 0)
+ return LIBUSB_ERROR_INVALID_PARAM;
+
+ // HCDs can be listed as devices with port #0
+ while((dev) && (dev->port_number != 0)) {
+ if (--i < 0) {
+ usbi_warn(ctx, "port numbers array is too small");
+ return LIBUSB_ERROR_OVERFLOW;
+ }
+ port_numbers[i] = dev->port_number;
+ dev = dev->parent_dev;
+ }
+ if (i < port_numbers_len)
+ memmove(port_numbers, &port_numbers[i], port_numbers_len - i);
+ return port_numbers_len - i;
+}
+
+/** \ingroup libusb_dev
+ * Deprecated please use libusb_get_port_numbers instead.
+ */
+int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev,
+ uint8_t* port_numbers, uint8_t port_numbers_len)
+{
+ UNUSED(ctx);
+
+ return libusb_get_port_numbers(dev, port_numbers, port_numbers_len);
+}
+
+/** \ingroup libusb_dev
+ * Get the the parent from the specified device.
+ * \param dev a device
+ * \returns the device parent or NULL if not available
+ * You should issue a \ref libusb_get_device_list() before calling this
+ * function and make sure that you only access the parent before issuing
+ * \ref libusb_free_device_list(). The reason is that libusb currently does
+ * not maintain a permanent list of device instances, and therefore can
+ * only guarantee that parents are fully instantiated within a
+ * libusb_get_device_list() - libusb_free_device_list() block.
+ */
+DEFAULT_VISIBILITY
+libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev)
+{
+ return dev->parent_dev;
+}
+
+/** \ingroup libusb_dev
+ * Get the address of the device on the bus it is connected to.
+ * \param dev a device
+ * \returns the device address
+ */
+uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev)
+{
+ return dev->device_address;
+}
+
+/** \ingroup libusb_dev
+ * Get the negotiated connection speed for a device.
+ * \param dev a device
+ * \returns a \ref libusb_speed code, where LIBUSB_SPEED_UNKNOWN means that
+ * the OS doesn't know or doesn't support returning the negotiated speed.
+ */
+int API_EXPORTED libusb_get_device_speed(libusb_device *dev)
+{
+ return dev->speed;
+}
+
+static const struct libusb_endpoint_descriptor *find_endpoint(
+ struct libusb_config_descriptor *config, unsigned char endpoint)
+{
+ int iface_idx;
+ for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) {
+ const struct libusb_interface *iface = &config->interface[iface_idx];
+ int altsetting_idx;
+
+ for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting;
+ altsetting_idx++) {
+ const struct libusb_interface_descriptor *altsetting
+ = &iface->altsetting[altsetting_idx];
+ int ep_idx;
+
+ for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) {
+ const struct libusb_endpoint_descriptor *ep =
+ &altsetting->endpoint[ep_idx];
+ if (ep->bEndpointAddress == endpoint)
+ return ep;
+ }
+ }
+ }
+ return NULL;
+}
+
+/** \ingroup libusb_dev
+ * Convenience function to retrieve the wMaxPacketSize value for a particular
+ * endpoint in the active device configuration.
+ *
+ * This function was originally intended to be of assistance when setting up
+ * isochronous transfers, but a design mistake resulted in this function
+ * instead. It simply returns the wMaxPacketSize value without considering
+ * its contents. If you're dealing with isochronous transfers, you probably
+ * want libusb_get_max_iso_packet_size() instead.
+ *
+ * \param dev a device
+ * \param endpoint address of the endpoint in question
+ * \returns the wMaxPacketSize value
+ * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
+ * \returns LIBUSB_ERROR_OTHER on other failure
+ */
+int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev,
+ unsigned char endpoint)
+{
+ struct libusb_config_descriptor *config;
+ const struct libusb_endpoint_descriptor *ep;
+ int r;
+
+ r = libusb_get_active_config_descriptor(dev, &config);
+ if (r < 0) {
+ usbi_err(DEVICE_CTX(dev),
+ "could not retrieve active config descriptor");
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ ep = find_endpoint(config, endpoint);
+ if (!ep) {
+ r = LIBUSB_ERROR_NOT_FOUND;
+ goto out;
+ }
+
+ r = ep->wMaxPacketSize;
+
+out:
+ libusb_free_config_descriptor(config);
+ return r;
+}
+
+/** \ingroup libusb_dev
+ * Calculate the maximum packet size which a specific endpoint is capable is
+ * sending or receiving in the duration of 1 microframe
+ *
+ * Only the active configuration is examined. The calculation is based on the
+ * wMaxPacketSize field in the endpoint descriptor as described in section
+ * 9.6.6 in the USB 2.0 specifications.
+ *
+ * If acting on an isochronous or interrupt endpoint, this function will
+ * multiply the value found in bits 0:10 by the number of transactions per
+ * microframe (determined by bits 11:12). Otherwise, this function just
+ * returns the numeric value found in bits 0:10. For USB 3.0 device, it
+ * will attempts to retrieve the Endpoint Companion Descriptor to return
+ * wBytesPerInterval.
+ *
+ * This function is useful for setting up isochronous transfers, for example
+ * you might pass the return value from this function to
+ * libusb_set_iso_packet_lengths() in order to set the length field of every
+ * isochronous packet in a transfer.
+ *
+ * Since v1.0.3.
+ *
+ * \param dev a device
+ * \param endpoint address of the endpoint in question
+ * \returns the maximum packet size which can be sent/received on this endpoint
+ * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
+ * \returns LIBUSB_ERROR_OTHER on other failure
+ */
+int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev,
+ unsigned char endpoint)
+{
+ struct libusb_config_descriptor *config;
+ const struct libusb_endpoint_descriptor *ep;
+ struct libusb_ss_endpoint_companion_descriptor *ss_ep_cmp;
+ enum libusb_transfer_type ep_type;
+ uint16_t val;
+ int r;
+ int speed;
+
+ r = libusb_get_active_config_descriptor(dev, &config);
+ if (r < 0) {
+ usbi_err(DEVICE_CTX(dev),
+ "could not retrieve active config descriptor");
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ ep = find_endpoint(config, endpoint);
+ if (!ep) {
+ r = LIBUSB_ERROR_NOT_FOUND;
+ goto out;
+ }
+
+ speed = libusb_get_device_speed( dev );
+ if (speed == LIBUSB_SPEED_SUPER) {
+ r = libusb_get_ss_endpoint_companion_descriptor(dev->ctx, ep, &ss_ep_cmp);
+ if (r == LIBUSB_SUCCESS) {
+ r = ss_ep_cmp->wBytesPerInterval;
+ libusb_free_ss_endpoint_companion_descriptor(ss_ep_cmp);
+ }
+ }
+
+ /* If the device isn't a SuperSpeed device or retrieving the SS endpoint didn't worked. */
+ if (speed != LIBUSB_SPEED_SUPER || r < 0) {
+ val = ep->wMaxPacketSize;
+ ep_type = (enum libusb_transfer_type) (ep->bmAttributes & 0x3);
+
+ r = val & 0x07ff;
+ if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
+ || ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT)
+ r *= (1 + ((val >> 11) & 3));
+ }
+
+out:
+ libusb_free_config_descriptor(config);
+ return r;
+}
+
+/** \ingroup libusb_dev
+ * Increment the reference count of a device.
+ * \param dev the device to reference
+ * \returns the same device
+ */
+DEFAULT_VISIBILITY
+libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev)
+{
+ usbi_mutex_lock(&dev->lock);
+ dev->refcnt++;
+ usbi_mutex_unlock(&dev->lock);
+ return dev;
+}
+
+/** \ingroup libusb_dev
+ * Decrement the reference count of a device. If the decrement operation
+ * causes the reference count to reach zero, the device shall be destroyed.
+ * \param dev the device to unreference
+ */
+void API_EXPORTED libusb_unref_device(libusb_device *dev)
+{
+ int refcnt;
+
+ if (!dev)
+ return;
+
+ usbi_mutex_lock(&dev->lock);
+ refcnt = --dev->refcnt;
+ usbi_mutex_unlock(&dev->lock);
+
+ if (refcnt == 0) {
+ usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address);
+
+ libusb_unref_device(dev->parent_dev);
+
+ if (usbi_backend.destroy_device)
+ usbi_backend.destroy_device(dev);
+
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
+ /* backend does not support hotplug */
+ usbi_disconnect_device(dev);
+ }
+
+ usbi_mutex_destroy(&dev->lock);
+ free(dev);
+ }
+}
+
+/*
+ * Signal the event pipe so that the event handling thread will be
+ * interrupted to process an internal event.
+ */
+int usbi_signal_event(struct libusb_context *ctx)
+{
+ unsigned char dummy = 1;
+ ssize_t r;
+
+ /* write some data on event pipe to interrupt event handlers */
+ r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy));
+ if (r != sizeof(dummy)) {
+ usbi_warn(ctx, "internal signalling write failed");
+ return LIBUSB_ERROR_IO;
+ }
+
+ return 0;
+}
+
+/*
+ * Clear the event pipe so that the event handling will no longer be
+ * 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");
+ return LIBUSB_ERROR_IO;
+ }
+
+ return 0;
+}
+
+/** \ingroup libusb_dev
+ * Wrap a platform-specific system device handle and obtain a libusb device
+ * handle for the underlying device. The handle allows you to use libusb to
+ * perform I/O on the device in question.
+ *
+ * On Linux, the system device handle must be a valid file descriptor opened
+ * on the device node.
+ *
+ * The system device handle must remain open until libusb_close() is called.
+ * The system device handle will not be closed by libusb_close().
+ *
+ * Internally, this function creates a temporary device and makes it
+ * available to you through libusb_get_device(). This device is destroyed
+ * during libusb_close(). The device shall not be opened through libusb_open().
+ *
+ * This is a non-blocking function; no requests are sent over the bus.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param sys_dev the platform-specific system device handle
+ * \param dev_handle output location for the returned device handle pointer. Only
+ * populated when the return code is 0.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure
+ * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED if the operation is not supported on this
+ * platform
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev,
+ libusb_device_handle **dev_handle)
+{
+ struct libusb_device_handle *_dev_handle;
+ size_t priv_size = usbi_backend.device_handle_priv_size;
+ int r;
+ usbi_dbg("wrap_sys_device %p", (void *)sys_dev);
+
+ USBI_GET_CONTEXT(ctx);
+
+ if (!usbi_backend.wrap_sys_device)
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+
+ _dev_handle = malloc(sizeof(*_dev_handle) + priv_size);
+ if (!_dev_handle)
+ return LIBUSB_ERROR_NO_MEM;
+
+ r = usbi_mutex_init(&_dev_handle->lock);
+ if (r) {
+ free(_dev_handle);
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ _dev_handle->dev = NULL;
+ _dev_handle->auto_detach_kernel_driver = 0;
+ _dev_handle->claimed_interfaces = 0;
+ memset(&_dev_handle->os_priv, 0, priv_size);
+
+ r = usbi_backend.wrap_sys_device(ctx, _dev_handle, sys_dev);
+ if (r < 0) {
+ usbi_dbg("wrap_sys_device %p returns %d", (void *)sys_dev, r);
+ usbi_mutex_destroy(&_dev_handle->lock);
+ free(_dev_handle);
+ return r;
+ }
+
+ usbi_mutex_lock(&ctx->open_devs_lock);
+ list_add(&_dev_handle->list, &ctx->open_devs);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
+ *dev_handle = _dev_handle;
+
+ return 0;
+}
+
+/** \ingroup libusb_dev
+ * Open a device and obtain a device handle. A handle allows you to perform
+ * I/O on the device in question.
+ *
+ * Internally, this function adds a reference to the device and makes it
+ * available to you through libusb_get_device(). This reference is removed
+ * during libusb_close().
+ *
+ * This is a non-blocking function; no requests are sent over the bus.
+ *
+ * \param dev the device to open
+ * \param dev_handle output location for the returned device handle pointer. Only
+ * populated when the return code is 0.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure
+ * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_open(libusb_device *dev,
+ libusb_device_handle **dev_handle)
+{
+ struct libusb_context *ctx = DEVICE_CTX(dev);
+ struct libusb_device_handle *_dev_handle;
+ size_t priv_size = usbi_backend.device_handle_priv_size;
+ int r;
+ usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
+
+ if (!dev->attached) {
+ return LIBUSB_ERROR_NO_DEVICE;
+ }
+
+ _dev_handle = malloc(sizeof(*_dev_handle) + priv_size);
+ if (!_dev_handle)
+ return LIBUSB_ERROR_NO_MEM;
+
+ r = usbi_mutex_init(&_dev_handle->lock);
+ if (r) {
+ free(_dev_handle);
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ _dev_handle->dev = libusb_ref_device(dev);
+ _dev_handle->auto_detach_kernel_driver = 0;
+ _dev_handle->claimed_interfaces = 0;
+ memset(&_dev_handle->os_priv, 0, priv_size);
+
+ r = usbi_backend.open(_dev_handle);
+ if (r < 0) {
+ usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
+ libusb_unref_device(dev);
+ usbi_mutex_destroy(&_dev_handle->lock);
+ free(_dev_handle);
+ return r;
+ }
+
+ usbi_mutex_lock(&ctx->open_devs_lock);
+ list_add(&_dev_handle->list, &ctx->open_devs);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
+ *dev_handle = _dev_handle;
+
+ return 0;
+}
+
+/** \ingroup libusb_dev
+ * Convenience function for finding a device with a particular
+ * <tt>idVendor</tt>/<tt>idProduct</tt> combination. This function is intended
+ * for those scenarios where you are using libusb to knock up a quick test
+ * application - it allows you to avoid calling libusb_get_device_list() and
+ * worrying about traversing/freeing the list.
+ *
+ * This function has limitations and is hence not intended for use in real
+ * applications: if multiple devices have the same IDs it will only
+ * give you the first one, etc.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param vendor_id the idVendor value to search for
+ * \param product_id the idProduct value to search for
+ * \returns a device handle for the first found device, or NULL on error
+ * or if the device could not be found. */
+DEFAULT_VISIBILITY
+libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
+ libusb_context *ctx, uint16_t vendor_id, uint16_t product_id)
+{
+ struct libusb_device **devs;
+ struct libusb_device *found = NULL;
+ struct libusb_device *dev;
+ struct libusb_device_handle *dev_handle = NULL;
+ size_t i = 0;
+ int r;
+
+ if (libusb_get_device_list(ctx, &devs) < 0)
+ return NULL;
+
+ while ((dev = devs[i++]) != NULL) {
+ struct libusb_device_descriptor desc;
+ r = libusb_get_device_descriptor(dev, &desc);
+ if (r < 0)
+ goto out;
+ if (desc.idVendor == vendor_id && desc.idProduct == product_id) {
+ found = dev;
+ break;
+ }
+ }
+
+ if (found) {
+ r = libusb_open(found, &dev_handle);
+ if (r < 0)
+ dev_handle = NULL;
+ }
+
+out:
+ libusb_free_device_list(devs, 1);
+ return dev_handle;
+}
+
+static void do_close(struct libusb_context *ctx,
+ struct libusb_device_handle *dev_handle)
+{
+ struct usbi_transfer *itransfer;
+ struct usbi_transfer *tmp;
+
+ /* remove any transfers in flight that are for this device */
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+
+ /* safe iteration because transfers may be being deleted */
+ list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) {
+ struct libusb_transfer *transfer =
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+
+ if (transfer->dev_handle != dev_handle)
+ continue;
+
+ usbi_mutex_lock(&itransfer->lock);
+ if (!(itransfer->state_flags & USBI_TRANSFER_DEVICE_DISAPPEARED)) {
+ usbi_err(ctx, "Device handle closed while transfer was still being processed, but the device is still connected as far as we know");
+
+ if (itransfer->state_flags & USBI_TRANSFER_CANCELLING)
+ usbi_warn(ctx, "A cancellation for an in-flight transfer hasn't completed but closing the device handle");
+ else
+ usbi_err(ctx, "A cancellation hasn't even been scheduled on the transfer for which the device is closing");
+ }
+ usbi_mutex_unlock(&itransfer->lock);
+
+ /* remove from the list of in-flight transfers and make sure
+ * we don't accidentally use the device handle in the future
+ * (or that such accesses will be easily caught and identified as a crash)
+ */
+ list_del(&itransfer->list);
+ transfer->dev_handle = NULL;
+
+ /* it is up to the user to free up the actual transfer struct. this is
+ * just making sure that we don't attempt to process the transfer after
+ * the device handle is invalid
+ */
+ usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed",
+ transfer, dev_handle);
+ }
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+
+ usbi_mutex_lock(&ctx->open_devs_lock);
+ list_del(&dev_handle->list);
+ usbi_mutex_unlock(&ctx->open_devs_lock);
+
+ usbi_backend.close(dev_handle);
+ libusb_unref_device(dev_handle->dev);
+ usbi_mutex_destroy(&dev_handle->lock);
+ free(dev_handle);
+}
+
+/** \ingroup libusb_dev
+ * Close a device handle. Should be called on all open handles before your
+ * application exits.
+ *
+ * Internally, this function destroys the reference that was added by
+ * libusb_open() on the given device.
+ *
+ * This is a non-blocking function; no requests are sent over the bus.
+ *
+ * \param dev_handle the device handle to close
+ */
+void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
+{
+ struct libusb_context *ctx;
+ int handling_events;
+ int pending_events;
+
+ if (!dev_handle)
+ return;
+ usbi_dbg("");
+
+ ctx = HANDLE_CTX(dev_handle);
+ handling_events = usbi_handling_events(ctx);
+
+ /* Similarly to libusb_open(), we want to interrupt all event handlers
+ * at this point. More importantly, we want to perform the actual close of
+ * the device while holding the event handling lock (preventing any other
+ * thread from doing event handling) because we will be removing a file
+ * descriptor from the polling loop. If this is being called by the current
+ * event handler, we can bypass the interruption code because we already
+ * hold the event handling lock. */
+
+ if (!handling_events) {
+ /* Record that we are closing a device.
+ * Only signal an event if there are no prior pending events. */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ pending_events = usbi_pending_events(ctx);
+ ctx->device_close++;
+ if (!pending_events)
+ usbi_signal_event(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ /* take event handling lock */
+ libusb_lock_events(ctx);
+ }
+
+ /* Close the device */
+ do_close(ctx, dev_handle);
+
+ if (!handling_events) {
+ /* We're done with closing this device.
+ * Clear the event pipe if there are no further pending events. */
+ usbi_mutex_lock(&ctx->event_data_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 */
+ libusb_unlock_events(ctx);
+ }
+}
+
+/** \ingroup libusb_dev
+ * Get the underlying device for a device handle. This function does not modify
+ * the reference count of the returned device, so do not feel compelled to
+ * unreference it when you are done.
+ * \param dev_handle a device handle
+ * \returns the underlying device
+ */
+DEFAULT_VISIBILITY
+libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle)
+{
+ return dev_handle->dev;
+}
+
+/** \ingroup libusb_dev
+ * Determine the bConfigurationValue of the currently active configuration.
+ *
+ * You could formulate your own control request to obtain this information,
+ * but this function has the advantage that it may be able to retrieve the
+ * information from operating system caches (no I/O involved).
+ *
+ * If the OS does not cache this information, then this function will block
+ * while a control transfer is submitted to retrieve the information.
+ *
+ * This function will return a value of 0 in the <tt>config</tt> output
+ * parameter if the device is in unconfigured state.
+ *
+ * \param dev_handle a device handle
+ * \param config output location for the bConfigurationValue of the active
+ * configuration (only valid for return code 0)
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle,
+ int *config)
+{
+ int r = LIBUSB_ERROR_NOT_SUPPORTED;
+
+ usbi_dbg("");
+ if (usbi_backend.get_configuration)
+ r = usbi_backend.get_configuration(dev_handle, config);
+
+ if (r == LIBUSB_ERROR_NOT_SUPPORTED) {
+ uint8_t tmp = 0;
+ usbi_dbg("falling back to control message");
+ r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
+ LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &tmp, 1, 1000);
+ if (r == 0) {
+ usbi_err(HANDLE_CTX(dev_handle), "zero bytes returned in ctrl transfer?");
+ r = LIBUSB_ERROR_IO;
+ } else if (r == 1) {
+ r = 0;
+ *config = tmp;
+ } else {
+ usbi_dbg("control failed, error %d", r);
+ }
+ }
+
+ if (r == 0)
+ usbi_dbg("active config %d", *config);
+
+ return r;
+}
+
+/** \ingroup libusb_dev
+ * Set the active configuration for a device.
+ *
+ * The operating system may or may not have already set an active
+ * configuration on the device. It is up to your application to ensure the
+ * correct configuration is selected before you attempt to claim interfaces
+ * and perform other operations.
+ *
+ * If you call this function on a device already configured with the selected
+ * configuration, then this function will act as a lightweight device reset:
+ * it will issue a SET_CONFIGURATION request using the current configuration,
+ * causing most USB-related device state to be reset (altsetting reset to zero,
+ * endpoint halts cleared, toggles reset).
+ *
+ * You cannot change/reset configuration if your application has claimed
+ * interfaces. It is advised to set the desired configuration before claiming
+ * interfaces.
+ *
+ * Alternatively you can call libusb_release_interface() first. Note if you
+ * do things this way you must ensure that auto_detach_kernel_driver for
+ * <tt>dev</tt> is 0, otherwise the kernel driver will be re-attached when you
+ * release the interface(s).
+ *
+ * You cannot change/reset configuration if other applications or drivers have
+ * claimed interfaces.
+ *
+ * A configuration value of -1 will put the device in unconfigured state.
+ * The USB specifications state that a configuration value of 0 does this,
+ * however buggy devices exist which actually have a configuration 0.
+ *
+ * You should always use this function rather than formulating your own
+ * SET_CONFIGURATION control request. This is because the underlying operating
+ * system needs to know when such changes happen.
+ *
+ * This is a blocking function.
+ *
+ * \param dev_handle a device handle
+ * \param configuration the bConfigurationValue of the configuration you
+ * wish to activate, or -1 if you wish to put the device in an unconfigured
+ * state
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist
+ * \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ * \see libusb_set_auto_detach_kernel_driver()
+ */
+int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev_handle,
+ int configuration)
+{
+ usbi_dbg("configuration %d", configuration);
+ return usbi_backend.set_configuration(dev_handle, configuration);
+}
+
+/** \ingroup libusb_dev
+ * Claim an interface on a given device handle. You must claim the interface
+ * you wish to use before you can perform I/O on any of its endpoints.
+ *
+ * It is legal to attempt to claim an already-claimed interface, in which
+ * case libusb just returns 0 without doing anything.
+ *
+ * If auto_detach_kernel_driver is set to 1 for <tt>dev</tt>, the kernel driver
+ * will be detached if necessary, on failure the detach error is returned.
+ *
+ * Claiming of interfaces is a purely logical operation; it does not cause
+ * any requests to be sent over the bus. Interface claiming is used to
+ * instruct the underlying operating system that your application wishes
+ * to take ownership of the interface.
+ *
+ * This is a non-blocking function.
+ *
+ * \param dev_handle a device handle
+ * \param interface_number the <tt>bInterfaceNumber</tt> of the interface you
+ * wish to claim
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the requested interface does not exist
+ * \returns LIBUSB_ERROR_BUSY if another program or driver has claimed the
+ * interface
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns a LIBUSB_ERROR code on other failure
+ * \see libusb_set_auto_detach_kernel_driver()
+ */
+int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle,
+ int interface_number)
+{
+ int r = 0;
+
+ usbi_dbg("interface %d", interface_number);
+ if (interface_number >= USB_MAXINTERFACES)
+ return LIBUSB_ERROR_INVALID_PARAM;
+
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ usbi_mutex_lock(&dev_handle->lock);
+ if (dev_handle->claimed_interfaces & (1U << interface_number))
+ goto out;
+
+ r = usbi_backend.claim_interface(dev_handle, interface_number);
+ if (r == 0)
+ dev_handle->claimed_interfaces |= 1U << interface_number;
+
+out:
+ usbi_mutex_unlock(&dev_handle->lock);
+ return r;
+}
+
+/** \ingroup libusb_dev
+ * Release an interface previously claimed with libusb_claim_interface(). You
+ * should release all claimed interfaces before closing a device handle.
+ *
+ * This is a blocking function. A SET_INTERFACE control request will be sent
+ * to the device, resetting interface state to the first alternate setting.
+ *
+ * If auto_detach_kernel_driver is set to 1 for <tt>dev</tt>, the kernel
+ * driver will be re-attached after releasing the interface.
+ *
+ * \param dev_handle a device handle
+ * \param interface_number the <tt>bInterfaceNumber</tt> of the
+ * previously-claimed interface
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ * \see libusb_set_auto_detach_kernel_driver()
+ */
+int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle,
+ int interface_number)
+{
+ int r;
+
+ usbi_dbg("interface %d", interface_number);
+ if (interface_number >= USB_MAXINTERFACES)
+ return LIBUSB_ERROR_INVALID_PARAM;
+
+ usbi_mutex_lock(&dev_handle->lock);
+ if (!(dev_handle->claimed_interfaces & (1U << interface_number))) {
+ r = LIBUSB_ERROR_NOT_FOUND;
+ goto out;
+ }
+
+ r = usbi_backend.release_interface(dev_handle, interface_number);
+ if (r == 0)
+ dev_handle->claimed_interfaces &= ~(1U << interface_number);
+
+out:
+ usbi_mutex_unlock(&dev_handle->lock);
+ return r;
+}
+
+/** \ingroup libusb_dev
+ * Activate an alternate setting for an interface. The interface must have
+ * been previously claimed with libusb_claim_interface().
+ *
+ * You should always use this function rather than formulating your own
+ * SET_INTERFACE control request. This is because the underlying operating
+ * system needs to know when such changes happen.
+ *
+ * This is a blocking function.
+ *
+ * \param dev_handle a device handle
+ * \param interface_number the <tt>bInterfaceNumber</tt> of the
+ * previously-claimed interface
+ * \param alternate_setting the <tt>bAlternateSetting</tt> of the alternate
+ * setting to activate
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed, or the
+ * requested alternate setting does not exist
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_handle,
+ int interface_number, int alternate_setting)
+{
+ usbi_dbg("interface %d altsetting %d",
+ interface_number, alternate_setting);
+ if (interface_number >= USB_MAXINTERFACES)
+ return LIBUSB_ERROR_INVALID_PARAM;
+
+ usbi_mutex_lock(&dev_handle->lock);
+ if (!dev_handle->dev->attached) {
+ usbi_mutex_unlock(&dev_handle->lock);
+ return LIBUSB_ERROR_NO_DEVICE;
+ }
+
+ if (!(dev_handle->claimed_interfaces & (1U << interface_number))) {
+ usbi_mutex_unlock(&dev_handle->lock);
+ return LIBUSB_ERROR_NOT_FOUND;
+ }
+ usbi_mutex_unlock(&dev_handle->lock);
+
+ return usbi_backend.set_interface_altsetting(dev_handle, interface_number,
+ alternate_setting);
+}
+
+/** \ingroup libusb_dev
+ * Clear the halt/stall condition for an endpoint. Endpoints with halt status
+ * are unable to receive or transmit data until the halt condition is stalled.
+ *
+ * You should cancel all pending transfers before attempting to clear the halt
+ * condition.
+ *
+ * This is a blocking function.
+ *
+ * \param dev_handle a device handle
+ * \param endpoint the endpoint to clear halt status
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev_handle,
+ unsigned char endpoint)
+{
+ usbi_dbg("endpoint %x", endpoint);
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ return usbi_backend.clear_halt(dev_handle, endpoint);
+}
+
+/** \ingroup libusb_dev
+ * Perform a USB port reset to reinitialize a device. The system will attempt
+ * to restore the previous configuration and alternate settings after the
+ * reset has completed.
+ *
+ * If the reset fails, the descriptors change, or the previous state cannot be
+ * restored, the device will appear to be disconnected and reconnected. This
+ * means that the device handle is no longer valid (you should close it) and
+ * rediscover the device. A return code of LIBUSB_ERROR_NOT_FOUND indicates
+ * when this is the case.
+ *
+ * This is a blocking function which usually incurs a noticeable delay.
+ *
+ * \param dev_handle a handle of the device to reset
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the
+ * device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle)
+{
+ usbi_dbg("");
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ return usbi_backend.reset_device(dev_handle);
+}
+
+/** \ingroup libusb_asyncio
+ * Allocate up to num_streams usb bulk streams on the specified endpoints. This
+ * function takes an array of endpoints rather then a single endpoint because
+ * some protocols require that endpoints are setup with similar stream ids.
+ * All endpoints passed in must belong to the same interface.
+ *
+ * Note this function may return less streams then requested. Also note that the
+ * same number of streams are allocated for each endpoint in the endpoint array.
+ *
+ * Stream id 0 is reserved, and should not be used to communicate with devices.
+ * If libusb_alloc_streams() returns with a value of N, you may use stream ids
+ * 1 to N.
+ *
+ * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
+ *
+ * \param dev_handle a device handle
+ * \param num_streams number of streams to try to allocate
+ * \param endpoints array of endpoints to allocate streams on
+ * \param num_endpoints length of the endpoints array
+ * \returns number of streams allocated, or a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle,
+ uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
+{
+ usbi_dbg("streams %u eps %d", (unsigned) num_streams, num_endpoints);
+
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ if (usbi_backend.alloc_streams)
+ return usbi_backend.alloc_streams(dev_handle, num_streams, endpoints,
+ num_endpoints);
+ else
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+
+/** \ingroup libusb_asyncio
+ * Free usb bulk streams allocated with libusb_alloc_streams().
+ *
+ * Note streams are automatically free-ed when releasing an interface.
+ *
+ * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
+ *
+ * \param dev_handle a device handle
+ * \param endpoints array of endpoints to free streams on
+ * \param num_endpoints length of the endpoints array
+ * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle,
+ unsigned char *endpoints, int num_endpoints)
+{
+ usbi_dbg("eps %d", num_endpoints);
+
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ if (usbi_backend.free_streams)
+ return usbi_backend.free_streams(dev_handle, endpoints,
+ num_endpoints);
+ else
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+
+/** \ingroup libusb_asyncio
+ * Attempts to allocate a block of persistent DMA memory suitable for transfers
+ * against the given device. If successful, will return a block of memory
+ * that is suitable for use as "buffer" in \ref libusb_transfer against this
+ * device. Using this memory instead of regular memory means that the host
+ * controller can use DMA directly into the buffer to increase performance, and
+ * also that transfers can no longer fail due to kernel memory fragmentation.
+ *
+ * Note that this means you should not modify this memory (or even data on
+ * the same cache lines) when a transfer is in progress, although it is legal
+ * to have several transfers going on within the same memory block.
+ *
+ * Will return NULL on failure. Many systems do not support such zerocopy
+ * and will always return NULL. Memory allocated with this function must be
+ * freed with \ref libusb_dev_mem_free. Specifically, this means that the
+ * flag \ref LIBUSB_TRANSFER_FREE_BUFFER cannot be used to free memory allocated
+ * with this function.
+ *
+ * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105
+ *
+ * \param dev_handle a device handle
+ * \param length size of desired data buffer
+ * \returns a pointer to the newly allocated memory, or NULL on failure
+ */
+DEFAULT_VISIBILITY
+unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle,
+ size_t length)
+{
+ if (!dev_handle->dev->attached)
+ return NULL;
+
+ if (usbi_backend.dev_mem_alloc)
+ return usbi_backend.dev_mem_alloc(dev_handle, length);
+ else
+ return NULL;
+}
+
+/** \ingroup libusb_asyncio
+ * Free device memory allocated with libusb_dev_mem_alloc().
+ *
+ * \param dev_handle a device handle
+ * \param buffer pointer to the previously allocated memory
+ * \param length size of previously allocated memory
+ * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_dev_mem_free(libusb_device_handle *dev_handle,
+ unsigned char *buffer, size_t length)
+{
+ if (usbi_backend.dev_mem_free)
+ return usbi_backend.dev_mem_free(dev_handle, buffer, length);
+ else
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+
+/** \ingroup libusb_dev
+ * Determine if a kernel driver is active on an interface. If a kernel driver
+ * is active, you cannot claim the interface, and libusb will be unable to
+ * perform I/O.
+ *
+ * This functionality is not available on Windows.
+ *
+ * \param dev_handle a device handle
+ * \param interface_number the interface to check
+ * \returns 0 if no kernel driver is active
+ * \returns 1 if a kernel driver is active
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
+ * is not available
+ * \returns another LIBUSB_ERROR code on other failure
+ * \see libusb_detach_kernel_driver()
+ */
+int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle,
+ int interface_number)
+{
+ usbi_dbg("interface %d", interface_number);
+
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ if (usbi_backend.kernel_driver_active)
+ return usbi_backend.kernel_driver_active(dev_handle, interface_number);
+ else
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+
+/** \ingroup libusb_dev
+ * Detach a kernel driver from an interface. If successful, you will then be
+ * able to claim the interface and perform I/O.
+ *
+ * This functionality is not available on Darwin or Windows.
+ *
+ * Note that libusb itself also talks to the device through a special kernel
+ * driver, if this driver is already attached to the device, this call will
+ * not detach it and return LIBUSB_ERROR_NOT_FOUND.
+ *
+ * \param dev_handle a device handle
+ * \param interface_number the interface to detach the driver from
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
+ * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
+ * is not available
+ * \returns another LIBUSB_ERROR code on other failure
+ * \see libusb_kernel_driver_active()
+ */
+int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
+ int interface_number)
+{
+ usbi_dbg("interface %d", interface_number);
+
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ if (usbi_backend.detach_kernel_driver)
+ return usbi_backend.detach_kernel_driver(dev_handle, interface_number);
+ else
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+
+/** \ingroup libusb_dev
+ * Re-attach an interface's kernel driver, which was previously detached
+ * using libusb_detach_kernel_driver(). This call is only effective on
+ * Linux and returns LIBUSB_ERROR_NOT_SUPPORTED on all other platforms.
+ *
+ * This functionality is not available on Darwin or Windows.
+ *
+ * \param dev_handle a device handle
+ * \param interface_number the interface to attach the driver from
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
+ * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
+ * is not available
+ * \returns LIBUSB_ERROR_BUSY if the driver cannot be attached because the
+ * interface is claimed by a program or driver
+ * \returns another LIBUSB_ERROR code on other failure
+ * \see libusb_kernel_driver_active()
+ */
+int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev_handle,
+ int interface_number)
+{
+ usbi_dbg("interface %d", interface_number);
+
+ if (!dev_handle->dev->attached)
+ return LIBUSB_ERROR_NO_DEVICE;
+
+ if (usbi_backend.attach_kernel_driver)
+ return usbi_backend.attach_kernel_driver(dev_handle, interface_number);
+ else
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+
+/** \ingroup libusb_dev
+ * Enable/disable libusb's automatic kernel driver detachment. When this is
+ * enabled libusb will automatically detach the kernel driver on an interface
+ * when claiming the interface, and attach it when releasing the interface.
+ *
+ * Automatic kernel driver detachment is disabled on newly opened device
+ * handles by default.
+ *
+ * On platforms which do not have LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER
+ * this function will return LIBUSB_ERROR_NOT_SUPPORTED, and libusb will
+ * continue as if this function was never called.
+ *
+ * \param dev_handle a device handle
+ * \param enable whether to enable or disable auto kernel driver detachment
+ *
+ * \returns LIBUSB_SUCCESS on success
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
+ * is not available
+ * \see libusb_claim_interface()
+ * \see libusb_release_interface()
+ * \see libusb_set_configuration()
+ */
+int API_EXPORTED libusb_set_auto_detach_kernel_driver(
+ libusb_device_handle *dev_handle, int enable)
+{
+ if (!(usbi_backend.caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER))
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+
+ dev_handle->auto_detach_kernel_driver = enable;
+ return LIBUSB_SUCCESS;
+}
+
+/** \ingroup libusb_lib
+ * \deprecated Use libusb_set_option() instead using the
+ * \ref LIBUSB_OPTION_LOG_LEVEL option.
+ */
+void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level)
+{
+#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
+ USBI_GET_CONTEXT(ctx);
+ if (!ctx->debug_fixed) {
+ level = CLAMP(level, LIBUSB_LOG_LEVEL_NONE, LIBUSB_LOG_LEVEL_DEBUG);
+ ctx->debug = (enum libusb_log_level)level;
+ }
+#else
+ UNUSED(ctx);
+ UNUSED(level);
+#endif
+}
+
+/** \ingroup libusb_lib
+ * Set log handler.
+ *
+ * libusb will redirect its log messages to the provided callback function.
+ * libusb supports redirection of per context and global log messages.
+ * Log messages sent to the context will be sent to the global log handler too.
+ *
+ * If libusb is compiled without message logging or USE_SYSTEM_LOGGING_FACILITY
+ * is defined then global callback function will never be called.
+ * If ENABLE_DEBUG_LOGGING is defined then per context callback function will
+ * never be called.
+ *
+ * \param ctx context on which to assign log handler, or NULL for the default
+ * context. Parameter ignored if only LIBUSB_LOG_CB_GLOBAL mode is requested.
+ * \param cb pointer to the callback function, or NULL to stop log
+ * messages redirection
+ * \param mode mode of callback function operation. Several modes can be
+ * selected for a single callback function, see \ref libusb_log_cb_mode for
+ * a description.
+ * \see libusb_log_cb, libusb_log_cb_mode
+ */
+void API_EXPORTED libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb,
+ int mode)
+{
+#if !defined(USE_SYSTEM_LOGGING_FACILITY)
+ if (mode & LIBUSB_LOG_CB_GLOBAL) {
+ log_handler = cb;
+ }
+#endif
+#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
+ if (mode & LIBUSB_LOG_CB_CONTEXT) {
+ USBI_GET_CONTEXT(ctx);
+ ctx->log_handler = cb;
+ }
+#else
+ UNUSED(ctx);
+#if defined(USE_SYSTEM_LOGGING_FACILITY)
+ UNUSED(cb);
+ UNUSED(mode);
+#endif
+#endif
+}
+
+/** \ingroup libusb_lib
+ * Set an option in the library.
+ *
+ * Use this function to configure a specific option within the library.
+ *
+ * Some options require one or more arguments to be provided. Consult each
+ * option's documentation for specific requirements.
+ *
+ * Since version 1.0.22, \ref LIBUSB_API_VERSION >= 0x01000106
+ *
+ * \param ctx context on which to operate
+ * \param option which option to set
+ * \param ... any required arguments for the specified option
+ *
+ * \returns LIBUSB_SUCCESS on success
+ * \returns LIBUSB_ERROR_INVALID_PARAM if the option or arguments are invalid
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED if the option is valid but not supported
+ * on this platform
+ */
+int API_EXPORTED libusb_set_option(libusb_context *ctx,
+ enum libusb_option option, ...)
+{
+ int arg, r = LIBUSB_SUCCESS;
+ va_list ap;
+
+ USBI_GET_CONTEXT(ctx);
+
+ va_start(ap, option);
+ switch (option) {
+ case LIBUSB_OPTION_LOG_LEVEL:
+ arg = va_arg(ap, int);
+ if (arg < LIBUSB_LOG_LEVEL_NONE || arg > LIBUSB_LOG_LEVEL_DEBUG) {
+ r = LIBUSB_ERROR_INVALID_PARAM;
+ break;
+ }
+#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
+ if (!ctx->debug_fixed)
+ ctx->debug = (enum libusb_log_level)arg;
+#endif
+ break;
+
+ /* Handle all backend-specific options here */
+ case LIBUSB_OPTION_USE_USBDK:
+ if (usbi_backend.set_option)
+ r = usbi_backend.set_option(ctx, option, ap);
+ else
+ r = LIBUSB_ERROR_NOT_SUPPORTED;
+ break;
+
+ default:
+ r = LIBUSB_ERROR_INVALID_PARAM;
+ }
+ va_end(ap);
+
+ return r;
+}
+
+#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
+/* returns the log level as defined in the LIBUSB_DEBUG environment variable.
+ * if LIBUSB_DEBUG is not present or not a number, returns LIBUSB_LOG_LEVEL_NONE.
+ * value is clamped to ensure it is within the valid range of possibilities.
+ */
+static enum libusb_log_level get_env_debug_level(void)
+{
+ const char *dbg = getenv("LIBUSB_DEBUG");
+ enum libusb_log_level level;
+ if (dbg) {
+ int dbg_level = atoi(dbg);
+ dbg_level = CLAMP(dbg_level, LIBUSB_LOG_LEVEL_NONE, LIBUSB_LOG_LEVEL_DEBUG);
+ level = (enum libusb_log_level)dbg_level;
+ } else {
+ level = LIBUSB_LOG_LEVEL_NONE;
+ }
+ return level;
+}
+#endif
+
+/** \ingroup libusb_lib
+ * Initialize libusb. This function must be called before calling any other
+ * libusb function.
+ *
+ * If you do not provide an output location for a context pointer, a default
+ * context will be created. If there was already a default context, it will
+ * be reused (and nothing will be initialized/reinitialized).
+ *
+ * \param context Optional output location for context pointer.
+ * Only valid on return code 0.
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
+ * \see libusb_contexts
+ */
+int API_EXPORTED libusb_init(libusb_context **context)
+{
+ struct libusb_device *dev, *next;
+ size_t priv_size = usbi_backend.context_priv_size;
+ struct libusb_context *ctx;
+ static int first_init = 1;
+ int r = 0;
+
+ usbi_mutex_static_lock(&default_context_lock);
+
+ if (!timestamp_origin.tv_sec) {
+ usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, ×tamp_origin);
+ }
+
+ if (!context && usbi_default_context) {
+ usbi_dbg("reusing default context");
+ default_context_refcnt++;
+ usbi_mutex_static_unlock(&default_context_lock);
+ return 0;
+ }
+
+ ctx = calloc(1, sizeof(*ctx) + priv_size);
+ if (!ctx) {
+ r = LIBUSB_ERROR_NO_MEM;
+ goto err_unlock;
+ }
+
+#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
+ ctx->debug = get_env_debug_level();
+ if (ctx->debug != LIBUSB_LOG_LEVEL_NONE)
+ ctx->debug_fixed = 1;
+#endif
+
+ /* default context should be initialized before calling usbi_dbg */
+ if (!usbi_default_context) {
+ usbi_default_context = ctx;
+ default_context_refcnt++;
+ usbi_dbg("created default context");
+ }
+
+ 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.rc);
+
+ usbi_mutex_init(&ctx->usb_devs_lock);
+ usbi_mutex_init(&ctx->open_devs_lock);
+ usbi_mutex_init(&ctx->hotplug_cbs_lock);
+ list_init(&ctx->usb_devs);
+ list_init(&ctx->open_devs);
+ list_init(&ctx->hotplug_cbs);
+ ctx->next_hotplug_cb_handle = 1;
+
+ usbi_mutex_static_lock(&active_contexts_lock);
+ if (first_init) {
+ first_init = 0;
+ list_init (&active_contexts_list);
+ }
+ list_add (&ctx->list, &active_contexts_list);
+ usbi_mutex_static_unlock(&active_contexts_lock);
+
+ if (usbi_backend.init) {
+ r = usbi_backend.init(ctx);
+ if (r)
+ goto err_free_ctx;
+ }
+
+ r = usbi_io_init(ctx);
+ if (r < 0)
+ goto err_backend_exit;
+
+ usbi_mutex_static_unlock(&default_context_lock);
+
+ if (context)
+ *context = ctx;
+
+ return 0;
+
+err_backend_exit:
+ if (usbi_backend.exit)
+ usbi_backend.exit(ctx);
+err_free_ctx:
+ if (ctx == usbi_default_context) {
+ usbi_default_context = NULL;
+ default_context_refcnt--;
+ }
+
+ usbi_mutex_static_lock(&active_contexts_lock);
+ list_del (&ctx->list);
+ usbi_mutex_static_unlock(&active_contexts_lock);
+
+ usbi_mutex_lock(&ctx->usb_devs_lock);
+ list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
+ list_del(&dev->list);
+ libusb_unref_device(dev);
+ }
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
+
+ usbi_mutex_destroy(&ctx->open_devs_lock);
+ usbi_mutex_destroy(&ctx->usb_devs_lock);
+ usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
+
+ free(ctx);
+err_unlock:
+ usbi_mutex_static_unlock(&default_context_lock);
+ return r;
+}
+
+/** \ingroup libusb_lib
+ * Deinitialize libusb. Should be called after closing all open devices and
+ * before your application terminates.
+ * \param ctx the context to deinitialize, or NULL for the default context
+ */
+void API_EXPORTED libusb_exit(struct libusb_context *ctx)
+{
+ struct libusb_device *dev, *next;
+ struct timeval tv = { 0, 0 };
+ int destroying_default_context = 0;
+
+ usbi_dbg("");
+ USBI_GET_CONTEXT(ctx);
+
+ /* if working with default context, only actually do the deinitialization
+ * if we're the last user */
+ usbi_mutex_static_lock(&default_context_lock);
+ if (ctx == usbi_default_context) {
+ if (--default_context_refcnt > 0) {
+ usbi_dbg("not destroying default context");
+ usbi_mutex_static_unlock(&default_context_lock);
+ return;
+ }
+ usbi_dbg("destroying default context");
+
+ /*
+ * Setting this flag without unlocking the default context, as
+ * we are actually destroying the default context.
+ * usbi_default_context is not set to NULL yet, as all activities
+ * would only stop after usbi_backend->exit() returns.
+ */
+ destroying_default_context = 1;
+ } else {
+ // Unlock default context, as we're not modifying it.
+ usbi_mutex_static_unlock(&default_context_lock);
+ }
+
+ usbi_mutex_static_lock(&active_contexts_lock);
+ list_del (&ctx->list);
+ usbi_mutex_static_unlock(&active_contexts_lock);
+
+ if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
+ usbi_hotplug_deregister(ctx, 1);
+
+ /*
+ * Ensure any pending unplug events are read from the hotplug
+ * pipe. The usb_device-s hold in the events are no longer part
+ * of usb_devs, but the events still hold a reference!
+ *
+ * Note we don't do this if the application has left devices
+ * open (which implies a buggy app) to avoid packet completion
+ * handlers running when the app does not expect them to run.
+ */
+ if (list_empty(&ctx->open_devs))
+ libusb_handle_events_timeout(ctx, &tv);
+
+ usbi_mutex_lock(&ctx->usb_devs_lock);
+ list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
+ list_del(&dev->list);
+ libusb_unref_device(dev);
+ }
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
+ }
+
+ /* a few sanity checks. don't bother with locking because unless
+ * there is an application bug, nobody will be accessing these. */
+ if (!list_empty(&ctx->usb_devs))
+ usbi_warn(ctx, "some libusb_devices were leaked");
+ if (!list_empty(&ctx->open_devs))
+ usbi_warn(ctx, "application left some devices open");
+
+ usbi_io_exit(ctx);
+ if (usbi_backend.exit)
+ usbi_backend.exit(ctx);
+
+ usbi_mutex_destroy(&ctx->open_devs_lock);
+ usbi_mutex_destroy(&ctx->usb_devs_lock);
+ usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
+ free(ctx);
+
+ if (destroying_default_context) {
+ usbi_default_context = NULL;
+ usbi_mutex_static_unlock(&default_context_lock);
+ }
+}
+
+/** \ingroup libusb_misc
+ * Check at runtime if the loaded library has a given capability.
+ * This call should be performed after \ref libusb_init(), to ensure the
+ * backend has updated its capability set.
+ *
+ * \param capability the \ref libusb_capability to check for
+ * \returns nonzero if the running library has the capability, 0 otherwise
+ */
+int API_EXPORTED libusb_has_capability(uint32_t capability)
+{
+ switch (capability) {
+ case LIBUSB_CAP_HAS_CAPABILITY:
+ return 1;
+ case LIBUSB_CAP_HAS_HOTPLUG:
+ return !(usbi_backend.get_device_list);
+ case LIBUSB_CAP_HAS_HID_ACCESS:
+ return (usbi_backend.caps & USBI_CAP_HAS_HID_ACCESS);
+ case LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER:
+ return (usbi_backend.caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER);
+ }
+ return 0;
+}
+
+#ifdef ENABLE_LOGGING
+
+/* this is defined in libusbi.h if needed */
+#ifdef LIBUSB_PRINTF_WIN32
+/*
+ * Prior to VS2015, Microsoft did not provide the snprintf() function and
+ * provided a vsnprintf() that did not guarantee NULL-terminated output.
+ * Microsoft did provide a _snprintf() function, but again it did not
+ * guarantee NULL-terminated output.
+ *
+ * The below implementations guarantee NULL-terminated output and are
+ * C99 compliant.
+ */
+
+int usbi_snprintf(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = usbi_vsnprintf(str, size, format, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+int usbi_vsnprintf(char *str, size_t size, const char *format, va_list ap)
+{
+ int ret;
+
+ ret = _vsnprintf(str, size, format, ap);
+ if (ret < 0 || ret == (int)size) {
+ /* Output is truncated, ensure buffer is NULL-terminated and
+ * determine how many characters would have been written. */
+ str[size - 1] = '\0';
+ if (ret < 0)
+ ret = _vsnprintf(NULL, 0, format, ap);
+ }
+
+ return ret;
+}
+#endif /* LIBUSB_PRINTF_WIN32 */
+
+static void usbi_log_str(enum libusb_log_level level, const char *str)
+{
+#if defined(USE_SYSTEM_LOGGING_FACILITY)
+#if defined(OS_WINDOWS) || defined(OS_WINCE)
+#if !defined(UNICODE)
+ OutputDebugStringA(str);
+#else
+ WCHAR wbuf[USBI_MAX_LOG_LEN];
+ if (MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf)) != 0)
+ OutputDebugStringW(wbuf);
+#endif
+#elif defined(__ANDROID__)
+ int priority = ANDROID_LOG_UNKNOWN;
+ switch (level) {
+ case LIBUSB_LOG_LEVEL_NONE: return;
+ case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break;
+ case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break;
+ case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break;
+ case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break;
+ }
+ __android_log_write(priority, "libusb", str);
+#elif defined(HAVE_SYSLOG_FUNC)
+ int syslog_level = LOG_INFO;
+ switch (level) {
+ case LIBUSB_LOG_LEVEL_NONE: return;
+ case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break;
+ case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break;
+ case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break;
+ case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break;
+ }
+ syslog(syslog_level, "%s", str);
+#else /* All of gcc, Clang, Xcode seem to use #warning */
+#warning System logging is not supported on this platform. Logging to stderr will be used instead.
+ fputs(str, stderr);
+#endif
+#else
+ /* Global log handler */
+ if (log_handler != NULL)
+ log_handler(NULL, level, str);
+ else
+ fputs(str, stderr);
+#endif /* USE_SYSTEM_LOGGING_FACILITY */
+ UNUSED(level);
+}
+
+void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
+ const char *function, const char *format, va_list args)
+{
+ const char *prefix;
+ char buf[USBI_MAX_LOG_LEN];
+ struct timespec now;
+ int global_debug, header_len, text_len;
+ static int has_debug_header_been_displayed = 0;
+
+#ifdef ENABLE_DEBUG_LOGGING
+ global_debug = 1;
+ UNUSED(ctx);
+#else
+ enum libusb_log_level ctx_level = LIBUSB_LOG_LEVEL_NONE;
+
+ USBI_GET_CONTEXT(ctx);
+ if (ctx)
+ ctx_level = ctx->debug;
+ else
+ ctx_level = get_env_debug_level();
+
+ if (ctx_level == LIBUSB_LOG_LEVEL_NONE)
+ return;
+ if (level == LIBUSB_LOG_LEVEL_WARNING && ctx_level < LIBUSB_LOG_LEVEL_WARNING)
+ return;
+ if (level == LIBUSB_LOG_LEVEL_INFO && ctx_level < LIBUSB_LOG_LEVEL_INFO)
+ return;
+ if (level == LIBUSB_LOG_LEVEL_DEBUG && ctx_level < LIBUSB_LOG_LEVEL_DEBUG)
+ return;
+
+ global_debug = (ctx_level == LIBUSB_LOG_LEVEL_DEBUG);
+#endif
+
+ usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &now);
+ if ((global_debug) && (!has_debug_header_been_displayed)) {
+ has_debug_header_been_displayed = 1;
+ usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>" USBI_LOG_LINE_END);
+ usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END);
+ }
+ if (now.tv_nsec < timestamp_origin.tv_nsec) {
+ now.tv_sec--;
+ now.tv_nsec += 1000000000L;
+ }
+ now.tv_sec -= timestamp_origin.tv_sec;
+ now.tv_nsec -= timestamp_origin.tv_nsec;
+
+ switch (level) {
+ case LIBUSB_LOG_LEVEL_NONE:
+ return;
+ case LIBUSB_LOG_LEVEL_ERROR:
+ prefix = "error";
+ break;
+ case LIBUSB_LOG_LEVEL_WARNING:
+ prefix = "warning";
+ break;
+ case LIBUSB_LOG_LEVEL_INFO:
+ prefix = "info";
+ break;
+ case LIBUSB_LOG_LEVEL_DEBUG:
+ prefix = "debug";
+ break;
+ default:
+ prefix = "unknown";
+ break;
+ }
+
+ if (global_debug) {
+ header_len = snprintf(buf, sizeof(buf),
+ "[%2ld.%06ld] [%08x] libusb: %s [%s] ",
+ (long)now.tv_sec, (long)(now.tv_nsec / 1000L), usbi_get_tid(), prefix, function);
+ } else {
+ header_len = snprintf(buf, sizeof(buf),
+ "libusb: %s [%s] ", prefix, function);
+ }
+
+ if (header_len < 0 || header_len >= (int)sizeof(buf)) {
+ /* Somehow snprintf failed to write to the buffer,
+ * remove the header so something useful is output. */
+ header_len = 0;
+ }
+ /* Make sure buffer is NUL terminated */
+ buf[header_len] = '\0';
+ text_len = vsnprintf(buf + header_len, sizeof(buf) - (size_t)header_len,
+ format, args);
+ if (text_len < 0 || text_len + header_len >= (int)sizeof(buf)) {
+ /* Truncated log output. On some platforms a -1 return value means
+ * that the output was truncated. */
+ text_len = (int)sizeof(buf) - header_len;
+ }
+ if (header_len + text_len + (int)sizeof(USBI_LOG_LINE_END) >= (int)sizeof(buf)) {
+ /* Need to truncate the text slightly to fit on the terminator. */
+ text_len -= (header_len + text_len + (int)sizeof(USBI_LOG_LINE_END)) - (int)sizeof(buf);
+ }
+ strcpy(buf + header_len + text_len, USBI_LOG_LINE_END);
+
+ usbi_log_str(level, buf);
+
+ /* Per context log handler */
+#ifndef ENABLE_DEBUG_LOGGING
+ if (ctx && ctx->log_handler)
+ ctx->log_handler(ctx, level, buf);
+#endif
+}
+
+void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
+ const char *function, const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ usbi_log_v(ctx, level, function, format, args);
+ va_end (args);
+}
+
+#endif /* ENABLE_LOGGING */
+
+/** \ingroup libusb_misc
+ * Returns a constant NULL-terminated string with the ASCII name of a libusb
+ * error or transfer status code. The caller must not free() the returned
+ * string.
+ *
+ * \param error_code The \ref libusb_error or libusb_transfer_status code to
+ * return the name of.
+ * \returns The error name, or the string **UNKNOWN** if the value of
+ * error_code is not a known error / status code.
+ */
+DEFAULT_VISIBILITY const char * LIBUSB_CALL libusb_error_name(int error_code)
+{
+ switch (error_code) {
+ case LIBUSB_ERROR_IO:
+ return "LIBUSB_ERROR_IO";
+ case LIBUSB_ERROR_INVALID_PARAM:
+ return "LIBUSB_ERROR_INVALID_PARAM";
+ case LIBUSB_ERROR_ACCESS:
+ return "LIBUSB_ERROR_ACCESS";
+ case LIBUSB_ERROR_NO_DEVICE:
+ return "LIBUSB_ERROR_NO_DEVICE";
+ case LIBUSB_ERROR_NOT_FOUND:
+ return "LIBUSB_ERROR_NOT_FOUND";
+ case LIBUSB_ERROR_BUSY:
+ return "LIBUSB_ERROR_BUSY";
+ case LIBUSB_ERROR_TIMEOUT:
+ return "LIBUSB_ERROR_TIMEOUT";
+ case LIBUSB_ERROR_OVERFLOW:
+ return "LIBUSB_ERROR_OVERFLOW";
+ case LIBUSB_ERROR_PIPE:
+ return "LIBUSB_ERROR_PIPE";
+ case LIBUSB_ERROR_INTERRUPTED:
+ return "LIBUSB_ERROR_INTERRUPTED";
+ case LIBUSB_ERROR_NO_MEM:
+ return "LIBUSB_ERROR_NO_MEM";
+ case LIBUSB_ERROR_NOT_SUPPORTED:
+ return "LIBUSB_ERROR_NOT_SUPPORTED";
+ case LIBUSB_ERROR_OTHER:
+ return "LIBUSB_ERROR_OTHER";
+
+ case LIBUSB_TRANSFER_ERROR:
+ return "LIBUSB_TRANSFER_ERROR";
+ case LIBUSB_TRANSFER_TIMED_OUT:
+ return "LIBUSB_TRANSFER_TIMED_OUT";
+ case LIBUSB_TRANSFER_CANCELLED:
+ return "LIBUSB_TRANSFER_CANCELLED";
+ case LIBUSB_TRANSFER_STALL:
+ return "LIBUSB_TRANSFER_STALL";
+ case LIBUSB_TRANSFER_NO_DEVICE:
+ return "LIBUSB_TRANSFER_NO_DEVICE";
+ case LIBUSB_TRANSFER_OVERFLOW:
+ return "LIBUSB_TRANSFER_OVERFLOW";
+
+ case 0:
+ return "LIBUSB_SUCCESS / LIBUSB_TRANSFER_COMPLETED";
+ default:
+ return "**UNKNOWN**";
+ }
+}
+
+/** \ingroup libusb_misc
+ * Returns a pointer to const struct libusb_version with the version
+ * (major, minor, micro, nano and rc) of the running library.
+ */
+DEFAULT_VISIBILITY
+const struct libusb_version * LIBUSB_CALL libusb_get_version(void)
+{
+ return &libusb_version_internal;
+}
diff --git a/libusb1/darwin/config.h b/libusb1/darwin/config.h
new file mode 100644
index 0000000..14d1527
--- /dev/null
+++ b/libusb1/darwin/config.h
@@ -0,0 +1,25 @@
+/* config.h. Manually generated for Xcode. */
+
+/* Default visibility */
+#define DEFAULT_VISIBILITY /**/
+
+/* Message logging */
+#define ENABLE_LOGGING 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Darwin backend */
+#define OS_DARWIN 1
+
+/* type of second poll() argument */
+#define POLL_NFDS_TYPE nfds_t
+
+/* Use POSIX Threads */
+#define THREADS_POSIX 1
+
+/* Use GNU extensions */
+#define _GNU_SOURCE 1
diff --git a/libusb1/descriptor.c b/libusb1/descriptor.c
new file mode 100644
index 0000000..53905e6
--- /dev/null
+++ b/libusb1/descriptor.c
@@ -0,0 +1,1193 @@
+/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
+/*
+ * USB descriptor handling functions for libusb
+ * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
+ * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libusbi.h"
+
+#define DESC_HEADER_LENGTH 2
+#define DEVICE_DESC_LENGTH 18
+#define CONFIG_DESC_LENGTH 9
+#define INTERFACE_DESC_LENGTH 9
+#define ENDPOINT_DESC_LENGTH 7
+#define ENDPOINT_AUDIO_DESC_LENGTH 9
+
+/** @defgroup libusb_desc USB descriptors
+ * This page details how to examine the various standard USB descriptors
+ * for detected devices
+ */
+
+/* set host_endian if the w values are already in host endian format,
+ * as opposed to bus endian. */
+int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
+ void *dest, int host_endian)
+{
+ const unsigned char *sp = source;
+ unsigned char *dp = dest;
+ uint16_t w;
+ const char *cp;
+ uint32_t d;
+
+ for (cp = descriptor; *cp; cp++) {
+ switch (*cp) {
+ case 'b': /* 8-bit byte */
+ *dp++ = *sp++;
+ break;
+ case 'w': /* 16-bit word, convert from little endian to CPU */
+ dp += ((uintptr_t)dp & 1); /* Align to word boundary */
+
+ if (host_endian) {
+ memcpy(dp, sp, 2);
+ } else {
+ w = (uint16_t)((sp[1] << 8) | sp[0]);
+ *((uint16_t *)dp) = w;
+ }
+ sp += 2;
+ dp += 2;
+ break;
+ case 'd': /* 32-bit word, convert from little endian to CPU */
+ dp += ((uintptr_t)dp & 1); /* Align to word boundary */
+
+ if (host_endian) {
+ memcpy(dp, sp, 4);
+ } else {
+ d = (uint32_t)((sp[3] << 24) | (sp[2] << 16) |
+ (sp[1] << 8) | sp[0]);
+ *((uint32_t *)dp) = d;
+ }
+ sp += 4;
+ dp += 4;
+ break;
+ case 'u': /* 16 byte UUID */
+ memcpy(dp, sp, 16);
+ sp += 16;
+ dp += 16;
+ break;
+ }
+ }
+
+ return (int) (sp - source);
+}
+
+static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
+{
+ free((void *) endpoint->extra);
+}
+
+static int parse_endpoint(struct libusb_context *ctx,
+ struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
+ int size, int host_endian)
+{
+ struct usb_descriptor_header header;
+ unsigned char *extra;
+ unsigned char *begin;
+ int parsed = 0;
+ int len;
+
+ if (size < DESC_HEADER_LENGTH) {
+ usbi_err(ctx, "short endpoint descriptor read %d/%d",
+ size, DESC_HEADER_LENGTH);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usbi_parse_descriptor(buffer, "bb", &header, 0);
+ if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
+ usbi_err(ctx, "unexpected descriptor %x (expected %x)",
+ header.bDescriptorType, LIBUSB_DT_ENDPOINT);
+ return parsed;
+ }
+ if (header.bLength > size) {
+ usbi_warn(ctx, "short endpoint descriptor read %d/%d",
+ size, header.bLength);
+ return parsed;
+ }
+ if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
+ usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
+ else if (header.bLength >= ENDPOINT_DESC_LENGTH)
+ usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
+ else {
+ usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength);
+ return LIBUSB_ERROR_IO;
+ }
+
+ buffer += header.bLength;
+ size -= header.bLength;
+ parsed += header.bLength;
+
+ /* Skip over the rest of the Class Specific or Vendor Specific */
+ /* descriptors */
+ begin = buffer;
+ while (size >= DESC_HEADER_LENGTH) {
+ usbi_parse_descriptor(buffer, "bb", &header, 0);
+ if (header.bLength < DESC_HEADER_LENGTH) {
+ usbi_err(ctx, "invalid extra ep desc len (%d)",
+ header.bLength);
+ return LIBUSB_ERROR_IO;
+ } else if (header.bLength > size) {
+ usbi_warn(ctx, "short extra ep desc read %d/%d",
+ size, header.bLength);
+ return parsed;
+ }
+
+ /* If we find another "proper" descriptor then we're done */
+ if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
+ (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
+ (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
+ (header.bDescriptorType == LIBUSB_DT_DEVICE))
+ break;
+
+ usbi_dbg("skipping descriptor %x", header.bDescriptorType);
+ buffer += header.bLength;
+ size -= header.bLength;
+ parsed += header.bLength;
+ }
+
+ /* Copy any unknown descriptors into a storage area for drivers */
+ /* to later parse */
+ len = (int)(buffer - begin);
+ if (len <= 0) {
+ endpoint->extra = NULL;
+ endpoint->extra_length = 0;
+ return parsed;
+ }
+
+ extra = malloc((size_t)len);
+ endpoint->extra = extra;
+ if (!extra) {
+ endpoint->extra_length = 0;
+ return LIBUSB_ERROR_NO_MEM;
+ }
+
+ memcpy(extra, begin, len);
+ endpoint->extra_length = len;
+
+ return parsed;
+}
+
+static void clear_interface(struct libusb_interface *usb_interface)
+{
+ int i;
+ int j;
+
+ if (usb_interface->altsetting) {
+ for (i = 0; i < usb_interface->num_altsetting; i++) {
+ struct libusb_interface_descriptor *ifp =
+ (struct libusb_interface_descriptor *)
+ usb_interface->altsetting + i;
+ free((void *) ifp->extra);
+ if (ifp->endpoint) {
+ for (j = 0; j < ifp->bNumEndpoints; j++)
+ clear_endpoint((struct libusb_endpoint_descriptor *)
+ ifp->endpoint + j);
+ }
+ free((void *) ifp->endpoint);
+ }
+ }
+ free((void *) usb_interface->altsetting);
+ usb_interface->altsetting = NULL;
+}
+
+static int parse_interface(libusb_context *ctx,
+ struct libusb_interface *usb_interface, unsigned char *buffer, int size,
+ int host_endian)
+{
+ int i;
+ int len;
+ int r;
+ int parsed = 0;
+ int interface_number = -1;
+ struct usb_descriptor_header header;
+ struct libusb_interface_descriptor *ifp;
+ unsigned char *begin;
+
+ usb_interface->num_altsetting = 0;
+
+ while (size >= INTERFACE_DESC_LENGTH) {
+ struct libusb_interface_descriptor *altsetting =
+ (struct libusb_interface_descriptor *) usb_interface->altsetting;
+ altsetting = usbi_reallocf(altsetting,
+ sizeof(struct libusb_interface_descriptor) *
+ ((size_t)usb_interface->num_altsetting + 1));
+ if (!altsetting) {
+ r = LIBUSB_ERROR_NO_MEM;
+ goto err;
+ }
+ usb_interface->altsetting = altsetting;
+
+ ifp = altsetting + usb_interface->num_altsetting;
+ usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
+ if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
+ usbi_err(ctx, "unexpected descriptor %x (expected %x)",
+ ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
+ return parsed;
+ }
+ if (ifp->bLength < INTERFACE_DESC_LENGTH) {
+ usbi_err(ctx, "invalid interface bLength (%d)",
+ ifp->bLength);
+ r = LIBUSB_ERROR_IO;
+ goto err;
+ }
+ if (ifp->bLength > size) {
+ usbi_warn(ctx, "short intf descriptor read %d/%d",
+ size, ifp->bLength);
+ return parsed;
+ }
+ if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
+ usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
+ r = LIBUSB_ERROR_IO;
+ goto err;
+ }
+
+ usb_interface->num_altsetting++;
+ ifp->extra = NULL;
+ ifp->extra_length = 0;
+ ifp->endpoint = NULL;
+
+ if (interface_number == -1)
+ interface_number = ifp->bInterfaceNumber;
+
+ /* Skip over the interface */
+ buffer += ifp->bLength;
+ parsed += ifp->bLength;
+ size -= ifp->bLength;
+
+ begin = buffer;
+
+ /* Skip over any interface, class or vendor descriptors */
+ while (size >= DESC_HEADER_LENGTH) {
+ usbi_parse_descriptor(buffer, "bb", &header, 0);
+ if (header.bLength < DESC_HEADER_LENGTH) {
+ usbi_err(ctx,
+ "invalid extra intf desc len (%d)",
+ header.bLength);
+ r = LIBUSB_ERROR_IO;
+ goto err;
+ } else if (header.bLength > size) {
+ usbi_warn(ctx,
+ "short extra intf desc read %d/%d",
+ size, header.bLength);
+ return parsed;
+ }
+
+ /* If we find another "proper" descriptor then we're done */
+ if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
+ (header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
+ (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
+ (header.bDescriptorType == LIBUSB_DT_DEVICE))
+ break;
+
+ buffer += header.bLength;
+ parsed += header.bLength;
+ size -= header.bLength;
+ }
+
+ /* Copy any unknown descriptors into a storage area for */
+ /* drivers to later parse */
+ len = (int)(buffer - begin);
+ if (len > 0) {
+ ifp->extra = malloc((size_t)len);
+ if (!ifp->extra) {
+ r = LIBUSB_ERROR_NO_MEM;
+ goto err;
+ }
+ memcpy((unsigned char *) ifp->extra, begin, len);
+ ifp->extra_length = len;
+ }
+
+ if (ifp->bNumEndpoints > 0) {
+ struct libusb_endpoint_descriptor *endpoint;
+ endpoint = calloc(ifp->bNumEndpoints, sizeof(struct libusb_endpoint_descriptor));
+ ifp->endpoint = endpoint;
+ if (!endpoint) {
+ r = LIBUSB_ERROR_NO_MEM;
+ goto err;
+ }
+
+ for (i = 0; i < ifp->bNumEndpoints; i++) {
+ r = parse_endpoint(ctx, endpoint + i, buffer, size,
+ host_endian);
+ if (r < 0)
+ goto err;
+ if (r == 0) {
+ ifp->bNumEndpoints = (uint8_t)i;
+ break;
+ }
+
+ buffer += r;
+ parsed += r;
+ size -= r;
+ }
+ }
+
+ /* We check to see if it's an alternate to this one */
+ ifp = (struct libusb_interface_descriptor *) buffer;
+ if (size < LIBUSB_DT_INTERFACE_SIZE ||
+ ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
+ ifp->bInterfaceNumber != interface_number)
+ return parsed;
+ }
+
+ return parsed;
+err:
+ clear_interface(usb_interface);
+ return r;
+}
+
+static void clear_configuration(struct libusb_config_descriptor *config)
+{
+ int i;
+ if (config->interface) {
+ for (i = 0; i < config->bNumInterfaces; i++)
+ clear_interface((struct libusb_interface *)
+ config->interface + i);
+ }
+ free((void *) config->interface);
+ free((void *) config->extra);
+}
+
+static int parse_configuration(struct libusb_context *ctx,
+ struct libusb_config_descriptor *config, unsigned char *buffer,
+ int size, int host_endian)
+{
+ int i;
+ int r;
+ struct usb_descriptor_header header;
+ struct libusb_interface *usb_interface;
+
+ if (size < LIBUSB_DT_CONFIG_SIZE) {
+ usbi_err(ctx, "short config descriptor read %d/%d",
+ size, LIBUSB_DT_CONFIG_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
+ if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
+ usbi_err(ctx, "unexpected descriptor %x (expected %x)",
+ config->bDescriptorType, LIBUSB_DT_CONFIG);
+ return LIBUSB_ERROR_IO;
+ }
+ if (config->bLength < LIBUSB_DT_CONFIG_SIZE) {
+ usbi_err(ctx, "invalid config bLength (%d)", config->bLength);
+ return LIBUSB_ERROR_IO;
+ }
+ if (config->bLength > size) {
+ usbi_err(ctx, "short config descriptor read %d/%d",
+ size, config->bLength);
+ return LIBUSB_ERROR_IO;
+ }
+ if (config->bNumInterfaces > USB_MAXINTERFACES) {
+ usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usb_interface = calloc(config->bNumInterfaces, sizeof(struct libusb_interface));
+ config->interface = usb_interface;
+ if (!usb_interface)
+ return LIBUSB_ERROR_NO_MEM;
+
+ buffer += config->bLength;
+ size -= config->bLength;
+
+ config->extra = NULL;
+ config->extra_length = 0;
+
+ for (i = 0; i < config->bNumInterfaces; i++) {
+ int len;
+ unsigned char *begin;
+
+ /* Skip over the rest of the Class Specific or Vendor */
+ /* Specific descriptors */
+ begin = buffer;
+ while (size >= DESC_HEADER_LENGTH) {
+ usbi_parse_descriptor(buffer, "bb", &header, 0);
+
+ if (header.bLength < DESC_HEADER_LENGTH) {
+ usbi_err(ctx,
+ "invalid extra config desc len (%d)",
+ header.bLength);
+ r = LIBUSB_ERROR_IO;
+ goto err;
+ } else if (header.bLength > size) {
+ usbi_warn(ctx,
+ "short extra config desc read %d/%d",
+ size, header.bLength);
+ config->bNumInterfaces = (uint8_t)i;
+ return size;
+ }
+
+ /* If we find another "proper" descriptor then we're done */
+ if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
+ (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
+ (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
+ (header.bDescriptorType == LIBUSB_DT_DEVICE))
+ break;
+
+ usbi_dbg("skipping descriptor 0x%x", header.bDescriptorType);
+ buffer += header.bLength;
+ size -= header.bLength;
+ }
+
+ /* Copy any unknown descriptors into a storage area for */
+ /* drivers to later parse */
+ len = (int)(buffer - begin);
+ if (len > 0) {
+ /* FIXME: We should realloc and append here */
+ if (!config->extra_length) {
+ config->extra = malloc((size_t)len);
+ if (!config->extra) {
+ r = LIBUSB_ERROR_NO_MEM;
+ goto err;
+ }
+
+ memcpy((unsigned char *) config->extra, begin, len);
+ config->extra_length = len;
+ }
+ }
+
+ r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian);
+ if (r < 0)
+ goto err;
+ if (r == 0) {
+ config->bNumInterfaces = (uint8_t)i;
+ break;
+ }
+
+ buffer += r;
+ size -= r;
+ }
+
+ return size;
+
+err:
+ clear_configuration(config);
+ return r;
+}
+
+static int raw_desc_to_config(struct libusb_context *ctx,
+ unsigned char *buf, int size, int host_endian,
+ struct libusb_config_descriptor **config)
+{
+ struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
+ int r;
+
+ if (!_config)
+ return LIBUSB_ERROR_NO_MEM;
+
+ r = parse_configuration(ctx, _config, buf, size, host_endian);
+ if (r < 0) {
+ usbi_err(ctx, "parse_configuration failed with error %d", r);
+ free(_config);
+ return r;
+ } else if (r > 0) {
+ usbi_warn(ctx, "still %d bytes of descriptor data left", r);
+ }
+
+ *config = _config;
+ return LIBUSB_SUCCESS;
+}
+
+int usbi_device_cache_descriptor(libusb_device *dev)
+{
+ int r, host_endian = 0;
+
+ r = usbi_backend.get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor,
+ &host_endian);
+ if (r < 0)
+ return r;
+
+ if (!host_endian) {
+ dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB);
+ dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor);
+ dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct);
+ dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice);
+ }
+
+ return LIBUSB_SUCCESS;
+}
+
+/** \ingroup libusb_desc
+ * Get the USB device descriptor for a given device.
+ *
+ * This is a non-blocking function; the device descriptor is cached in memory.
+ *
+ * Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this
+ * function always succeeds.
+ *
+ * \param dev the device
+ * \param desc output location for the descriptor data
+ * \returns 0 on success or a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
+ struct libusb_device_descriptor *desc)
+{
+ usbi_dbg("");
+ memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor,
+ sizeof (dev->device_descriptor));
+ return 0;
+}
+
+/** \ingroup libusb_desc
+ * Get the USB configuration descriptor for the currently active configuration.
+ * This is a non-blocking function which does not involve any requests being
+ * sent to the device.
+ *
+ * \param dev a device
+ * \param config output location for the USB configuration descriptor. Only
+ * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
+ * after use.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
+ * \returns another LIBUSB_ERROR code on error
+ * \see libusb_get_config_descriptor
+ */
+int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
+ struct libusb_config_descriptor **config)
+{
+ struct libusb_config_descriptor _config;
+ unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
+ unsigned char *buf = NULL;
+ int host_endian = 0;
+ int r;
+
+ r = usbi_backend.get_active_config_descriptor(dev, tmp,
+ LIBUSB_DT_CONFIG_SIZE, &host_endian);
+ if (r < 0)
+ return r;
+ if (r < LIBUSB_DT_CONFIG_SIZE) {
+ usbi_err(dev->ctx, "short config descriptor read %d/%d",
+ r, LIBUSB_DT_CONFIG_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
+ buf = malloc(_config.wTotalLength);
+ if (!buf)
+ return LIBUSB_ERROR_NO_MEM;
+
+ r = usbi_backend.get_active_config_descriptor(dev, buf,
+ _config.wTotalLength, &host_endian);
+ if (r >= 0)
+ r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
+
+ free(buf);
+ return r;
+}
+
+/** \ingroup libusb_desc
+ * Get a USB configuration descriptor based on its index.
+ * This is a non-blocking function which does not involve any requests being
+ * sent to the device.
+ *
+ * \param dev a device
+ * \param config_index the index of the configuration you wish to retrieve
+ * \param config output location for the USB configuration descriptor. Only
+ * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
+ * after use.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
+ * \returns another LIBUSB_ERROR code on error
+ * \see libusb_get_active_config_descriptor()
+ * \see libusb_get_config_descriptor_by_value()
+ */
+int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
+ uint8_t config_index, struct libusb_config_descriptor **config)
+{
+ struct libusb_config_descriptor _config;
+ unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
+ unsigned char *buf = NULL;
+ int host_endian = 0;
+ int r;
+
+ usbi_dbg("index %d", config_index);
+ if (config_index >= dev->num_configurations)
+ return LIBUSB_ERROR_NOT_FOUND;
+
+ r = usbi_backend.get_config_descriptor(dev, config_index, tmp,
+ LIBUSB_DT_CONFIG_SIZE, &host_endian);
+ if (r < 0)
+ return r;
+ if (r < LIBUSB_DT_CONFIG_SIZE) {
+ usbi_err(dev->ctx, "short config descriptor read %d/%d",
+ r, LIBUSB_DT_CONFIG_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
+ buf = malloc(_config.wTotalLength);
+ if (!buf)
+ return LIBUSB_ERROR_NO_MEM;
+
+ r = usbi_backend.get_config_descriptor(dev, config_index, buf,
+ _config.wTotalLength, &host_endian);
+ if (r >= 0)
+ r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
+
+ free(buf);
+ return r;
+}
+
+/* iterate through all configurations, returning the index of the configuration
+ * matching a specific bConfigurationValue in the idx output parameter, or -1
+ * if the config was not found.
+ * returns 0 on success or a LIBUSB_ERROR code
+ */
+int usbi_get_config_index_by_value(struct libusb_device *dev,
+ uint8_t bConfigurationValue, int *idx)
+{
+ uint8_t i;
+
+ usbi_dbg("value %d", bConfigurationValue);
+ for (i = 0; i < dev->num_configurations; i++) {
+ unsigned char tmp[6];
+ int host_endian;
+ int r = usbi_backend.get_config_descriptor(dev, i, tmp, sizeof(tmp),
+ &host_endian);
+ if (r < 0) {
+ *idx = -1;
+ return r;
+ }
+ if (tmp[5] == bConfigurationValue) {
+ *idx = i;
+ return 0;
+ }
+ }
+
+ *idx = -1;
+ return 0;
+}
+
+/** \ingroup libusb_desc
+ * Get a USB configuration descriptor with a specific bConfigurationValue.
+ * This is a non-blocking function which does not involve any requests being
+ * sent to the device.
+ *
+ * \param dev a device
+ * \param bConfigurationValue the bConfigurationValue of the configuration you
+ * wish to retrieve
+ * \param config output location for the USB configuration descriptor. Only
+ * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
+ * after use.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
+ * \returns another LIBUSB_ERROR code on error
+ * \see libusb_get_active_config_descriptor()
+ * \see libusb_get_config_descriptor()
+ */
+int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
+ uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
+{
+ int r, idx, host_endian;
+ unsigned char *buf = NULL;
+
+ if (usbi_backend.get_config_descriptor_by_value) {
+ r = usbi_backend.get_config_descriptor_by_value(dev,
+ bConfigurationValue, &buf, &host_endian);
+ if (r < 0)
+ return r;
+ return raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
+ }
+
+ r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
+ if (r < 0)
+ return r;
+ else if (idx == -1)
+ return LIBUSB_ERROR_NOT_FOUND;
+ else
+ return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
+}
+
+/** \ingroup libusb_desc
+ * Free a configuration descriptor obtained from
+ * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
+ * It is safe to call this function with a NULL config parameter, in which
+ * case the function simply returns.
+ *
+ * \param config the configuration descriptor to free
+ */
+void API_EXPORTED libusb_free_config_descriptor(
+ struct libusb_config_descriptor *config)
+{
+ if (!config)
+ return;
+
+ clear_configuration(config);
+ free(config);
+}
+
+/** \ingroup libusb_desc
+ * Get an endpoints superspeed endpoint companion descriptor (if any)
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param endpoint endpoint descriptor from which to get the superspeed
+ * endpoint companion descriptor
+ * \param ep_comp output location for the superspeed endpoint companion
+ * descriptor. Only valid if 0 was returned. Must be freed with
+ * libusb_free_ss_endpoint_companion_descriptor() after use.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
+ * \returns another LIBUSB_ERROR code on error
+ */
+int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
+ struct libusb_context *ctx,
+ const struct libusb_endpoint_descriptor *endpoint,
+ struct libusb_ss_endpoint_companion_descriptor **ep_comp)
+{
+ struct usb_descriptor_header header;
+ int size = endpoint->extra_length;
+ const unsigned char *buffer = endpoint->extra;
+
+ *ep_comp = NULL;
+
+ while (size >= DESC_HEADER_LENGTH) {
+ usbi_parse_descriptor(buffer, "bb", &header, 0);
+ if (header.bLength < 2 || header.bLength > size) {
+ usbi_err(ctx, "invalid descriptor length %d",
+ header.bLength);
+ return LIBUSB_ERROR_IO;
+ }
+ if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
+ buffer += header.bLength;
+ size -= header.bLength;
+ continue;
+ }
+ if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
+ usbi_err(ctx, "invalid ss-ep-comp-desc length %d",
+ header.bLength);
+ return LIBUSB_ERROR_IO;
+ }
+ *ep_comp = malloc(sizeof(**ep_comp));
+ if (*ep_comp == NULL)
+ return LIBUSB_ERROR_NO_MEM;
+ usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0);
+ return LIBUSB_SUCCESS;
+ }
+ return LIBUSB_ERROR_NOT_FOUND;
+}
+
+/** \ingroup libusb_desc
+ * Free a superspeed endpoint companion descriptor obtained from
+ * libusb_get_ss_endpoint_companion_descriptor().
+ * It is safe to call this function with a NULL ep_comp parameter, in which
+ * case the function simply returns.
+ *
+ * \param ep_comp the superspeed endpoint companion descriptor to free
+ */
+void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
+ struct libusb_ss_endpoint_companion_descriptor *ep_comp)
+{
+ free(ep_comp);
+}
+
+static int parse_bos(struct libusb_context *ctx,
+ struct libusb_bos_descriptor **bos,
+ unsigned char *buffer, int size, int host_endian)
+{
+ struct libusb_bos_descriptor bos_header, *_bos;
+ struct libusb_bos_dev_capability_descriptor dev_cap;
+ int i;
+
+ if (size < LIBUSB_DT_BOS_SIZE) {
+ usbi_err(ctx, "short bos descriptor read %d/%d",
+ size, LIBUSB_DT_BOS_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian);
+ if (bos_header.bDescriptorType != LIBUSB_DT_BOS) {
+ usbi_err(ctx, "unexpected descriptor %x (expected %x)",
+ bos_header.bDescriptorType, LIBUSB_DT_BOS);
+ return LIBUSB_ERROR_IO;
+ }
+ if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) {
+ usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength);
+ return LIBUSB_ERROR_IO;
+ }
+ if (bos_header.bLength > size) {
+ usbi_err(ctx, "short bos descriptor read %d/%d",
+ size, bos_header.bLength);
+ return LIBUSB_ERROR_IO;
+ }
+
+ _bos = calloc (1,
+ sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *));
+ if (!_bos)
+ return LIBUSB_ERROR_NO_MEM;
+
+ usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian);
+ buffer += bos_header.bLength;
+ size -= bos_header.bLength;
+
+ /* Get the device capability descriptors */
+ for (i = 0; i < bos_header.bNumDeviceCaps; i++) {
+ if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
+ usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
+ size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
+ break;
+ }
+ usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian);
+ if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
+ usbi_warn(ctx, "unexpected descriptor %x (expected %x)",
+ dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
+ break;
+ }
+ if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
+ usbi_err(ctx, "invalid dev-cap bLength (%d)",
+ dev_cap.bLength);
+ libusb_free_bos_descriptor(_bos);
+ return LIBUSB_ERROR_IO;
+ }
+ if (dev_cap.bLength > size) {
+ usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
+ size, dev_cap.bLength);
+ break;
+ }
+
+ _bos->dev_capability[i] = malloc(dev_cap.bLength);
+ if (!_bos->dev_capability[i]) {
+ libusb_free_bos_descriptor(_bos);
+ return LIBUSB_ERROR_NO_MEM;
+ }
+ memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength);
+ buffer += dev_cap.bLength;
+ size -= dev_cap.bLength;
+ }
+ _bos->bNumDeviceCaps = (uint8_t)i;
+ *bos = _bos;
+
+ return LIBUSB_SUCCESS;
+}
+
+/** \ingroup libusb_desc
+ * Get a Binary Object Store (BOS) descriptor
+ * This is a BLOCKING function, which will send requests to the device.
+ *
+ * \param dev_handle the handle of an open libusb device
+ * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
+ * Must be freed with \ref libusb_free_bos_descriptor() after use.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
+ * \returns another LIBUSB_ERROR code on error
+ */
+int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
+ struct libusb_bos_descriptor **bos)
+{
+ struct libusb_bos_descriptor _bos;
+ uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
+ unsigned char *bos_data = NULL;
+ const int host_endian = 0;
+ int r;
+
+ /* Read the BOS. This generates 2 requests on the bus,
+ * one for the header, and one for the full BOS */
+ r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_header,
+ LIBUSB_DT_BOS_SIZE);
+ if (r < 0) {
+ if (r != LIBUSB_ERROR_PIPE)
+ usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
+ return r;
+ }
+ if (r < LIBUSB_DT_BOS_SIZE) {
+ usbi_err(HANDLE_CTX(dev_handle), "short BOS read %d/%d",
+ r, LIBUSB_DT_BOS_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian);
+ usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
+ _bos.wTotalLength, _bos.bNumDeviceCaps);
+ bos_data = calloc(_bos.wTotalLength, 1);
+ if (bos_data == NULL)
+ return LIBUSB_ERROR_NO_MEM;
+
+ r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data,
+ _bos.wTotalLength);
+ if (r >= 0)
+ r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r, host_endian);
+ else
+ usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
+
+ free(bos_data);
+ return r;
+}
+
+/** \ingroup libusb_desc
+ * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
+ * It is safe to call this function with a NULL bos parameter, in which
+ * case the function simply returns.
+ *
+ * \param bos the BOS descriptor to free
+ */
+void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
+{
+ int i;
+
+ if (!bos)
+ return;
+
+ for (i = 0; i < bos->bNumDeviceCaps; i++)
+ free(bos->dev_capability[i]);
+ free(bos);
+}
+
+/** \ingroup libusb_desc
+ * Get an USB 2.0 Extension descriptor
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
+ * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
+ * LIBUSB_BT_USB_2_0_EXTENSION
+ * \param usb_2_0_extension output location for the USB 2.0 Extension
+ * descriptor. Only valid if 0 was returned. Must be freed with
+ * libusb_free_usb_2_0_extension_descriptor() after use.
+ * \returns 0 on success
+ * \returns a LIBUSB_ERROR code on error
+ */
+int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
+ struct libusb_context *ctx,
+ struct libusb_bos_dev_capability_descriptor *dev_cap,
+ struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
+{
+ struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
+ const int host_endian = 0;
+
+ if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
+ usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
+ dev_cap->bDevCapabilityType,
+ LIBUSB_BT_USB_2_0_EXTENSION);
+ return LIBUSB_ERROR_INVALID_PARAM;
+ }
+ if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
+ usbi_err(ctx, "short dev-cap descriptor read %d/%d",
+ dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
+ if (!_usb_2_0_extension)
+ return LIBUSB_ERROR_NO_MEM;
+
+ usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd",
+ _usb_2_0_extension, host_endian);
+
+ *usb_2_0_extension = _usb_2_0_extension;
+ return LIBUSB_SUCCESS;
+}
+
+/** \ingroup libusb_desc
+ * Free a USB 2.0 Extension descriptor obtained from
+ * libusb_get_usb_2_0_extension_descriptor().
+ * It is safe to call this function with a NULL usb_2_0_extension parameter,
+ * in which case the function simply returns.
+ *
+ * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
+ */
+void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
+ struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
+{
+ free(usb_2_0_extension);
+}
+
+/** \ingroup libusb_desc
+ * Get a SuperSpeed USB Device Capability descriptor
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
+ * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
+ * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
+ * \param ss_usb_device_cap output location for the SuperSpeed USB Device
+ * Capability descriptor. Only valid if 0 was returned. Must be freed with
+ * libusb_free_ss_usb_device_capability_descriptor() after use.
+ * \returns 0 on success
+ * \returns a LIBUSB_ERROR code on error
+ */
+int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
+ struct libusb_context *ctx,
+ struct libusb_bos_dev_capability_descriptor *dev_cap,
+ struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
+{
+ struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
+ const int host_endian = 0;
+
+ if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
+ usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
+ dev_cap->bDevCapabilityType,
+ LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
+ return LIBUSB_ERROR_INVALID_PARAM;
+ }
+ if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
+ usbi_err(ctx, "short dev-cap descriptor read %d/%d",
+ dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
+ if (!_ss_usb_device_cap)
+ return LIBUSB_ERROR_NO_MEM;
+
+ usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw",
+ _ss_usb_device_cap, host_endian);
+
+ *ss_usb_device_cap = _ss_usb_device_cap;
+ return LIBUSB_SUCCESS;
+}
+
+/** \ingroup libusb_desc
+ * Free a SuperSpeed USB Device Capability descriptor obtained from
+ * libusb_get_ss_usb_device_capability_descriptor().
+ * It is safe to call this function with a NULL ss_usb_device_cap
+ * parameter, in which case the function simply returns.
+ *
+ * \param ss_usb_device_cap the SuperSpeed USB Device Capability descriptor
+ * to free
+ */
+void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
+ struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
+{
+ free(ss_usb_device_cap);
+}
+
+/** \ingroup libusb_desc
+ * Get a Container ID descriptor
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
+ * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
+ * LIBUSB_BT_CONTAINER_ID
+ * \param container_id output location for the Container ID descriptor.
+ * Only valid if 0 was returned. Must be freed with
+ * libusb_free_container_id_descriptor() after use.
+ * \returns 0 on success
+ * \returns a LIBUSB_ERROR code on error
+ */
+int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
+ struct libusb_bos_dev_capability_descriptor *dev_cap,
+ struct libusb_container_id_descriptor **container_id)
+{
+ struct libusb_container_id_descriptor *_container_id;
+ const int host_endian = 0;
+
+ if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
+ usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
+ dev_cap->bDevCapabilityType,
+ LIBUSB_BT_CONTAINER_ID);
+ return LIBUSB_ERROR_INVALID_PARAM;
+ }
+ if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
+ usbi_err(ctx, "short dev-cap descriptor read %d/%d",
+ dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
+ return LIBUSB_ERROR_IO;
+ }
+
+ _container_id = malloc(sizeof(*_container_id));
+ if (!_container_id)
+ return LIBUSB_ERROR_NO_MEM;
+
+ usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu",
+ _container_id, host_endian);
+
+ *container_id = _container_id;
+ return LIBUSB_SUCCESS;
+}
+
+/** \ingroup libusb_desc
+ * Free a Container ID descriptor obtained from
+ * libusb_get_container_id_descriptor().
+ * It is safe to call this function with a NULL container_id parameter,
+ * in which case the function simply returns.
+ *
+ * \param container_id the Container ID descriptor to free
+ */
+void API_EXPORTED libusb_free_container_id_descriptor(
+ struct libusb_container_id_descriptor *container_id)
+{
+ free(container_id);
+}
+
+/** \ingroup libusb_desc
+ * Retrieve a string descriptor in C style ASCII.
+ *
+ * Wrapper around libusb_get_string_descriptor(). Uses the first language
+ * supported by the device.
+ *
+ * \param dev_handle a device handle
+ * \param desc_index the index of the descriptor to retrieve
+ * \param data output buffer for ASCII string descriptor
+ * \param length size of data buffer
+ * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
+ uint8_t desc_index, unsigned char *data, int length)
+{
+ unsigned char tbuf[255]; /* Some devices choke on size > 255 */
+ int r, si, di;
+ uint16_t langid;
+
+ /* Asking for the zero'th index is special - it returns a string
+ * descriptor that contains all the language IDs supported by the
+ * device. Typically there aren't many - often only one. Language
+ * IDs are 16 bit numbers, and they start at the third byte in the
+ * descriptor. There's also no point in trying to read descriptor 0
+ * with this function. See USB 2.0 specification section 9.6.7 for
+ * more information.
+ */
+
+ if (desc_index == 0)
+ return LIBUSB_ERROR_INVALID_PARAM;
+
+ r = libusb_get_string_descriptor(dev_handle, 0, 0, tbuf, sizeof(tbuf));
+ if (r < 0)
+ return r;
+
+ if (r < 4)
+ return LIBUSB_ERROR_IO;
+
+ langid = (uint16_t)(tbuf[2] | (tbuf[3] << 8));
+
+ r = libusb_get_string_descriptor(dev_handle, desc_index, langid, tbuf,
+ sizeof(tbuf));
+ if (r < 0)
+ return r;
+
+ if (tbuf[1] != LIBUSB_DT_STRING)
+ return LIBUSB_ERROR_IO;
+
+ if (tbuf[0] > r)
+ return LIBUSB_ERROR_IO;
+
+ di = 0;
+ for (si = 2; si < tbuf[0]; si += 2) {
+ if (di >= (length - 1))
+ break;
+
+ if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
+ data[di++] = '?';
+ else
+ data[di++] = tbuf[si];
+ }
+
+ data[di] = 0;
+ return di;
+}
diff --git a/libusb1/hotplug.c b/libusb1/hotplug.c
new file mode 100644
index 0000000..a4320bc
--- /dev/null
+++ b/libusb1/hotplug.c
@@ -0,0 +1,373 @@
+/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
+/*
+ * Hotplug functions for libusb
+ * Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
+ * Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <assert.h>
+
+#include "libusbi.h"
+#include "hotplug.h"
+
+/**
+ * @defgroup libusb_hotplug Device hotplug event notification
+ * This page details how to use the libusb hotplug interface, where available.
+ *
+ * Be mindful that not all platforms currently implement hotplug notification and
+ * that you should first call on \ref libusb_has_capability() with parameter
+ * \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available.
+ *
+ * \page libusb_hotplug Device hotplug event notification
+ *
+ * \section hotplug_intro Introduction
+ *
+ * Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support
+ * for hotplug events on <b>some</b> platforms (you should test if your platform
+ * supports hotplug notification by calling \ref libusb_has_capability() with
+ * parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
+ *
+ * This interface allows you to request notification for the arrival and departure
+ * of matching USB devices.
+ *
+ * To receive hotplug notification you register a callback by calling
+ * \ref libusb_hotplug_register_callback(). This function will optionally return
+ * a callback handle that can be passed to \ref libusb_hotplug_deregister_callback().
+ *
+ * A callback function must return an int (0 or 1) indicating whether the callback is
+ * expecting additional events. Returning 0 will rearm the callback and 1 will cause
+ * the callback to be deregistered. Note that when callbacks are called from
+ * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE
+ * flag, the callback return value is ignored, iow you cannot cause a callback
+ * to be deregistered by returning 1 when it is called from
+ * libusb_hotplug_register_callback().
+ *
+ * Callbacks for a particular context are automatically deregistered by libusb_exit().
+ *
+ * As of 1.0.16 there are two supported hotplug events:
+ * - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use
+ * - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available
+ *
+ * A hotplug event can listen for either or both of these events.
+ *
+ * Note: If you receive notification that a device has left and you have any
+ * a libusb_device_handles for the device it is up to you to call libusb_close()
+ * on each device handle to free up any remaining resources associated with the device.
+ * Once a device has left any libusb_device_handle associated with the device
+ * are invalid and will remain so even if the device comes back.
+ *
+ * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered
+ * safe to call any libusb function that takes a libusb_device. It also safe to
+ * open a device and submit asynchronous transfers. However, most other functions
+ * that take a libusb_device_handle are <b>not</b> safe to call. Examples of such
+ * functions are any of the \ref libusb_syncio "synchronous API" functions or the blocking
+ * functions that retrieve various \ref libusb_desc "USB descriptors". These functions must
+ * be used outside of the context of the hotplug callback.
+ *
+ * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function
+ * is libusb_get_device_descriptor().
+ *
+ * The following code provides an example of the usage of the hotplug interface:
+\code
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <libusb.h>
+
+static int count = 0;
+
+int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
+ libusb_hotplug_event event, void *user_data) {
+ static libusb_device_handle *dev_handle = NULL;
+ struct libusb_device_descriptor desc;
+ int rc;
+
+ (void)libusb_get_device_descriptor(dev, &desc);
+
+ if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
+ rc = libusb_open(dev, &dev_handle);
+ if (LIBUSB_SUCCESS != rc) {
+ printf("Could not open USB device\n");
+ }
+ } else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
+ if (dev_handle) {
+ libusb_close(dev_handle);
+ dev_handle = NULL;
+ }
+ } else {
+ printf("Unhandled event %d\n", event);
+ }
+ count++;
+
+ return 0;
+}
+
+int main (void) {
+ libusb_hotplug_callback_handle callback_handle;
+ int rc;
+
+ libusb_init(NULL);
+
+ rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
+ LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
+ &callback_handle);
+ if (LIBUSB_SUCCESS != rc) {
+ printf("Error creating a hotplug callback\n");
+ libusb_exit(NULL);
+ return EXIT_FAILURE;
+ }
+
+ while (count < 2) {
+ libusb_handle_events_completed(NULL, NULL);
+ nanosleep(&(struct timespec){0, 10000000UL}, NULL);
+ }
+
+ libusb_hotplug_deregister_callback(NULL, callback_handle);
+ libusb_exit(NULL);
+
+ return 0;
+}
+\endcode
+ */
+
+static int usbi_hotplug_match_cb(struct libusb_context *ctx,
+ struct libusb_device *dev, libusb_hotplug_event event,
+ struct libusb_hotplug_callback *hotplug_cb)
+{
+ if (!(hotplug_cb->flags & event)) {
+ return 0;
+ }
+
+ if ((hotplug_cb->flags & USBI_HOTPLUG_VENDOR_ID_VALID) &&
+ hotplug_cb->vendor_id != dev->device_descriptor.idVendor) {
+ return 0;
+ }
+
+ if ((hotplug_cb->flags & USBI_HOTPLUG_PRODUCT_ID_VALID) &&
+ hotplug_cb->product_id != dev->device_descriptor.idProduct) {
+ return 0;
+ }
+
+ if ((hotplug_cb->flags & USBI_HOTPLUG_DEV_CLASS_VALID) &&
+ hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) {
+ return 0;
+ }
+
+ return hotplug_cb->cb(ctx, dev, event, hotplug_cb->user_data);
+}
+
+void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
+ libusb_hotplug_event event)
+{
+ struct libusb_hotplug_callback *hotplug_cb, *next;
+ int ret;
+
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
+
+ list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
+ if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
+ /* process deregistration in usbi_hotplug_deregister() */
+ continue;
+ }
+
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
+ ret = usbi_hotplug_match_cb(ctx, dev, event, hotplug_cb);
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
+
+ if (ret) {
+ list_del(&hotplug_cb->list);
+ free(hotplug_cb);
+ }
+ }
+
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
+}
+
+void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
+ libusb_hotplug_event event)
+{
+ int pending_events;
+ struct libusb_hotplug_message *message = calloc(1, sizeof(*message));
+
+ if (!message) {
+ usbi_err(ctx, "error allocating hotplug message");
+ return;
+ }
+
+ message->event = event;
+ message->device = dev;
+
+ /* Take the event data lock and add this message to the list.
+ * Only signal an event if there are no prior pending events. */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ pending_events = usbi_pending_events(ctx);
+ list_add_tail(&message->list, &ctx->hotplug_msgs);
+ if (!pending_events)
+ usbi_signal_event(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+}
+
+int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
+ libusb_hotplug_event events, libusb_hotplug_flag flags,
+ int vendor_id, int product_id, int dev_class,
+ libusb_hotplug_callback_fn cb_fn, void *user_data,
+ libusb_hotplug_callback_handle *callback_handle)
+{
+ struct libusb_hotplug_callback *new_callback;
+
+ /* check for sane values */
+ if ((!events || (~(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) & events)) ||
+ (flags && (~LIBUSB_HOTPLUG_ENUMERATE & flags)) ||
+ (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
+ (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
+ (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
+ !cb_fn) {
+ return LIBUSB_ERROR_INVALID_PARAM;
+ }
+
+ /* check for hotplug support */
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+ }
+
+ USBI_GET_CONTEXT(ctx);
+
+ new_callback = calloc(1, sizeof(*new_callback));
+ if (!new_callback) {
+ return LIBUSB_ERROR_NO_MEM;
+ }
+
+ new_callback->flags = (uint8_t)events;
+ if (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id) {
+ new_callback->flags |= USBI_HOTPLUG_VENDOR_ID_VALID;
+ new_callback->vendor_id = (uint16_t)vendor_id;
+ }
+ if (LIBUSB_HOTPLUG_MATCH_ANY != product_id) {
+ new_callback->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID;
+ new_callback->product_id = (uint16_t)product_id;
+ }
+ if (LIBUSB_HOTPLUG_MATCH_ANY != dev_class) {
+ new_callback->flags |= USBI_HOTPLUG_DEV_CLASS_VALID;
+ new_callback->dev_class = (uint8_t)dev_class;
+ }
+ new_callback->cb = cb_fn;
+ new_callback->user_data = user_data;
+
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
+
+ /* protect the handle by the context hotplug lock */
+ new_callback->handle = ctx->next_hotplug_cb_handle++;
+
+ /* handle the unlikely case of overflow */
+ if (ctx->next_hotplug_cb_handle < 0)
+ ctx->next_hotplug_cb_handle = 1;
+
+ list_add(&new_callback->list, &ctx->hotplug_cbs);
+
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
+
+ usbi_dbg("new hotplug cb %p with handle %d", new_callback, new_callback->handle);
+
+ if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
+ ssize_t i, len;
+ struct libusb_device **devs;
+
+ len = libusb_get_device_list(ctx, &devs);
+ if (len < 0) {
+ libusb_hotplug_deregister_callback(ctx,
+ new_callback->handle);
+ return (int)len;
+ }
+
+ for (i = 0; i < len; i++) {
+ usbi_hotplug_match_cb(ctx, devs[i],
+ LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
+ new_callback);
+ }
+
+ libusb_free_device_list(devs, 1);
+ }
+
+
+ if (callback_handle)
+ *callback_handle = new_callback->handle;
+
+ return LIBUSB_SUCCESS;
+}
+
+void API_EXPORTED libusb_hotplug_deregister_callback(struct libusb_context *ctx,
+ libusb_hotplug_callback_handle callback_handle)
+{
+ struct libusb_hotplug_callback *hotplug_cb;
+ int deregistered = 0;
+
+ /* check for hotplug support */
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
+ return;
+ }
+
+ USBI_GET_CONTEXT(ctx);
+
+ usbi_dbg("deregister hotplug cb %d", callback_handle);
+
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
+ list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
+ if (callback_handle == hotplug_cb->handle) {
+ /* Mark this callback for deregistration */
+ hotplug_cb->flags |= USBI_HOTPLUG_NEEDS_FREE;
+ deregistered = 1;
+ }
+ }
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
+
+ if (deregistered) {
+ int pending_events;
+
+ usbi_mutex_lock(&ctx->event_data_lock);
+ pending_events = usbi_pending_events(ctx);
+ ctx->event_flags |= USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
+ if (!pending_events)
+ usbi_signal_event(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ }
+}
+
+void usbi_hotplug_deregister(struct libusb_context *ctx, int forced)
+{
+ struct libusb_hotplug_callback *hotplug_cb, *next;
+
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
+ list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
+ if (forced || (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)) {
+ usbi_dbg("freeing hotplug cb %p with handle %d", hotplug_cb,
+ hotplug_cb->handle);
+ list_del(&hotplug_cb->list);
+ free(hotplug_cb);
+ }
+ }
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
+}
diff --git a/libusb1/hotplug.h b/libusb1/hotplug.h
new file mode 100644
index 0000000..75b2695
--- /dev/null
+++ b/libusb1/hotplug.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
+/*
+ * Hotplug support for libusb
+ * Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
+ * Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef USBI_HOTPLUG_H
+#define USBI_HOTPLUG_H
+
+#include "libusbi.h"
+
+enum usbi_hotplug_flags {
+ /* This callback is interested in device arrivals */
+ USBI_HOTPLUG_DEVICE_ARRIVED = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
+
+ /* This callback is interested in device removals */
+ USBI_HOTPLUG_DEVICE_LEFT = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
+
+ /* IMPORTANT: The values for the below entries must start *after*
+ * the highest value of the above entries!!!
+ */
+
+ /* The vendor_id field is valid for matching */
+ USBI_HOTPLUG_VENDOR_ID_VALID = (1U << 3),
+
+ /* The product_id field is valid for matching */
+ USBI_HOTPLUG_PRODUCT_ID_VALID = (1U << 4),
+
+ /* The dev_class field is valid for matching */
+ USBI_HOTPLUG_DEV_CLASS_VALID = (1U << 5),
+
+ /* This callback has been unregistered and needs to be freed */
+ USBI_HOTPLUG_NEEDS_FREE = (1U << 6),
+};
+
+/** \ingroup hotplug
+ * The hotplug callback structure. The user populates this structure with
+ * libusb_hotplug_prepare_callback() and then calls libusb_hotplug_register_callback()
+ * to receive notification of hotplug events.
+ */
+struct libusb_hotplug_callback {
+ /** Flags that control how this callback behaves */
+ uint8_t flags;
+
+ /** Vendor ID to match (if flags says this is valid) */
+ uint16_t vendor_id;
+
+ /** Product ID to match (if flags says this is valid) */
+ uint16_t product_id;
+
+ /** Device class to match (if flags says this is valid) */
+ uint8_t dev_class;
+
+ /** Callback function to invoke for matching event/device */
+ libusb_hotplug_callback_fn cb;
+
+ /** Handle for this callback (used to match on deregister) */
+ libusb_hotplug_callback_handle handle;
+
+ /** User data that will be passed to the callback function */
+ void *user_data;
+
+ /** List this callback is registered in (ctx->hotplug_cbs) */
+ struct list_head list;
+};
+
+struct libusb_hotplug_message {
+ /** The hotplug event that occurred */
+ libusb_hotplug_event event;
+
+ /** The device for which this hotplug event occurred */
+ struct libusb_device *device;
+
+ /** List this message is contained in (ctx->hotplug_msgs) */
+ struct list_head list;
+};
+
+void usbi_hotplug_deregister(struct libusb_context *ctx, int forced);
+void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
+ libusb_hotplug_event event);
+void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
+ libusb_hotplug_event event);
+
+#endif
diff --git a/libusb1/io.c b/libusb1/io.c
new file mode 100644
index 0000000..978b09a
--- /dev/null
+++ b/libusb1/io.c
@@ -0,0 +1,2866 @@
+/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
+/*
+ * I/O functions for libusb
+ * Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
+ * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
+ * Copyright © 2019 Nathan Hjelm <hjelmn@cs.umm.edu>
+ * Copyright © 2019 Google LLC. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef USBI_TIMERFD_AVAILABLE
+#include <unistd.h>
+#include <sys/timerfd.h>
+#endif
+
+#include "libusbi.h"
+#include "hotplug.h"
+
+/**
+ * \page libusb_io Synchronous and asynchronous device I/O
+ *
+ * \section io_intro Introduction
+ *
+ * If you're using libusb in your application, you're probably wanting to
+ * perform I/O with devices - you want to perform USB data transfers.
+ *
+ * libusb offers two separate interfaces for device I/O. This page aims to
+ * introduce the two in order to help you decide which one is more suitable
+ * for your application. You can also choose to use both interfaces in your
+ * application by considering each transfer on a case-by-case basis.
+ *
+ * Once you have read through the following discussion, you should consult the
+ * detailed API documentation pages for the details:
+ * - \ref libusb_syncio
+ * - \ref libusb_asyncio
+ *
+ * \section theory Transfers at a logical level
+ *
+ * At a logical level, USB transfers typically happen in two parts. For
+ * example, when reading data from a endpoint:
+ * -# A request for data is sent to the device
+ * -# Some time later, the incoming data is received by the host
+ *
+ * or when writing data to an endpoint:
+ *
+ * -# The data is sent to the device
+ * -# Some time later, the host receives acknowledgement from the device that
+ * the data has been transferred.
+ *
+ * There may be an indefinite delay between the two steps. Consider a
+ * fictional USB input device with a button that the user can press. In order
+ * to determine when the button is pressed, you would likely submit a request
+ * to read data on a bulk or interrupt endpoint and wait for data to arrive.
+ * Data will arrive when the button is pressed by the user, which is
+ * potentially hours later.
+ *
+ * libusb offers both a synchronous and an asynchronous interface to performing
+ * USB transfers. The main difference is that the synchronous interface
+ * combines both steps indicated above into a single function call, whereas
+ * the asynchronous interface separates them.
+ *
+ * \section sync The synchronous interface
+ *
+ * The synchronous I/O interface allows you to perform a USB transfer with
+ * a single function call. When the function call returns, the transfer has
+ * completed and you can parse the results.
+ *
+ * If you have used the libusb-0.1 before, this I/O style will seem familar to
+ * you. libusb-0.1 only offered a synchronous interface.
+ *
+ * In our input device example, to read button presses you might write code
+ * in the following style:
+\code
+unsigned char data[4];
+int actual_length;
+int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0);
+if (r == 0 && actual_length == sizeof(data)) {
+ // results of the transaction can now be found in the data buffer
+ // parse them here and report button press
+} else {
+ error();
+}
+\endcode
+ *
+ * The main advantage of this model is simplicity: you did everything with
+ * a single simple function call.
+ *
+ * However, this interface has its limitations. Your application will sleep
+ * inside libusb_bulk_transfer() until the transaction has completed. If it
+ * takes the user 3 hours to press the button, your application will be
+ * sleeping for that long. Execution will be tied up inside the library -
+ * the entire thread will be useless for that duration.
+ *
+ * Another issue is that by tieing up the thread with that single transaction
+ * there is no possibility of performing I/O with multiple endpoints and/or
+ * multiple devices simultaneously, unless you resort to creating one thread
+ * per transaction.
+ *
+ * Additionally, there is no opportunity to cancel the transfer after the
+ * request has been submitted.
+ *
+ * For details on how to use the synchronous API, see the
+ * \ref libusb_syncio "synchronous I/O API documentation" pages.
+ *
+ * \section async The asynchronous interface
+ *
+ * Asynchronous I/O is the most significant new feature in libusb-1.0.
+ * Although it is a more complex interface, it solves all the issues detailed
+ * above.
+ *
+ * Instead of providing which functions that block until the I/O has complete,
+ * libusb's asynchronous interface presents non-blocking functions which
+ * begin a transfer and then return immediately. Your application passes a
+ * callback function pointer to this non-blocking function, which libusb will
+ * call with the results of the transaction when it has completed.
+ *
+ * Transfers which have been submitted through the non-blocking functions
+ * can be cancelled with a separate function call.
+ *
+ * The non-blocking nature of this interface allows you to be simultaneously
+ * performing I/O to multiple endpoints on multiple devices, without having
+ * to use threads.
+ *
+ * This added flexibility does come with some complications though:
+ * - In the interest of being a lightweight library, libusb does not create
+ * threads and can only operate when your application is calling into it. Your
+ * application must call into libusb from it's main loop when events are ready
+ * to be handled, or you must use some other scheme to allow libusb to
+ * undertake whatever work needs to be done.
+ * - libusb also needs to be called into at certain fixed points in time in
+ * order to accurately handle transfer timeouts.
+ * - Memory handling becomes more complex. You cannot use stack memory unless
+ * the function with that stack is guaranteed not to return until the transfer
+ * callback has finished executing.
+ * - You generally lose some linearity from your code flow because submitting
+ * the transfer request is done in a separate function from where the transfer
+ * results are handled. This becomes particularly obvious when you want to
+ * submit a second transfer based on the results of an earlier transfer.
+ *
+ * Internally, libusb's synchronous interface is expressed in terms of function
+ * calls to the asynchronous interface.
+ *
+ * For details on how to use the asynchronous API, see the
+ * \ref libusb_asyncio "asynchronous I/O API" documentation pages.
+ */
+
+
+/**
+ * \page libusb_packetoverflow Packets and overflows
+ *
+ * \section packets Packet abstraction
+ *
+ * The USB specifications describe how data is transmitted in packets, with
+ * constraints on packet size defined by endpoint descriptors. The host must
+ * not send data payloads larger than the endpoint's maximum packet size.
+ *
+ * libusb and the underlying OS abstract out the packet concept, allowing you
+ * to request transfers of any size. Internally, the request will be divided
+ * up into correctly-sized packets. You do not have to be concerned with
+ * packet sizes, but there is one exception when considering overflows.
+ *
+ * \section overflow Bulk/interrupt transfer overflows
+ *
+ * When requesting data on a bulk endpoint, libusb requires you to supply a
+ * buffer and the maximum number of bytes of data that libusb can put in that
+ * buffer. However, the size of the buffer is not communicated to the device -
+ * the device is just asked to send any amount of data.
+ *
+ * There is no problem if the device sends an amount of data that is less than
+ * or equal to the buffer size. libusb reports this condition to you through
+ * the \ref libusb_transfer::actual_length "libusb_transfer.actual_length"
+ * field.
+ *
+ * Problems may occur if the device attempts to send more data than can fit in
+ * the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but
+ * other behaviour is largely undefined: actual_length may or may not be
+ * accurate, the chunk of data that can fit in the buffer (before overflow)
+ * may or may not have been transferred.
+ *
+ * Overflows are nasty, but can be avoided. Even though you were told to
+ * ignore packets above, think about the lower level details: each transfer is
+ * split into packets (typically small, with a maximum size of 512 bytes).
+ * Overflows can only happen if the final packet in an incoming data transfer
+ * is smaller than the actual packet that the device wants to transfer.
+ * Therefore, you will never see an overflow if your transfer buffer size is a
+ * multiple of the endpoint's packet size: the final packet will either
+ * fill up completely or will be only partially filled.
+ */
+
+/**
+ * @defgroup libusb_asyncio Asynchronous device I/O
+ *
+ * This page details libusb's asynchronous (non-blocking) API for USB device
+ * I/O. This interface is very powerful but is also quite complex - you will
+ * need to read this page carefully to understand the necessary considerations
+ * and issues surrounding use of this interface. Simplistic applications
+ * may wish to consider the \ref libusb_syncio "synchronous I/O API" instead.
+ *
+ * The asynchronous interface is built around the idea of separating transfer
+ * submission and handling of transfer completion (the synchronous model
+ * combines both of these into one). There may be a long delay between
+ * submission and completion, however the asynchronous submission function
+ * is non-blocking so will return control to your application during that
+ * potentially long delay.
+ *
+ * \section asyncabstraction Transfer abstraction
+ *
+ * For the asynchronous I/O, libusb implements the concept of a generic
+ * transfer entity for all types of I/O (control, bulk, interrupt,
+ * isochronous). The generic transfer object must be treated slightly
+ * differently depending on which type of I/O you are performing with it.
+ *
+ * This is represented by the public libusb_transfer structure type.
+ *
+ * \section asynctrf Asynchronous transfers
+ *
+ * We can view asynchronous I/O as a 5 step process:
+ * -# <b>Allocation</b>: allocate a libusb_transfer
+ * -# <b>Filling</b>: populate the libusb_transfer instance with information
+ * about the transfer you wish to perform
+ * -# <b>Submission</b>: ask libusb to submit the transfer
+ * -# <b>Completion handling</b>: examine transfer results in the
+ * libusb_transfer structure
+ * -# <b>Deallocation</b>: clean up resources
+ *
+ *
+ * \subsection asyncalloc Allocation
+ *
+ * This step involves allocating memory for a USB transfer. This is the
+ * generic transfer object mentioned above. At this stage, the transfer
+ * is "blank" with no details about what type of I/O it will be used for.
+ *
+ * Allocation is done with the libusb_alloc_transfer() function. You must use
+ * this function rather than allocating your own transfers.
+ *
+ * \subsection asyncfill Filling
+ *
+ * This step is where you take a previously allocated transfer and fill it
+ * with information to determine the message type and direction, data buffer,
+ * callback function, etc.
+ *
+ * You can either fill the required fields yourself or you can use the
+ * helper functions: libusb_fill_control_transfer(), libusb_fill_bulk_transfer()
+ * and libusb_fill_interrupt_transfer().
+ *
+ * \subsection asyncsubmit Submission
+ *
+ * When you have allocated a transfer and filled it, you can submit it using
+ * libusb_submit_transfer(). This function returns immediately but can be
+ * regarded as firing off the I/O request in the background.
+ *
+ * \subsection asynccomplete Completion handling
+ *
+ * After a transfer has been submitted, one of four things can happen to it:
+ *
+ * - The transfer completes (i.e. some data was transferred)
+ * - The transfer has a timeout and the timeout expires before all data is
+ * transferred
+ * - The transfer fails due to an error
+ * - The transfer is cancelled
+ *
+ * Each of these will cause the user-specified transfer callback function to
+ * be invoked. It is up to the callback function to determine which of the
+ * above actually happened and to act accordingly.
+ *
+ * The user-specified callback is passed a pointer to the libusb_transfer
+ * structure which was used to setup and submit the transfer. At completion
+ * time, libusb has populated this structure with results of the transfer:
+ * success or failure reason, number of bytes of data transferred, etc. See
+ * the libusb_transfer structure documentation for more information.
+ *
+ * <b>Important Note</b>: The user-specified callback is called from an event
+ * handling context. It is therefore important that no calls are made into
+ * libusb that will attempt to perform any event handling. Examples of such
+ * functions are any listed in the \ref libusb_syncio "synchronous API" and any of
+ * the blocking functions that retrieve \ref libusb_desc "USB descriptors".
+ *
+ * \subsection Deallocation
+ *
+ * When a transfer has completed (i.e. the callback function has been invoked),
+ * you are advised to free the transfer (unless you wish to resubmit it, see
+ * below). Transfers are deallocated with libusb_free_transfer().
+ *
+ * It is undefined behaviour to free a transfer which has not completed.
+ *
+ * \section asyncresubmit Resubmission
+ *
+ * You may be wondering why allocation, filling, and submission are all
+ * separated above where they could reasonably be combined into a single
+ * operation.
+ *
+ * The reason for separation is to allow you to resubmit transfers without
+ * having to allocate new ones every time. This is especially useful for
+ * common situations dealing with interrupt endpoints - you allocate one
+ * transfer, fill and submit it, and when it returns with results you just
+ * resubmit it for the next interrupt.
+ *
+ * \section asynccancel Cancellation
+ *
+ * Another advantage of using the asynchronous interface is that you have
+ * the ability to cancel transfers which have not yet completed. This is
+ * done by calling the libusb_cancel_transfer() function.
+ *
+ * libusb_cancel_transfer() is asynchronous/non-blocking in itself. When the
+ * cancellation actually completes, the transfer's callback function will
+ * be invoked, and the callback function should check the transfer status to
+ * determine that it was cancelled.
+ *
+ * Freeing the transfer after it has been cancelled but before cancellation
+ * has completed will result in undefined behaviour.
+ *
+ * When a transfer is cancelled, some of the data may have been transferred.
+ * libusb will communicate this to you in the transfer callback. Do not assume
+ * that no data was transferred.
+ *
+ * \section bulk_overflows Overflows on device-to-host bulk/interrupt endpoints
+ *
+ * If your device does not have predictable transfer sizes (or it misbehaves),
+ * your application may submit a request for data on an IN endpoint which is
+ * smaller than the data that the device wishes to send. In some circumstances
+ * this will cause an overflow, which is a nasty condition to deal with. See
+ * the \ref libusb_packetoverflow page for discussion.
+ *
+ * \section asyncctrl Considerations for control transfers
+ *
+ * The <tt>libusb_transfer</tt> structure is generic and hence does not
+ * include specific fields for the control-specific setup packet structure.
+ *
+ * In order to perform a control transfer, you must place the 8-byte setup
+ * packet at the start of the data buffer. To simplify this, you could
+ * cast the buffer pointer to type struct libusb_control_setup, or you can
+ * use the helper function libusb_fill_control_setup().
+ *
+ * The wLength field placed in the setup packet must be the length you would
+ * expect to be sent in the setup packet: the length of the payload that
+ * follows (or the expected maximum number of bytes to receive). However,
+ * the length field of the libusb_transfer object must be the length of
+ * the data buffer - i.e. it should be wLength <em>plus</em> the size of
+ * the setup packet (LIBUSB_CONTROL_SETUP_SIZE).
+ *
+ * If you use the helper functions, this is simplified for you:
+ * -# Allocate a buffer of size LIBUSB_CONTROL_SETUP_SIZE plus the size of the
+ * data you are sending/requesting.
+ * -# Call libusb_fill_control_setup() on the data buffer, using the transfer
+ * request size as the wLength value (i.e. do not include the extra space you
+ * allocated for the control setup).
+ * -# If this is a host-to-device transfer, place the data to be transferred
+ * in the data buffer, starting at offset LIBUSB_CONTROL_SETUP_SIZE.
+ * -# Call libusb_fill_control_transfer() to associate the data buffer with
+ * the transfer (and to set the remaining details such as callback and timeout).
+ * - Note that there is no parameter to set the length field of the transfer.
+ * The length is automatically inferred from the wLength field of the setup
+ * packet.
+ * -# Submit the transfer.
+ *
+ * The multi-byte control setup fields (wValue, wIndex and wLength) must
+ * be given in little-endian byte order (the endianness of the USB bus).
+ * Endianness conversion is transparently handled by
+ * libusb_fill_control_setup() which is documented to accept host-endian
+ * values.
+ *
+ * Further considerations are needed when handling transfer completion in
+ * your callback function:
+ * - As you might expect, the setup packet will still be sitting at the start
+ * of the data buffer.
+ * - If this was a device-to-host transfer, the received data will be sitting
+ * at offset LIBUSB_CONTROL_SETUP_SIZE into the buffer.
+ * - The actual_length field of the transfer structure is relative to the
+ * wLength of the setup packet, rather than the size of the data buffer. So,
+ * if your wLength was 4, your transfer's <tt>length</tt> was 12, then you
+ * should expect an <tt>actual_length</tt> of 4 to indicate that the data was
+ * transferred in entirity.
+ *
+ * To simplify parsing of setup packets and obtaining the data from the
+ * correct offset, you may wish to use the libusb_control_transfer_get_data()
+ * and libusb_control_transfer_get_setup() functions within your transfer
+ * callback.
+ *
+ * Even though control endpoints do not halt, a completed control transfer
+ * may have a LIBUSB_TRANSFER_STALL status code. This indicates the control
+ * request was not supported.
+ *
+ * \section asyncintr Considerations for interrupt transfers
+ *
+ * All interrupt transfers are performed using the polling interval presented
+ * by the bInterval value of the endpoint descriptor.
+ *
+ * \section asynciso Considerations for isochronous transfers
+ *
+ * Isochronous transfers are more complicated than transfers to
+ * non-isochronous endpoints.
+ *
+ * To perform I/O to an isochronous endpoint, allocate the transfer by calling
+ * libusb_alloc_transfer() with an appropriate number of isochronous packets.
+ *
+ * During filling, set \ref libusb_transfer::type "type" to
+ * \ref libusb_transfer_type::LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
+ * "LIBUSB_TRANSFER_TYPE_ISOCHRONOUS", and set
+ * \ref libusb_transfer::num_iso_packets "num_iso_packets" to a value less than
+ * or equal to the number of packets you requested during allocation.
+ * libusb_alloc_transfer() does not set either of these fields for you, given
+ * that you might not even use the transfer on an isochronous endpoint.
+ *
+ * Next, populate the length field for the first num_iso_packets entries in
+ * the \ref libusb_transfer::iso_packet_desc "iso_packet_desc" array. Section
+ * 5.6.3 of the USB2 specifications describe how the maximum isochronous
+ * packet length is determined by the wMaxPacketSize field in the endpoint
+ * descriptor.
+ * Two functions can help you here:
+ *
+ * - libusb_get_max_iso_packet_size() is an easy way to determine the max
+ * packet size for an isochronous endpoint. Note that the maximum packet
+ * size is actually the maximum number of bytes that can be transmitted in
+ * a single microframe, therefore this function multiplies the maximum number
+ * of bytes per transaction by the number of transaction opportunities per
+ * microframe.
+ * - libusb_set_iso_packet_lengths() assigns the same length to all packets
+ * within a transfer, which is usually what you want.
+ *
+ * For outgoing transfers, you'll obviously fill the buffer and populate the
+ * packet descriptors in hope that all the data gets transferred. For incoming
+ * transfers, you must ensure the buffer has sufficient capacity for
+ * the situation where all packets transfer the full amount of requested data.
+ *
+ * Completion handling requires some extra consideration. The
+ * \ref libusb_transfer::actual_length "actual_length" field of the transfer
+ * is meaningless and should not be examined; instead you must refer to the
+ * \ref libusb_iso_packet_descriptor::actual_length "actual_length" field of
+ * each individual packet.
+ *
+ * The \ref libusb_transfer::status "status" field of the transfer is also a
+ * little misleading:
+ * - If the packets were submitted and the isochronous data microframes
+ * completed normally, status will have value
+ * \ref libusb_transfer_status::LIBUSB_TRANSFER_COMPLETED
+ * "LIBUSB_TRANSFER_COMPLETED". Note that bus errors and software-incurred
+ * delays are not counted as transfer errors; the transfer.status field may
+ * indicate COMPLETED even if some or all of the packets failed. Refer to
+ * the \ref libusb_iso_packet_descriptor::status "status" field of each
+ * individual packet to determine packet failures.
+ * - The status field will have value
+ * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR
+ * "LIBUSB_TRANSFER_ERROR" only when serious errors were encountered.
+ * - Other transfer status codes occur with normal behaviour.
+ *
+ * The data for each packet will be found at an offset into the buffer that
+ * can be calculated as if each prior packet completed in full. The
+ * libusb_get_iso_packet_buffer() and libusb_get_iso_packet_buffer_simple()
+ * functions may help you here.
+ *
+ * <b>Note</b>: Some operating systems (e.g. Linux) may impose limits on the
+ * length of individual isochronous packets and/or the total length of the
+ * isochronous transfer. Such limits can be difficult for libusb to detect,
+ * so the library will simply try and submit the transfer as set up by you.
+ * If the transfer fails to submit because it is too large,
+ * libusb_submit_transfer() will return
+ * \ref libusb_error::LIBUSB_ERROR_INVALID_PARAM "LIBUSB_ERROR_INVALID_PARAM".
+ *
+ * \section asyncmem Memory caveats
+ *
+ * In most circumstances, it is not safe to use stack memory for transfer
+ * buffers. This is because the function that fired off the asynchronous
+ * transfer may return before libusb has finished using the buffer, and when
+ * the function returns it's stack gets destroyed. This is true for both
+ * host-to-device and device-to-host transfers.
+ *
+ * The only case in which it is safe to use stack memory is where you can
+ * guarantee that the function owning the stack space for the buffer does not
+ * return until after the transfer's callback function has completed. In every
+ * other case, you need to use heap memory instead.
+ *
+ * \section asyncflags Fine control
+ *
+ * Through using this asynchronous interface, you may find yourself repeating
+ * a few simple operations many times. You can apply a bitwise OR of certain
+ * flags to a transfer to simplify certain things:
+ * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_SHORT_NOT_OK
+ * "LIBUSB_TRANSFER_SHORT_NOT_OK" results in transfers which transferred
+ * less than the requested amount of data being marked with status
+ * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR "LIBUSB_TRANSFER_ERROR"
+ * (they would normally be regarded as COMPLETED)
+ * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER
+ * "LIBUSB_TRANSFER_FREE_BUFFER" allows you to ask libusb to free the transfer
+ * buffer when freeing the transfer.
+ * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_TRANSFER
+ * "LIBUSB_TRANSFER_FREE_TRANSFER" causes libusb to automatically free the
+ * transfer after the transfer callback returns.
+ *
+ * \section asyncevent Event handling
+ *
+ * An asynchronous model requires that libusb perform work at various
+ * points in time - namely processing the results of previously-submitted
+ * transfers and invoking the user-supplied callback function.
+ *
+ * This gives rise to the libusb_handle_events() function which your
+ * application must call into when libusb has work do to. This gives libusb
+ * the opportunity to reap pending transfers, invoke callbacks, etc.
+ *
+ * There are 2 different approaches to dealing with libusb_handle_events:
+ *
+ * -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated
+ * thread.
+ * -# Integrate libusb with your application's main event loop. libusb
+ * exposes a set of file descriptors which allow you to do this.
+ *
+ * The first approach has the big advantage that it will also work on Windows
+ * were libusb' poll API for select / poll integration is not available. So
+ * if you want to support Windows and use the async API, you must use this
+ * approach, see the \ref eventthread "Using an event handling thread" section
+ * below for details.
+ *
+ * If you prefer a single threaded approach with a single central event loop,
+ * see the \ref libusb_poll "polling and timing" section for how to integrate libusb
+ * into your application's main event loop.
+ *
+ * \section eventthread Using an event handling thread
+ *
+ * Lets begin with stating the obvious: If you're going to use a separate
+ * thread for libusb event handling, your callback functions MUST be
+ * threadsafe.
+ *
+ * Other then that doing event handling from a separate thread, is mostly
+ * simple. You can use an event thread function as follows:
+\code
+void *event_thread_func(void *ctx)
+{
+ while (event_thread_run)
+ libusb_handle_events(ctx);
+
+ return NULL;
+}
+\endcode
+ *
+ * There is one caveat though, stopping this thread requires setting the
+ * event_thread_run variable to 0, and after that libusb_handle_events() needs
+ * to return control to event_thread_func. But unless some event happens,
+ * libusb_handle_events() will not return.
+ *
+ * There are 2 different ways of dealing with this, depending on if your
+ * application uses libusb' \ref libusb_hotplug "hotplug" support or not.
+ *
+ * Applications which do not use hotplug support, should not start the event
+ * thread until after their first call to libusb_open(), and should stop the
+ * thread when closing the last open device as follows:
+\code
+void my_close_handle(libusb_device_handle *dev_handle)
+{
+ if (open_devs == 1)
+ event_thread_run = 0;
+
+ libusb_close(dev_handle); // This wakes up libusb_handle_events()
+
+ if (open_devs == 1)
+ pthread_join(event_thread);
+
+ open_devs--;
+}
+\endcode
+ *
+ * Applications using hotplug support should start the thread at program init,
+ * after having successfully called libusb_hotplug_register_callback(), and
+ * should stop the thread at program exit as follows:
+\code
+void my_libusb_exit(void)
+{
+ event_thread_run = 0;
+ libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events()
+ pthread_join(event_thread);
+ libusb_exit(ctx);
+}
+\endcode
+ */
+
+/**
+ * @defgroup libusb_poll Polling and timing
+ *
+ * This page documents libusb's functions for polling events and timing.
+ * These functions are only necessary for users of the
+ * \ref libusb_asyncio "asynchronous API". If you are only using the simpler
+ * \ref libusb_syncio "synchronous API" then you do not need to ever call these
+ * functions.
+ *
+ * The justification for the functionality described here has already been
+ * discussed in the \ref asyncevent "event handling" section of the
+ * asynchronous API documentation. In summary, libusb does not create internal
+ * threads for event processing and hence relies on your application calling
+ * into libusb at certain points in time so that pending events can be handled.
+ *
+ * Your main loop is probably already calling poll() or select() or a
+ * variant on a set of file descriptors for other event sources (e.g. keyboard
+ * button presses, mouse movements, network sockets, etc). You then add
+ * libusb's file descriptors to your poll()/select() calls, and when activity
+ * is detected on such descriptors you know it is time to call
+ * libusb_handle_events().
+ *
+ * There is one final event handling complication. libusb supports
+ * asynchronous transfers which time out after a specified time period.
+ *
+ * On some platforms a timerfd is used, so the timeout handling is just another
+ * fd, on other platforms this requires that libusb is called into at or after
+ * the timeout to handle it. So, in addition to considering libusb's file
+ * descriptors in your main event loop, you must also consider that libusb
+ * sometimes needs to be called into at fixed points in time even when there
+ * is no file descriptor activity, see \ref polltime details.
+ *
+ * In order to know precisely when libusb needs to be called into, libusb
+ * offers you a set of pollable file descriptors and information about when
+ * the next timeout expires.
+ *
+ * If you are using the asynchronous I/O API, you must take one of the two
+ * following options, otherwise your I/O will not complete.
+ *
+ * \section pollsimple The simple option
+ *
+ * If your application revolves solely around libusb and does not need to
+ * handle other event sources, you can have a program structure as follows:
+\code
+// initialize libusb
+// find and open device
+// maybe fire off some initial async I/O
+
+while (user_has_not_requested_exit)
+ libusb_handle_events(ctx);
+
+// clean up and exit
+\endcode
+ *
+ * With such a simple main loop, you do not have to worry about managing
+ * sets of file descriptors or handling timeouts. libusb_handle_events() will
+ * handle those details internally.
+ *
+ * \section libusb_pollmain The more advanced option
+ *
+ * \note This functionality is currently only available on Unix-like platforms.
+ * On Windows, libusb_get_pollfds() simply returns NULL. Applications which
+ * want to support Windows are advised to use an \ref eventthread
+ * "event handling thread" instead.
+ *
+ * In more advanced applications, you will already have a main loop which
+ * is monitoring other event sources: network sockets, X11 events, mouse
+ * movements, etc. Through exposing a set of file descriptors, libusb is
+ * designed to cleanly integrate into such main loops.
+ *
+ * In addition to polling file descriptors for the other event sources, you
+ * take a set of file descriptors from libusb and monitor those too. When you
+ * detect activity on libusb's file descriptors, you call
+ * libusb_handle_events_timeout() in non-blocking mode.
+ *
+ * What's more, libusb may also need to handle events at specific moments in
+ * time. No file descriptor activity is generated at these times, so your
+ * own application needs to be continually aware of when the next one of these
+ * moments occurs (through calling libusb_get_next_timeout()), and then it
+ * needs to call libusb_handle_events_timeout() in non-blocking mode when
+ * these moments occur. This means that you need to adjust your
+ * poll()/select() timeout accordingly.
+ *
+ * libusb provides you with a set of file descriptors to poll and expects you
+ * to poll all of them, treating them as a single entity. The meaning of each
+ * file descriptor in the set is an internal implementation detail,
+ * platform-dependent and may vary from release to release. Don't try and
+ * interpret the meaning of the file descriptors, just do as libusb indicates,
+ * polling all of them at once.
+ *
+ * In pseudo-code, you want something that looks like:
+\code
+// initialise libusb
+
+libusb_get_pollfds(ctx)
+while (user has not requested application exit) {
+ libusb_get_next_timeout(ctx);
+ poll(on libusb file descriptors plus any other event sources of interest,
+ using a timeout no larger than the value libusb just suggested)
+ if (poll() indicated activity on libusb file descriptors)
+ libusb_handle_events_timeout(ctx, &zero_tv);
+ if (time has elapsed to or beyond the libusb timeout)
+ libusb_handle_events_timeout(ctx, &zero_tv);
+ // handle events from other sources here
+}
+
+// clean up and exit
+\endcode
+ *
+ * \subsection polltime Notes on time-based events
+ *
+ * The above complication with having to track time and call into libusb at
+ * specific moments is a bit of a headache. For maximum compatibility, you do
+ * need to write your main loop as above, but you may decide that you can
+ * restrict the supported platforms of your application and get away with
+ * a more simplistic scheme.
+ *
+ * These time-based event complications are \b not required on the following
+ * platforms:
+ * - Darwin
+ * - Linux, provided that the following version requirements are satisfied:
+ * - Linux v2.6.27 or newer, compiled with timerfd support
+ * - glibc v2.9 or newer
+ * - libusb v1.0.5 or newer
+ *
+ * Under these configurations, libusb_get_next_timeout() will \em always return
+ * 0, so your main loop can be simplified to:
+\code
+// initialise libusb
+
+libusb_get_pollfds(ctx)
+while (user has not requested application exit) {
+ poll(on libusb file descriptors plus any other event sources of interest,
+ using any timeout that you like)
+ if (poll() indicated activity on libusb file descriptors)
+ libusb_handle_events_timeout(ctx, &zero_tv);
+ // handle events from other sources here
+}
+
+// clean up and exit
+\endcode
+ *
+ * Do remember that if you simplify your main loop to the above, you will
+ * lose compatibility with some platforms (including legacy Linux platforms,
+ * and <em>any future platforms supported by libusb which may have time-based
+ * event requirements</em>). The resultant problems will likely appear as
+ * strange bugs in your application.
+ *
+ * You can use the libusb_pollfds_handle_timeouts() function to do a runtime
+ * check to see if it is safe to ignore the time-based event complications.
+ * If your application has taken the shortcut of ignoring libusb's next timeout
+ * in your main loop, then you are advised to check the return value of
+ * libusb_pollfds_handle_timeouts() during application startup, and to abort
+ * if the platform does suffer from these timing complications.
+ *
+ * \subsection fdsetchange Changes in the file descriptor set
+ *
+ * The set of file descriptors that libusb uses as event sources may change
+ * during the life of your application. Rather than having to repeatedly
+ * call libusb_get_pollfds(), you can set up notification functions for when
+ * the file descriptor set changes using libusb_set_pollfd_notifiers().
+ *
+ * \subsection mtissues Multi-threaded considerations
+ *
+ * Unfortunately, the situation is complicated further when multiple threads
+ * come into play. If two threads are monitoring the same file descriptors,
+ * the fact that only one thread will be woken up when an event occurs causes
+ * some headaches.
+ *
+ * The events lock, event waiters lock, and libusb_handle_events_locked()
+ * entities are added to solve these problems. You do not need to be concerned
+ * with these entities otherwise.
+ *
+ * See the extra documentation: \ref libusb_mtasync
+ */
+
+/** \page libusb_mtasync Multi-threaded applications and asynchronous I/O
+ *
+ * libusb is a thread-safe library, but extra considerations must be applied
+ * to applications which interact with libusb from multiple threads.
+ *
+ * The underlying issue that must be addressed is that all libusb I/O
+ * revolves around monitoring file descriptors through the poll()/select()
+ * system calls. This is directly exposed at the
+ * \ref libusb_asyncio "asynchronous interface" but it is important to note that the
+ * \ref libusb_syncio "synchronous interface" is implemented on top of the
+ * asynchonrous interface, therefore the same considerations apply.
+ *
+ * The issue is that if two or more threads are concurrently calling poll()
+ * or select() on libusb's file descriptors then only one of those threads
+ * will be woken up when an event arrives. The others will be completely
+ * oblivious that anything has happened.
+ *
+ * Consider the following pseudo-code, which submits an asynchronous transfer
+ * then waits for its completion. This style is one way you could implement a
+ * synchronous interface on top of the asynchronous interface (and libusb
+ * does something similar, albeit more advanced due to the complications
+ * explained on this page).
+ *
+\code
+void cb(struct libusb_transfer *transfer)
+{
+ int *completed = transfer->user_data;
+ *completed = 1;
+}
+
+void myfunc() {
+ struct libusb_transfer *transfer;
+ unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE] __attribute__ ((aligned (2)));
+ int completed = 0;
+
+ transfer = libusb_alloc_transfer(0);
+ libusb_fill_control_setup(buffer,
+ LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, 0x04, 0x01, 0, 0);
+ libusb_fill_control_transfer(transfer, dev, buffer, cb, &completed, 1000);
+ libusb_submit_transfer(transfer);
+
+ while (!completed) {
+ poll(libusb file descriptors, 120*1000);
+ if (poll indicates activity)
+ libusb_handle_events_timeout(ctx, &zero_tv);
+ }
+ printf("completed!");
+ // other code here
+}
+\endcode
+ *
+ * Here we are <em>serializing</em> completion of an asynchronous event
+ * against a condition - the condition being completion of a specific transfer.
+ * The poll() loop has a long timeout to minimize CPU usage during situations
+ * when nothing is happening (it could reasonably be unlimited).
+ *
+ * If this is the only thread that is polling libusb's file descriptors, there
+ * is no problem: there is no danger that another thread will swallow up the
+ * event that we are interested in. On the other hand, if there is another
+ * thread polling the same descriptors, there is a chance that it will receive
+ * the event that we were interested in. In this situation, <tt>myfunc()</tt>
+ * will only realise that the transfer has completed on the next iteration of
+ * the loop, <em>up to 120 seconds later.</em> Clearly a two-minute delay is
+ * undesirable, and don't even think about using short timeouts to circumvent
+ * this issue!
+ *
+ * The solution here is to ensure that no two threads are ever polling the
+ * file descriptors at the same time. A naive implementation of this would
+ * impact the capabilities of the library, so libusb offers the scheme
+ * documented below to ensure no loss of functionality.
+ *
+ * Before we go any further, it is worth mentioning that all libusb-wrapped
+ * event handling procedures fully adhere to the scheme documented below.
+ * This includes libusb_handle_events() and its variants, and all the
+ * synchronous I/O functions - libusb hides this headache from you.
+ *
+ * \section Using libusb_handle_events() from multiple threads
+ *
+ * Even when only using libusb_handle_events() and synchronous I/O functions,
+ * you can still have a race condition. You might be tempted to solve the
+ * above with libusb_handle_events() like so:
+ *
+\code
+ libusb_submit_transfer(transfer);
+
+ while (!completed) {
+ libusb_handle_events(ctx);
+ }
+ printf("completed!");
+\endcode
+ *
+ * This however has a race between the checking of completed and
+ * libusb_handle_events() acquiring the events lock, so another thread
+ * could have completed the transfer, resulting in this thread hanging
+ * until either a timeout or another event occurs. See also commit
+ * 6696512aade99bb15d6792af90ae329af270eba6 which fixes this in the
+ * synchronous API implementation of libusb.
+ *
+ * Fixing this race requires checking the variable completed only after
+ * taking the event lock, which defeats the concept of just calling
+ * libusb_handle_events() without worrying about locking. This is why
+ * libusb-1.0.9 introduces the new libusb_handle_events_timeout_completed()
+ * and libusb_handle_events_completed() functions, which handles doing the
+ * completion check for you after they have acquired the lock:
+ *
+\code
+ libusb_submit_transfer(transfer);
+
+ while (!completed) {
+ libusb_handle_events_completed(ctx, &completed);
+ }
+ printf("completed!");
+\endcode
+ *
+ * This nicely fixes the race in our example. Note that if all you want to
+ * do is submit a single transfer and wait for its completion, then using
+ * one of the synchronous I/O functions is much easier.
+ *
+ * \section eventlock The events lock
+ *
+ * The problem is when we consider the fact that libusb exposes file
+ * descriptors to allow for you to integrate asynchronous USB I/O into
+ * existing main loops, effectively allowing you to do some work behind
+ * libusb's back. If you do take libusb's file descriptors and pass them to
+ * poll()/select() yourself, you need to be aware of the associated issues.
+ *
+ * The first concept to be introduced is the events lock. The events lock
+ * is used to serialize threads that want to handle events, such that only
+ * one thread is handling events at any one time.
+ *
+ * You must take the events lock before polling libusb file descriptors,
+ * using libusb_lock_events(). You must release the lock as soon as you have
+ * aborted your poll()/select() loop, using libusb_unlock_events().
+ *
+ * \section threadwait Letting other threads do the work for you
+ *
+ * Although the events lock is a critical part of the solution, it is not
+ * enough on it's own. You might wonder if the following is sufficient...
+\code
+ libusb_lock_events(ctx);
+ while (!completed) {
+ poll(libusb file descriptors, 120*1000);
+ if (poll indicates activity)
+ libusb_handle_events_timeout(ctx, &zero_tv);
+ }
+ libusb_unlock_events(ctx);
+\endcode
+ * ...and the answer is that it is not. This is because the transfer in the
+ * code shown above may take a long time (say 30 seconds) to complete, and
+ * the lock is not released until the transfer is completed.
+ *
+ * Another thread with similar code that wants to do event handling may be
+ * working with a transfer that completes after a few milliseconds. Despite
+ * having such a quick completion time, the other thread cannot check that
+ * status of its transfer until the code above has finished (30 seconds later)
+ * due to contention on the lock.
+ *
+ * To solve this, libusb offers you a mechanism to determine when another
+ * thread is handling events. It also offers a mechanism to block your thread
+ * until the event handling thread has completed an event (and this mechanism
+ * does not involve polling of file descriptors).
+ *
+ * After determining that another thread is currently handling events, you
+ * obtain the <em>event waiters</em> lock using libusb_lock_event_waiters().
+ * You then re-check that some other thread is still handling events, and if
+ * so, you call libusb_wait_for_event().
+ *
+ * libusb_wait_for_event() puts your application to sleep until an event
+ * occurs, or until a thread releases the events lock. When either of these
+ * things happen, your thread is woken up, and should re-check the condition
+ * it was waiting on. It should also re-check that another thread is handling
+ * events, and if not, it should start handling events itself.
+ *
+ * This looks like the following, as pseudo-code:
+\code
+retry:
+if (libusb_try_lock_events(ctx) == 0) {
+ // we obtained the event lock: do our own event handling
+ while (!completed) {
+ if (!libusb_event_handling_ok(ctx)) {
+ libusb_unlock_events(ctx);
+ goto retry;
+ }
+ poll(libusb file descriptors, 120*1000);
+ if (poll indicates activity)
+ libusb_handle_events_locked(ctx, 0);
+ }
+ libusb_unlock_events(ctx);
+} else {
+ // another thread is doing event handling. wait for it to signal us that
+ // an event has completed
+ libusb_lock_event_waiters(ctx);
+
+ while (!completed) {
+ // now that we have the event waiters lock, double check that another
+ // thread is still handling events for us. (it may have ceased handling
+ // events in the time it took us to reach this point)
+ if (!libusb_event_handler_active(ctx)) {
+ // whoever was handling events is no longer doing so, try again
+ libusb_unlock_event_waiters(ctx);
+ goto retry;
+ }
+
+ libusb_wait_for_event(ctx, NULL);
+ }
+ libusb_unlock_event_waiters(ctx);
+}
+printf("completed!\n");
+\endcode
+ *
+ * A naive look at the above code may suggest that this can only support
+ * one event waiter (hence a total of 2 competing threads, the other doing
+ * event handling), because the event waiter seems to have taken the event
+ * waiters lock while waiting for an event. However, the system does support
+ * multiple event waiters, because libusb_wait_for_event() actually drops
+ * the lock while waiting, and reaquires it before continuing.
+ *
+ * We have now implemented code which can dynamically handle situations where
+ * nobody is handling events (so we should do it ourselves), and it can also
+ * handle situations where another thread is doing event handling (so we can
+ * piggyback onto them). It is also equipped to handle a combination of
+ * the two, for example, another thread is doing event handling, but for
+ * whatever reason it stops doing so before our condition is met, so we take
+ * over the event handling.
+ *
+ * Four functions were introduced in the above pseudo-code. Their importance
+ * should be apparent from the code shown above.
+ * -# libusb_try_lock_events() is a non-blocking function which attempts
+ * to acquire the events lock but returns a failure code if it is contended.
+ * -# libusb_event_handling_ok() checks that libusb is still happy for your
+ * thread to be performing event handling. Sometimes, libusb needs to
+ * interrupt the event handler, and this is how you can check if you have
+ * been interrupted. If this function returns 0, the correct behaviour is
+ * for you to give up the event handling lock, and then to repeat the cycle.
+ * The following libusb_try_lock_events() will fail, so you will become an
+ * events waiter. For more information on this, read \ref fullstory below.
+ * -# libusb_handle_events_locked() is a variant of
+ * libusb_handle_events_timeout() that you can call while holding the
+ * events lock. libusb_handle_events_timeout() itself implements similar
+ * logic to the above, so be sure not to call it when you are
+ * "working behind libusb's back", as is the case here.
+ * -# libusb_event_handler_active() determines if someone is currently
+ * holding the events lock
+ *
+ * You might be wondering why there is no function to wake up all threads
+ * blocked on libusb_wait_for_event(). This is because libusb can do this
+ * internally: it will wake up all such threads when someone calls
+ * libusb_unlock_events() or when a transfer completes (at the point after its
+ * callback has returned).
+ *
+ * \subsection fullstory The full story
+ *
+ * The above explanation should be enough to get you going, but if you're
+ * really thinking through the issues then you may be left with some more
+ * questions regarding libusb's internals. If you're curious, read on, and if
+ * not, skip to the next section to avoid confusing yourself!
+ *
+ * The immediate question that may spring to mind is: what if one thread
+ * modifies the set of file descriptors that need to be polled while another
+ * thread is doing event handling?
+ *
+ * There are 2 situations in which this may happen.
+ * -# libusb_open() will add another file descriptor to the poll set,
+ * therefore it is desirable to interrupt the event handler so that it
+ * restarts, picking up the new descriptor.
+ * -# libusb_close() will remove a file descriptor from the poll set. There
+ * are all kinds of race conditions that could arise here, so it is
+ * important that nobody is doing event handling at this time.
+ *
+ * libusb handles these issues internally, so application developers do not
+ * have to stop their event handlers while opening/closing devices. Here's how
+ * it works, focusing on the libusb_close() situation first:
+ *
+ * -# During initialization, libusb opens an internal pipe, and it adds the read
+ * end of this pipe to the set of file descriptors to be polled.
+ * -# During libusb_close(), libusb writes some dummy data on this event pipe.
+ * This immediately interrupts the event handler. libusb also records
+ * internally that it is trying to interrupt event handlers for this
+ * high-priority event.
+ * -# At this point, some of the functions described above start behaving
+ * differently:
+ * - libusb_event_handling_ok() starts returning 1, indicating that it is NOT
+ * OK for event handling to continue.
+ * - libusb_try_lock_events() starts returning 1, indicating that another
+ * thread holds the event handling lock, even if the lock is uncontended.
+ * - libusb_event_handler_active() starts returning 1, indicating that
+ * another thread is doing event handling, even if that is not true.
+ * -# The above changes in behaviour result in the event handler stopping and
+ * giving up the events lock very quickly, giving the high-priority
+ * libusb_close() operation a "free ride" to acquire the events lock. All
+ * threads that are competing to do event handling become event waiters.
+ * -# With the events lock held inside libusb_close(), libusb can safely remove
+ * a file descriptor from the poll set, in the safety of knowledge that
+ * nobody is polling those descriptors or trying to access the poll set.
+ * -# After obtaining the events lock, the close operation completes very
+ * quickly (usually a matter of milliseconds) and then immediately releases
+ * the events lock.
+ * -# At the same time, the behaviour of libusb_event_handling_ok() and friends
+ * reverts to the original, documented behaviour.
+ * -# The release of the events lock causes the threads that are waiting for
+ * events to be woken up and to start competing to become event handlers
+ * again. One of them will succeed; it will then re-obtain the list of poll
+ * descriptors, and USB I/O will then continue as normal.
+ *
+ * libusb_open() is similar, and is actually a more simplistic case. Upon a
+ * call to libusb_open():
+ *
+ * -# The device is opened and a file descriptor is added to the poll set.
+ * -# libusb sends some dummy data on the event pipe, and records that it
+ * is trying to modify the poll descriptor set.
+ * -# The event handler is interrupted, and the same behaviour change as for
+ * libusb_close() takes effect, causing all event handling threads to become
+ * event waiters.
+ * -# The libusb_open() implementation takes its free ride to the events lock.
+ * -# Happy that it has successfully paused the events handler, libusb_open()
+ * releases the events lock.
+ * -# The event waiter threads are all woken up and compete to become event
+ * handlers again. The one that succeeds will obtain the list of poll
+ * descriptors again, which will include the addition of the new device.
+ *
+ * \subsection concl Closing remarks
+ *
+ * The above may seem a little complicated, but hopefully I have made it clear
+ * why such complications are necessary. Also, do not forget that this only
+ * applies to applications that take libusb's file descriptors and integrate
+ * them into their own polling loops.
+ *
+ * You may decide that it is OK for your multi-threaded application to ignore
+ * some of the rules and locks detailed above, because you don't think that
+ * two threads can ever be polling the descriptors at the same time. If that
+ * is the case, then that's good news for you because you don't have to worry.
+ * But be careful here; remember that the synchronous I/O functions do event
+ * handling internally. If you have one thread doing event handling in a loop
+ * (without implementing the rules and locking semantics documented above)
+ * and another trying to send a synchronous USB transfer, you will end up with
+ * two threads monitoring the same descriptors, and the above-described
+ * undesirable behaviour occurring. The solution is for your polling thread to
+ * play by the rules; the synchronous I/O functions do so, and this will result
+ * in them getting along in perfect harmony.
+ *
+ * If you do have a dedicated thread doing event handling, it is perfectly
+ * legal for it to take the event handling lock for long periods of time. Any
+ * synchronous I/O functions you call from other threads will transparently
+ * fall back to the "event waiters" mechanism detailed above. The only
+ * consideration that your event handling thread must apply is the one related
+ * to libusb_event_handling_ok(): you must call this before every poll(), and
+ * give up the events lock if instructed.
+ */
+
+int usbi_io_init(struct libusb_context *ctx)
+{
+ int r;
+
+ usbi_mutex_init(&ctx->flying_transfers_lock);
+ usbi_mutex_init(&ctx->events_lock);
+ usbi_mutex_init(&ctx->event_waiters_lock);
+ usbi_cond_init(&ctx->event_waiters_cond);
+ usbi_mutex_init(&ctx->event_data_lock);
+ usbi_tls_key_create(&ctx->event_handling_key);
+ list_init(&ctx->flying_transfers);
+ list_init(&ctx->ipollfds);
+ list_init(&ctx->removed_ipollfds);
+ list_init(&ctx->hotplug_msgs);
+ list_init(&ctx->completed_transfers);
+
+ /* FIXME should use an eventfd on kernels that support it */
+ r = usbi_pipe(ctx->event_pipe);
+ if (r < 0) {
+ r = LIBUSB_ERROR_OTHER;
+ goto err;
+ }
+
+ r = usbi_add_pollfd(ctx, ctx->event_pipe[0], POLLIN);
+ if (r < 0)
+ goto err_close_pipe;
+
+#ifdef USBI_TIMERFD_AVAILABLE
+ ctx->timerfd = timerfd_create(usbi_backend.get_timerfd_clockid(),
+ TFD_NONBLOCK | TFD_CLOEXEC);
+ if (ctx->timerfd >= 0) {
+ usbi_dbg("using timerfd for timeouts");
+ r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN);
+ if (r < 0)
+ goto err_close_timerfd;
+ } else {
+ usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno);
+ ctx->timerfd = -1;
+ }
+#endif
+
+ return 0;
+
+#ifdef USBI_TIMERFD_AVAILABLE
+err_close_timerfd:
+ close(ctx->timerfd);
+ usbi_remove_pollfd(ctx, ctx->event_pipe[0]);
+#endif
+err_close_pipe:
+ usbi_close(ctx->event_pipe[0]);
+ usbi_close(ctx->event_pipe[1]);
+err:
+ usbi_mutex_destroy(&ctx->flying_transfers_lock);
+ usbi_mutex_destroy(&ctx->events_lock);
+ usbi_mutex_destroy(&ctx->event_waiters_lock);
+ usbi_cond_destroy(&ctx->event_waiters_cond);
+ usbi_mutex_destroy(&ctx->event_data_lock);
+ usbi_tls_key_delete(ctx->event_handling_key);
+ return r;
+}
+
+static void cleanup_removed_pollfds(struct libusb_context *ctx)
+{
+ struct usbi_pollfd *ipollfd, *tmp;
+ list_for_each_entry_safe(ipollfd, tmp, &ctx->removed_ipollfds, list, struct usbi_pollfd) {
+ list_del(&ipollfd->list);
+ free(ipollfd);
+ }
+}
+
+void usbi_io_exit(struct libusb_context *ctx)
+{
+ usbi_remove_pollfd(ctx, ctx->event_pipe[0]);
+ usbi_close(ctx->event_pipe[0]);
+ usbi_close(ctx->event_pipe[1]);
+#ifdef USBI_TIMERFD_AVAILABLE
+ if (usbi_using_timerfd(ctx)) {
+ usbi_remove_pollfd(ctx, ctx->timerfd);
+ close(ctx->timerfd);
+ }
+#endif
+ usbi_mutex_destroy(&ctx->flying_transfers_lock);
+ usbi_mutex_destroy(&ctx->events_lock);
+ usbi_mutex_destroy(&ctx->event_waiters_lock);
+ usbi_cond_destroy(&ctx->event_waiters_cond);
+ usbi_mutex_destroy(&ctx->event_data_lock);
+ usbi_tls_key_delete(ctx->event_handling_key);
+ free(ctx->pollfds);
+ cleanup_removed_pollfds(ctx);
+}
+
+static int calculate_timeout(struct usbi_transfer *transfer)
+{
+ int r;
+ struct timespec current_time;
+ unsigned int timeout =
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout;
+
+ if (!timeout) {
+ timerclear(&transfer->timeout);
+ return 0;
+ }
+
+ r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, ¤t_time);
+ if (r < 0) {
+ usbi_err(ITRANSFER_CTX(transfer),
+ "failed to read monotonic clock, errno=%d", errno);
+ return r;
+ }
+
+ current_time.tv_sec += timeout / 1000;
+ current_time.tv_nsec += (timeout % 1000) * 1000000;
+
+ while (current_time.tv_nsec >= 1000000000) {
+ current_time.tv_nsec -= 1000000000;
+ current_time.tv_sec++;
+ }
+
+ TIMESPEC_TO_TIMEVAL(&transfer->timeout, ¤t_time);
+ return 0;
+}
+
+/** \ingroup libusb_asyncio
+ * Allocate a libusb transfer with a specified number of isochronous packet
+ * descriptors. The returned transfer is pre-initialized for you. When the new
+ * transfer is no longer needed, it should be freed with
+ * libusb_free_transfer().
+ *
+ * Transfers intended for non-isochronous endpoints (e.g. control, bulk,
+ * interrupt) should specify an iso_packets count of zero.
+ *
+ * For transfers intended for isochronous endpoints, specify an appropriate
+ * number of packet descriptors to be allocated as part of the transfer.
+ * The returned transfer is not specially initialized for isochronous I/O;
+ * you are still required to set the
+ * \ref libusb_transfer::num_iso_packets "num_iso_packets" and
+ * \ref libusb_transfer::type "type" fields accordingly.
+ *
+ * It is safe to allocate a transfer with some isochronous packets and then
+ * use it on a non-isochronous endpoint. If you do this, ensure that at time
+ * of submission, num_iso_packets is 0 and that type is set appropriately.
+ *
+ * \param iso_packets number of isochronous packet descriptors to allocate. Must be non-negative.
+ * \returns a newly allocated transfer, or NULL on error
+ */
+DEFAULT_VISIBILITY
+struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
+ int iso_packets)
+{
+ struct libusb_transfer *transfer;
+ size_t os_alloc_size;
+ size_t alloc_size;
+ struct usbi_transfer *itransfer;
+
+ assert(iso_packets >= 0);
+
+ os_alloc_size = usbi_backend.transfer_priv_size;
+ alloc_size = sizeof(struct usbi_transfer)
+ + sizeof(struct libusb_transfer)
+ + (sizeof(struct libusb_iso_packet_descriptor) * (size_t)iso_packets)
+ + os_alloc_size;
+ itransfer = calloc(1, alloc_size);
+ if (!itransfer)
+ return NULL;
+
+ itransfer->num_iso_packets = iso_packets;
+ usbi_mutex_init(&itransfer->lock);
+ transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ usbi_dbg("transfer %p", transfer);
+ return transfer;
+}
+
+/** \ingroup libusb_asyncio
+ * Free a transfer structure. This should be called for all transfers
+ * allocated with libusb_alloc_transfer().
+ *
+ * If the \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER
+ * "LIBUSB_TRANSFER_FREE_BUFFER" flag is set and the transfer buffer is
+ * non-NULL, this function will also free the transfer buffer using the
+ * standard system memory allocator (e.g. free()).
+ *
+ * It is legal to call this function with a NULL transfer. In this case,
+ * the function will simply return safely.
+ *
+ * It is not legal to free an active transfer (one which has been submitted
+ * and has not yet completed).
+ *
+ * \param transfer the transfer to free
+ */
+void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
+{
+ struct usbi_transfer *itransfer;
+ if (!transfer)
+ return;
+
+ usbi_dbg("transfer %p", transfer);
+ if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
+ free(transfer->buffer);
+
+ itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
+ usbi_mutex_destroy(&itransfer->lock);
+ free(itransfer);
+}
+
+#ifdef USBI_TIMERFD_AVAILABLE
+static int disarm_timerfd(struct libusb_context *ctx)
+{
+ const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } };
+ int r;
+
+ usbi_dbg("");
+ r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL);
+ if (r < 0)
+ return LIBUSB_ERROR_OTHER;
+ else
+ return 0;
+}
+
+/* iterates through the flying transfers, and rearms the timerfd based on the
+ * next upcoming timeout.
+ * must be called with flying_list locked.
+ * returns 0 on success or a LIBUSB_ERROR code on failure.
+ */
+static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
+{
+ struct usbi_transfer *transfer;
+
+ list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
+ struct timeval *cur_tv = &transfer->timeout;
+
+ /* if we've reached transfers of infinite timeout, then we have no
+ * arming to do */
+ if (!timerisset(cur_tv))
+ goto disarm;
+
+ /* act on first transfer that has not already been handled */
+ if (!(transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
+ int r;
+ const struct itimerspec it = { {0, 0},
+ { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
+ usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
+ r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
+ if (r < 0)
+ return LIBUSB_ERROR_OTHER;
+ return 0;
+ }
+ }
+
+disarm:
+ return disarm_timerfd(ctx);
+}
+#else
+static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
+{
+ UNUSED(ctx);
+ return 0;
+}
+#endif
+
+/* add a transfer to the (timeout-sorted) active transfers list.
+ * This function will return non 0 if fails to update the timer,
+ * in which case the transfer is *not* on the flying_transfers list. */
+static int add_to_flying_list(struct usbi_transfer *transfer)
+{
+ struct usbi_transfer *cur;
+ struct timeval *timeout = &transfer->timeout;
+ struct libusb_context *ctx = ITRANSFER_CTX(transfer);
+ int r;
+ int first = 1;
+
+ r = calculate_timeout(transfer);
+ if (r)
+ return r;
+
+ /* if we have no other flying transfers, start the list with this one */
+ if (list_empty(&ctx->flying_transfers)) {
+ list_add(&transfer->list, &ctx->flying_transfers);
+ goto out;
+ }
+
+ /* if we have infinite timeout, append to end of list */
+ if (!timerisset(timeout)) {
+ list_add_tail(&transfer->list, &ctx->flying_transfers);
+ /* first is irrelevant in this case */
+ goto out;
+ }
+
+ /* otherwise, find appropriate place in list */
+ list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) {
+ /* find first timeout that occurs after the transfer in question */
+ struct timeval *cur_tv = &cur->timeout;
+
+ if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
+ (cur_tv->tv_sec == timeout->tv_sec &&
+ cur_tv->tv_usec > timeout->tv_usec)) {
+ list_add_tail(&transfer->list, &cur->list);
+ goto out;
+ }
+ first = 0;
+ }
+ /* first is 0 at this stage (list not empty) */
+
+ /* otherwise we need to be inserted at the end */
+ list_add_tail(&transfer->list, &ctx->flying_transfers);
+out:
+#ifdef USBI_TIMERFD_AVAILABLE
+ if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) {
+ /* if this transfer has the lowest timeout of all active transfers,
+ * rearm the timerfd with this transfer's timeout */
+ const struct itimerspec it = { {0, 0},
+ { timeout->tv_sec, timeout->tv_usec * 1000 } };
+ usbi_dbg("arm timerfd for timeout in %dms (first in line)",
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
+ r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
+ if (r < 0) {
+ usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno);
+ r = LIBUSB_ERROR_OTHER;
+ }
+ }
+#else
+ UNUSED(first);
+#endif
+
+ if (r)
+ list_del(&transfer->list);
+
+ return r;
+}
+
+/* remove a transfer from the active transfers list.
+ * This function will *always* remove the transfer from the
+ * flying_transfers list. It will return a LIBUSB_ERROR code
+ * if it fails to update the timer for the next timeout. */
+static int remove_from_flying_list(struct usbi_transfer *transfer)
+{
+ struct libusb_context *ctx = ITRANSFER_CTX(transfer);
+ int rearm_timerfd;
+ int r = 0;
+
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+ rearm_timerfd = (timerisset(&transfer->timeout) &&
+ list_first_entry(&ctx->flying_transfers, struct usbi_transfer, list) == transfer);
+ list_del(&transfer->list);
+ if (usbi_using_timerfd(ctx) && rearm_timerfd)
+ r = arm_timerfd_for_next_timeout(ctx);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+
+ return r;
+}
+
+/** \ingroup libusb_asyncio
+ * Submit a transfer. This function will fire off the USB transfer and then
+ * return immediately.
+ *
+ * \param transfer the transfer to submit
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted.
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported
+ * by the operating system.
+ * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
+ * the operating system and/or hardware can support
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
+{
+ struct usbi_transfer *itransfer =
+ LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
+ struct libusb_context *ctx = TRANSFER_CTX(transfer);
+ int r;
+
+ usbi_dbg("transfer %p", transfer);
+
+ /*
+ * Important note on locking, this function takes / releases locks
+ * in the following order:
+ * take flying_transfers_lock
+ * take itransfer->lock
+ * clear transfer
+ * add to flying_transfers list
+ * release flying_transfers_lock
+ * submit transfer
+ * release itransfer->lock
+ * if submit failed:
+ * take flying_transfers_lock
+ * remove from flying_transfers list
+ * release flying_transfers_lock
+ *
+ * Note that it takes locks in the order a-b and then releases them
+ * in the same order a-b. This is somewhat unusual but not wrong,
+ * release order is not important as long as *all* locks are released
+ * before re-acquiring any locks.
+ *
+ * This means that the ordering of first releasing itransfer->lock
+ * and then re-acquiring the flying_transfers_list on error is
+ * important and must not be changed!
+ *
+ * This is done this way because when we take both locks we must always
+ * take flying_transfers_lock first to avoid ab-ba style deadlocks with
+ * the timeout handling and usbi_handle_disconnect paths.
+ *
+ * And we cannot release itransfer->lock before the submission is
+ * complete otherwise timeout handling for transfers with short
+ * timeouts may run before submission.
+ */
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+ usbi_mutex_lock(&itransfer->lock);
+ if (itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) {
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&itransfer->lock);
+ return LIBUSB_ERROR_BUSY;
+ }
+ itransfer->transferred = 0;
+ itransfer->state_flags = 0;
+ itransfer->timeout_flags = 0;
+ r = add_to_flying_list(itransfer);
+ if (r) {
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_mutex_unlock(&itransfer->lock);
+ return r;
+ }
+ /*
+ * We must release the flying transfers lock here, because with
+ * some backends the submit_transfer method is synchroneous.
+ */
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+
+ r = usbi_backend.submit_transfer(itransfer);
+ if (r == LIBUSB_SUCCESS) {
+ itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT;
+ /* keep a reference to this device */
+ libusb_ref_device(transfer->dev_handle->dev);
+ }
+ usbi_mutex_unlock(&itransfer->lock);
+
+ if (r != LIBUSB_SUCCESS)
+ remove_from_flying_list(itransfer);
+
+ return r;
+}
+
+/** \ingroup libusb_asyncio
+ * Asynchronously cancel a previously submitted transfer.
+ * This function returns immediately, but this does not indicate cancellation
+ * is complete. Your callback function will be invoked at some later time
+ * with a transfer status of
+ * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED
+ * "LIBUSB_TRANSFER_CANCELLED."
+ *
+ * \param transfer the transfer to cancel
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress,
+ * already complete, or already cancelled.
+ * \returns a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
+{
+ struct usbi_transfer *itransfer =
+ LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
+ int r;
+
+ usbi_dbg("transfer %p", transfer );
+ usbi_mutex_lock(&itransfer->lock);
+ if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT)
+ || (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) {
+ r = LIBUSB_ERROR_NOT_FOUND;
+ goto out;
+ }
+ r = usbi_backend.cancel_transfer(itransfer);
+ if (r < 0) {
+ if (r != LIBUSB_ERROR_NOT_FOUND &&
+ r != LIBUSB_ERROR_NO_DEVICE)
+ usbi_err(TRANSFER_CTX(transfer),
+ "cancel transfer failed error %d", r);
+ else
+ usbi_dbg("cancel transfer failed error %d", r);
+
+ if (r == LIBUSB_ERROR_NO_DEVICE)
+ itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
+ }
+
+ itransfer->state_flags |= USBI_TRANSFER_CANCELLING;
+
+out:
+ usbi_mutex_unlock(&itransfer->lock);
+ return r;
+}
+
+/** \ingroup libusb_asyncio
+ * Set a transfers bulk stream id. Note users are advised to use
+ * libusb_fill_bulk_stream_transfer() instead of calling this function
+ * directly.
+ *
+ * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
+ *
+ * \param transfer the transfer to set the stream id for
+ * \param stream_id the stream id to set
+ * \see libusb_alloc_streams()
+ */
+void API_EXPORTED libusb_transfer_set_stream_id(
+ struct libusb_transfer *transfer, uint32_t stream_id)
+{
+ struct usbi_transfer *itransfer =
+ LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
+
+ itransfer->stream_id = stream_id;
+}
+
+/** \ingroup libusb_asyncio
+ * Get a transfers bulk stream id.
+ *
+ * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
+ *
+ * \param transfer the transfer to get the stream id for
+ * \returns the stream id for the transfer
+ */
+uint32_t API_EXPORTED libusb_transfer_get_stream_id(
+ struct libusb_transfer *transfer)
+{
+ struct usbi_transfer *itransfer =
+ LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
+
+ return itransfer->stream_id;
+}
+
+/* Handle completion of a transfer (completion might be an error condition).
+ * This will invoke the user-supplied callback function, which may end up
+ * freeing the transfer. Therefore you cannot use the transfer structure
+ * after calling this function, and you should free all backend-specific
+ * data before calling it.
+ * Do not call this function with the usbi_transfer lock held. User-specified
+ * callback functions may attempt to directly resubmit the transfer, which
+ * will attempt to take the lock. */
+int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
+ enum libusb_transfer_status status)
+{
+ struct libusb_transfer *transfer =
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ struct libusb_device_handle *dev_handle = transfer->dev_handle;
+ uint8_t flags;
+ int r;
+
+ r = remove_from_flying_list(itransfer);
+ if (r < 0)
+ usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno);
+
+ usbi_mutex_lock(&itransfer->lock);
+ itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT;
+ usbi_mutex_unlock(&itransfer->lock);
+
+ if (status == LIBUSB_TRANSFER_COMPLETED
+ && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
+ int rqlen = transfer->length;
+ if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
+ rqlen -= LIBUSB_CONTROL_SETUP_SIZE;
+ if (rqlen != itransfer->transferred) {
+ usbi_dbg("interpreting short transfer as error");
+ status = LIBUSB_TRANSFER_ERROR;
+ }
+ }
+
+ flags = transfer->flags;
+ transfer->status = status;
+ transfer->actual_length = itransfer->transferred;
+ usbi_dbg("transfer %p has callback %p", transfer, transfer->callback);
+ if (transfer->callback)
+ transfer->callback(transfer);
+ /* transfer might have been freed by the above call, do not use from
+ * this point. */
+ if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
+ libusb_free_transfer(transfer);
+ libusb_unref_device(dev_handle->dev);
+ return r;
+}
+
+/* Similar to usbi_handle_transfer_completion() but exclusively for transfers
+ * that were asynchronously cancelled. The same concerns w.r.t. freeing of
+ * transfers exist here.
+ * Do not call this function with the usbi_transfer lock held. User-specified
+ * callback functions may attempt to directly resubmit the transfer, which
+ * will attempt to take the lock. */
+int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
+{
+ struct libusb_context *ctx = ITRANSFER_CTX(transfer);
+ uint8_t timed_out;
+
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+ timed_out = transfer->timeout_flags & USBI_TRANSFER_TIMED_OUT;
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+
+ /* if the URB was cancelled due to timeout, report timeout to the user */
+ if (timed_out) {
+ usbi_dbg("detected timeout cancellation");
+ return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT);
+ }
+
+ /* otherwise its a normal async cancel */
+ return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED);
+}
+
+/* Add a completed transfer to the completed_transfers list of the
+ * context and signal the event. The backend's handle_transfer_completion()
+ * function will be called the next time an event handler runs. */
+void usbi_signal_transfer_completion(struct usbi_transfer *transfer)
+{
+ libusb_device_handle *dev_handle = USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->dev_handle;
+
+ if (dev_handle) {
+ struct libusb_context *ctx = HANDLE_CTX(dev_handle);
+ int pending_events;
+
+ usbi_mutex_lock(&ctx->event_data_lock);
+ pending_events = usbi_pending_events(ctx);
+ list_add_tail(&transfer->completed_list, &ctx->completed_transfers);
+ if (!pending_events)
+ usbi_signal_event(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ }
+}
+
+/** \ingroup libusb_poll
+ * Attempt to acquire the event handling lock. This lock is used to ensure that
+ * only one thread is monitoring libusb event sources at any one time.
+ *
+ * You only need to use this lock if you are developing an application
+ * which calls poll() or select() on libusb's file descriptors directly.
+ * If you stick to libusb's event handling loop functions (e.g.
+ * libusb_handle_events()) then you do not need to be concerned with this
+ * locking.
+ *
+ * While holding this lock, you are trusted to actually be handling events.
+ * If you are no longer handling events, you must call libusb_unlock_events()
+ * as soon as possible.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \returns 0 if the lock was obtained successfully
+ * \returns 1 if the lock was not obtained (i.e. another thread holds the lock)
+ * \ref libusb_mtasync
+ */
+int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
+{
+ int r;
+ unsigned int ru;
+ USBI_GET_CONTEXT(ctx);
+
+ /* is someone else waiting to close a device? if so, don't let this thread
+ * start event handling */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ ru = ctx->device_close;
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ if (ru) {
+ usbi_dbg("someone else is closing a device");
+ return 1;
+ }
+
+ r = usbi_mutex_trylock(&ctx->events_lock);
+ if (r)
+ return 1;
+
+ ctx->event_handler_active = 1;
+ return 0;
+}
+
+/** \ingroup libusb_poll
+ * Acquire the event handling lock, blocking until successful acquisition if
+ * it is contended. This lock is used to ensure that only one thread is
+ * monitoring libusb event sources at any one time.
+ *
+ * You only need to use this lock if you are developing an application
+ * which calls poll() or select() on libusb's file descriptors directly.
+ * If you stick to libusb's event handling loop functions (e.g.
+ * libusb_handle_events()) then you do not need to be concerned with this
+ * locking.
+ *
+ * While holding this lock, you are trusted to actually be handling events.
+ * If you are no longer handling events, you must call libusb_unlock_events()
+ * as soon as possible.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \ref libusb_mtasync
+ */
+void API_EXPORTED libusb_lock_events(libusb_context *ctx)
+{
+ USBI_GET_CONTEXT(ctx);
+ usbi_mutex_lock(&ctx->events_lock);
+ ctx->event_handler_active = 1;
+}
+
+/** \ingroup libusb_poll
+ * Release the lock previously acquired with libusb_try_lock_events() or
+ * libusb_lock_events(). Releasing this lock will wake up any threads blocked
+ * on libusb_wait_for_event().
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \ref libusb_mtasync
+ */
+void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
+{
+ USBI_GET_CONTEXT(ctx);
+ ctx->event_handler_active = 0;
+ usbi_mutex_unlock(&ctx->events_lock);
+
+ /* FIXME: perhaps we should be a bit more efficient by not broadcasting
+ * the availability of the events lock when we are modifying pollfds
+ * (check ctx->device_close)? */
+ usbi_mutex_lock(&ctx->event_waiters_lock);
+ usbi_cond_broadcast(&ctx->event_waiters_cond);
+ usbi_mutex_unlock(&ctx->event_waiters_lock);
+}
+
+/** \ingroup libusb_poll
+ * Determine if it is still OK for this thread to be doing event handling.
+ *
+ * Sometimes, libusb needs to temporarily pause all event handlers, and this
+ * is the function you should use before polling file descriptors to see if
+ * this is the case.
+ *
+ * If this function instructs your thread to give up the events lock, you
+ * should just continue the usual logic that is documented in \ref libusb_mtasync.
+ * On the next iteration, your thread will fail to obtain the events lock,
+ * and will hence become an event waiter.
+ *
+ * This function should be called while the events lock is held: you don't
+ * need to worry about the results of this function if your thread is not
+ * the current event handler.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \returns 1 if event handling can start or continue
+ * \returns 0 if this thread must give up the events lock
+ * \ref fullstory "Multi-threaded I/O: the full story"
+ */
+int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
+{
+ unsigned int r;
+ USBI_GET_CONTEXT(ctx);
+
+ /* is someone else waiting to close a device? if so, don't let this thread
+ * continue event handling */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ r = ctx->device_close;
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ if (r) {
+ usbi_dbg("someone else is closing a device");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/** \ingroup libusb_poll
+ * Determine if an active thread is handling events (i.e. if anyone is holding
+ * the event handling lock).
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \returns 1 if a thread is handling events
+ * \returns 0 if there are no threads currently handling events
+ * \ref libusb_mtasync
+ */
+int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
+{
+ unsigned int r;
+ USBI_GET_CONTEXT(ctx);
+
+ /* is someone else waiting to close a device? if so, don't let this thread
+ * start event handling -- indicate that event handling is happening */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ r = ctx->device_close;
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ if (r) {
+ usbi_dbg("someone else is closing a device");
+ return 1;
+ }
+
+ return ctx->event_handler_active;
+}
+
+/** \ingroup libusb_poll
+ * Interrupt any active thread that is handling events. This is mainly useful
+ * for interrupting a dedicated event handling thread when an application
+ * wishes to call libusb_exit().
+ *
+ * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \ref libusb_mtasync
+ */
+void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx)
+{
+ int pending_events;
+ USBI_GET_CONTEXT(ctx);
+
+ usbi_dbg("");
+ usbi_mutex_lock(&ctx->event_data_lock);
+
+ pending_events = usbi_pending_events(ctx);
+ ctx->event_flags |= USBI_EVENT_USER_INTERRUPT;
+ if (!pending_events)
+ usbi_signal_event(ctx);
+
+ usbi_mutex_unlock(&ctx->event_data_lock);
+}
+
+/** \ingroup libusb_poll
+ * Acquire the event waiters lock. This lock is designed to be obtained under
+ * the situation where you want to be aware when events are completed, but
+ * some other thread is event handling so calling libusb_handle_events() is not
+ * allowed.
+ *
+ * You then obtain this lock, re-check that another thread is still handling
+ * events, then call libusb_wait_for_event().
+ *
+ * You only need to use this lock if you are developing an application
+ * which calls poll() or select() on libusb's file descriptors directly,
+ * <b>and</b> may potentially be handling events from 2 threads simultaenously.
+ * If you stick to libusb's event handling loop functions (e.g.
+ * libusb_handle_events()) then you do not need to be concerned with this
+ * locking.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \ref libusb_mtasync
+ */
+void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
+{
+ USBI_GET_CONTEXT(ctx);
+ usbi_mutex_lock(&ctx->event_waiters_lock);
+}
+
+/** \ingroup libusb_poll
+ * Release the event waiters lock.
+ * \param ctx the context to operate on, or NULL for the default context
+ * \ref libusb_mtasync
+ */
+void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
+{
+ USBI_GET_CONTEXT(ctx);
+ usbi_mutex_unlock(&ctx->event_waiters_lock);
+}
+
+/** \ingroup libusb_poll
+ * Wait for another thread to signal completion of an event. Must be called
+ * with the event waiters lock held, see libusb_lock_event_waiters().
+ *
+ * This function will block until any of the following conditions are met:
+ * -# The timeout expires
+ * -# A transfer completes
+ * -# A thread releases the event handling lock through libusb_unlock_events()
+ *
+ * Condition 1 is obvious. Condition 2 unblocks your thread <em>after</em>
+ * the callback for the transfer has completed. Condition 3 is important
+ * because it means that the thread that was previously handling events is no
+ * longer doing so, so if any events are to complete, another thread needs to
+ * step up and start event handling.
+ *
+ * This function releases the event waiters lock before putting your thread
+ * to sleep, and reacquires the lock as it is being woken up.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param tv maximum timeout for this blocking function. A NULL value
+ * indicates unlimited timeout.
+ * \returns 0 after a transfer completes or another thread stops event handling
+ * \returns 1 if the timeout expired
+ * \ref libusb_mtasync
+ */
+int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
+{
+ int r;
+
+ USBI_GET_CONTEXT(ctx);
+ if (tv == NULL) {
+ usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock);
+ return 0;
+ }
+
+ r = usbi_cond_timedwait(&ctx->event_waiters_cond,
+ &ctx->event_waiters_lock, tv);
+
+ if (r < 0)
+ return r;
+ else
+ return (r == ETIMEDOUT);
+}
+
+static void handle_timeout(struct usbi_transfer *itransfer)
+{
+ struct libusb_transfer *transfer =
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ int r;
+
+ itransfer->timeout_flags |= USBI_TRANSFER_TIMEOUT_HANDLED;
+ r = libusb_cancel_transfer(transfer);
+ if (r == LIBUSB_SUCCESS)
+ itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
+ else
+ usbi_warn(TRANSFER_CTX(transfer),
+ "async cancel failed %d errno=%d", r, errno);
+}
+
+static int handle_timeouts_locked(struct libusb_context *ctx)
+{
+ int r;
+ struct timespec systime_ts;
+ struct timeval systime;
+ struct usbi_transfer *transfer;
+
+ if (list_empty(&ctx->flying_transfers))
+ return 0;
+
+ /* get current time */
+ r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts);
+ if (r < 0)
+ return r;
+
+ TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
+
+ /* iterate through flying transfers list, finding all transfers that
+ * have expired timeouts */
+ list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
+ struct timeval *cur_tv = &transfer->timeout;
+
+ /* if we've reached transfers of infinite timeout, we're all done */
+ if (!timerisset(cur_tv))
+ return 0;
+
+ /* ignore timeouts we've already handled */
+ if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
+ continue;
+
+ /* if transfer has non-expired timeout, nothing more to do */
+ if ((cur_tv->tv_sec > systime.tv_sec) ||
+ (cur_tv->tv_sec == systime.tv_sec &&
+ cur_tv->tv_usec > systime.tv_usec))
+ return 0;
+
+ /* otherwise, we've got an expired timeout to handle */
+ handle_timeout(transfer);
+ }
+ return 0;
+}
+
+static int handle_timeouts(struct libusb_context *ctx)
+{
+ int r;
+ USBI_GET_CONTEXT(ctx);
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+ r = handle_timeouts_locked(ctx);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ return r;
+}
+
+#ifdef USBI_TIMERFD_AVAILABLE
+static int handle_timerfd_trigger(struct libusb_context *ctx)
+{
+ int r;
+
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+
+ /* process the timeout that just happened */
+ r = handle_timeouts_locked(ctx);
+ if (r < 0)
+ goto out;
+
+ /* arm for next timeout*/
+ r = arm_timerfd_for_next_timeout(ctx);
+
+out:
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ return r;
+}
+#endif
+
+/* do the actual event handling. assumes that no other thread is concurrently
+ * doing the same thing. */
+static int handle_events(struct libusb_context *ctx, struct timeval *tv)
+{
+ int r;
+ struct usbi_pollfd *ipollfd;
+ POLL_NFDS_TYPE nfds = 0;
+ POLL_NFDS_TYPE internal_nfds;
+ struct pollfd *fds = NULL;
+ int i = -1;
+ int timeout_ms;
+
+ /* prevent attempts to recursively handle events (e.g. calling into
+ * libusb_handle_events() from within a hotplug or transfer callback) */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ r = 0;
+ if (usbi_handling_events(ctx))
+ r = LIBUSB_ERROR_BUSY;
+ else
+ usbi_start_event_handling(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ if (r)
+ return r;
+
+ /* there are certain fds that libusb uses internally, currently:
+ *
+ * 1) event pipe
+ * 2) timerfd
+ *
+ * the backend will never need to attempt to handle events on these fds, so
+ * we determine how many fds are in use internally for this context and when
+ * handle_events() is called in the backend, the pollfd list and count will
+ * be adjusted to skip over these internal fds */
+ if (usbi_using_timerfd(ctx))
+ internal_nfds = 2;
+ else
+ internal_nfds = 1;
+
+ /* only reallocate the poll fds when the list of poll fds has been modified
+ * since the last poll, otherwise reuse them to save the additional overhead */
+ usbi_mutex_lock(&ctx->event_data_lock);
+ /* clean up removed poll fds */
+ cleanup_removed_pollfds(ctx);
+ if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) {
+ usbi_dbg("poll fds modified, reallocating");
+
+ free(ctx->pollfds);
+ ctx->pollfds = NULL;
+
+ /* sanity check - it is invalid for a context to have fewer than the
+ * required internal fds (memory corruption?) */
+ assert(ctx->pollfds_cnt >= internal_nfds);
+
+ ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds));
+ if (!ctx->pollfds) {
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ r = LIBUSB_ERROR_NO_MEM;
+ goto done;
+ }
+
+ list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) {
+ struct libusb_pollfd *pollfd = &ipollfd->pollfd;
+ i++;
+ ctx->pollfds[i].fd = pollfd->fd;
+ ctx->pollfds[i].events = pollfd->events;
+ }
+
+ /* reset the flag now that we have the updated list */
+ ctx->event_flags &= ~USBI_EVENT_POLLFDS_MODIFIED;
+
+ /* if no further pending events, clear the event pipe so that we do
+ * not immediately return from poll */
+ if (!usbi_pending_events(ctx))
+ usbi_clear_event(ctx);
+ }
+ fds = ctx->pollfds;
+ nfds = ctx->pollfds_cnt;
+ usbi_inc_fds_ref(fds, nfds);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
+
+ /* round up to next millisecond */
+ if (tv->tv_usec % 1000)
+ timeout_ms++;
+
+ usbi_dbg("poll() %d fds with timeout in %dms", (int)nfds, timeout_ms);
+ r = usbi_poll(fds, nfds, timeout_ms);
+ usbi_dbg("poll() returned %d", r);
+ if (r == 0) {
+ r = handle_timeouts(ctx);
+ goto done;
+ } else if (r == -1 && errno == EINTR) {
+ r = LIBUSB_ERROR_INTERRUPTED;
+ goto done;
+ } else if (r < 0) {
+ usbi_err(ctx, "poll failed %d err=%d", r, errno);
+ r = LIBUSB_ERROR_IO;
+ goto done;
+ }
+
+ /* fds[0] is always the event pipe */
+ if (fds[0].revents) {
+ struct list_head hotplug_msgs;
+ struct usbi_transfer *itransfer;
+ int hotplug_cb_deregistered = 0;
+ int ret = 0;
+
+ list_init(&hotplug_msgs);
+
+ usbi_dbg("caught a fish on the event pipe");
+
+ /* take the the event data lock while processing events */
+ usbi_mutex_lock(&ctx->event_data_lock);
+
+ /* check if someone added a new poll fd */
+ if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED)
+ usbi_dbg("someone updated the poll fds");
+
+ if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) {
+ usbi_dbg("someone purposely interrupted");
+ ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT;
+ }
+
+ if (ctx->event_flags & USBI_EVENT_HOTPLUG_CB_DEREGISTERED) {
+ usbi_dbg("someone unregistered a hotplug cb");
+ ctx->event_flags &= ~USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
+ hotplug_cb_deregistered = 1;
+ }
+
+ /* check if someone is closing a device */
+ if (ctx->device_close)
+ usbi_dbg("someone is closing a device");
+
+ /* check for any pending hotplug messages */
+ if (!list_empty(&ctx->hotplug_msgs)) {
+ usbi_dbg("hotplug message received");
+ list_cut(&hotplug_msgs, &ctx->hotplug_msgs);
+ }
+
+ /* complete any pending transfers */
+ while (ret == 0 && !list_empty(&ctx->completed_transfers)) {
+ itransfer = list_first_entry(&ctx->completed_transfers, struct usbi_transfer, completed_list);
+ list_del(&itransfer->completed_list);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ ret = usbi_backend.handle_transfer_completion(itransfer);
+ if (ret)
+ usbi_err(ctx, "backend handle_transfer_completion failed with error %d", ret);
+ usbi_mutex_lock(&ctx->event_data_lock);
+ }
+
+ /* if no further pending events, clear the event pipe */
+ if (!usbi_pending_events(ctx))
+ usbi_clear_event(ctx);
+
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ if (hotplug_cb_deregistered)
+ usbi_hotplug_deregister(ctx, 0);
+
+ /* process the hotplug messages, if any */
+ while (!list_empty(&hotplug_msgs)) {
+ struct libusb_hotplug_message *message =
+ list_first_entry(&hotplug_msgs, struct libusb_hotplug_message, list);
+
+ usbi_hotplug_match(ctx, message->device, message->event);
+
+ /* the device left, dereference the device */
+ if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message->event)
+ libusb_unref_device(message->device);
+
+ list_del(&message->list);
+ free(message);
+ }
+
+ if (ret) {
+ /* return error code */
+ r = ret;
+ goto done;
+ }
+
+ if (0 == --r)
+ goto done;
+ }
+
+#ifdef USBI_TIMERFD_AVAILABLE
+ /* on timerfd configurations, fds[1] is the timerfd */
+ if (usbi_using_timerfd(ctx) && fds[1].revents) {
+ /* timerfd indicates that a timeout has expired */
+ int ret;
+ usbi_dbg("timerfd triggered");
+
+ ret = handle_timerfd_trigger(ctx);
+ if (ret < 0) {
+ /* return error code */
+ r = ret;
+ goto done;
+ }
+
+ if (0 == --r)
+ goto done;
+ }
+#endif
+
+ list_for_each_entry(ipollfd, &ctx->removed_ipollfds, list, struct usbi_pollfd) {
+ for (i = internal_nfds ; i < nfds ; ++i) {
+ if (ipollfd->pollfd.fd == fds[i].fd) {
+ /* pollfd was removed between the creation of the fd
+ * array and here. remove any triggered revent as
+ * it is no longer relevant */
+ usbi_dbg("pollfd %d was removed. ignoring raised events",
+ fds[i].fd);
+ fds[i].revents = 0;
+ break;
+ }
+ }
+ }
+
+ r = usbi_backend.handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r);
+ if (r)
+ usbi_err(ctx, "backend handle_events failed with error %d", r);
+
+done:
+ usbi_end_event_handling(ctx);
+ usbi_dec_fds_ref(fds, nfds);
+ return r;
+}
+
+/* returns the smallest of:
+ * 1. timeout of next URB
+ * 2. user-supplied timeout
+ * returns 1 if there is an already-expired timeout, otherwise returns 0
+ * and populates out
+ */
+static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
+ struct timeval *out)
+{
+ struct timeval timeout;
+ int r = libusb_get_next_timeout(ctx, &timeout);
+ if (r) {
+ /* timeout already expired? */
+ if (!timerisset(&timeout))
+ return 1;
+
+ /* choose the smallest of next URB timeout or user specified timeout */
+ if (timercmp(&timeout, tv, <))
+ *out = timeout;
+ else
+ *out = *tv;
+ } else {
+ *out = *tv;
+ }
+ return 0;
+}
+
+/** \ingroup libusb_poll
+ * Handle any pending events.
+ *
+ * libusb determines "pending events" by checking if any timeouts have expired
+ * and by checking the set of file descriptors for activity.
+ *
+ * If a zero timeval is passed, this function will handle any already-pending
+ * events and then immediately return in non-blocking style.
+ *
+ * If a non-zero timeval is passed and no events are currently pending, this
+ * function will block waiting for events to handle up until the specified
+ * timeout. If an event arrives or a signal is raised, this function will
+ * return early.
+ *
+ * If the parameter completed is not NULL then <em>after obtaining the event
+ * handling lock</em> this function will return immediately if the integer
+ * pointed to is not 0. This allows for race free waiting for the completion
+ * of a specific transfer.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param tv the maximum time to block waiting for events, or an all zero
+ * timeval struct for non-blocking mode
+ * \param completed pointer to completion integer to check, or NULL
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
+ * \ref libusb_mtasync
+ */
+int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
+ struct timeval *tv, int *completed)
+{
+ int r;
+ struct timeval poll_timeout;
+
+ USBI_GET_CONTEXT(ctx);
+ r = get_next_timeout(ctx, tv, &poll_timeout);
+ if (r) {
+ /* timeout already expired */
+ return handle_timeouts(ctx);
+ }
+
+retry:
+ if (libusb_try_lock_events(ctx) == 0) {
+ if (completed == NULL || !*completed) {
+ /* we obtained the event lock: do our own event handling */
+ usbi_dbg("doing our own event handling");
+ r = handle_events(ctx, &poll_timeout);
+ }
+ libusb_unlock_events(ctx);
+ return r;
+ }
+
+ /* another thread is doing event handling. wait for thread events that
+ * notify event completion. */
+ libusb_lock_event_waiters(ctx);
+
+ if (completed && *completed)
+ goto already_done;
+
+ if (!libusb_event_handler_active(ctx)) {
+ /* we hit a race: whoever was event handling earlier finished in the
+ * time it took us to reach this point. try the cycle again. */
+ libusb_unlock_event_waiters(ctx);
+ usbi_dbg("event handler was active but went away, retrying");
+ goto retry;
+ }
+
+ usbi_dbg("another thread is doing event handling");
+ r = libusb_wait_for_event(ctx, &poll_timeout);
+
+already_done:
+ libusb_unlock_event_waiters(ctx);
+
+ if (r < 0)
+ return r;
+ else if (r == 1)
+ return handle_timeouts(ctx);
+ else
+ return 0;
+}
+
+/** \ingroup libusb_poll
+ * Handle any pending events
+ *
+ * Like libusb_handle_events_timeout_completed(), but without the completed
+ * parameter, calling this function is equivalent to calling
+ * libusb_handle_events_timeout_completed() with a NULL completed parameter.
+ *
+ * This function is kept primarily for backwards compatibility.
+ * All new code should call libusb_handle_events_completed() or
+ * libusb_handle_events_timeout_completed() to avoid race conditions.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param tv the maximum time to block waiting for events, or an all zero
+ * timeval struct for non-blocking mode
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
+ struct timeval *tv)
+{
+ return libusb_handle_events_timeout_completed(ctx, tv, NULL);
+}
+
+/** \ingroup libusb_poll
+ * Handle any pending events in blocking mode. There is currently a timeout
+ * hardcoded at 60 seconds but we plan to make it unlimited in future. For
+ * finer control over whether this function is blocking or non-blocking, or
+ * for control over the timeout, use libusb_handle_events_timeout_completed()
+ * instead.
+ *
+ * This function is kept primarily for backwards compatibility.
+ * All new code should call libusb_handle_events_completed() or
+ * libusb_handle_events_timeout_completed() to avoid race conditions.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
+ */
+int API_EXPORTED libusb_handle_events(libusb_context *ctx)
+{
+ struct timeval tv;
+ tv.tv_sec = 60;
+ tv.tv_usec = 0;
+ return libusb_handle_events_timeout_completed(ctx, &tv, NULL);
+}
+
+/** \ingroup libusb_poll
+ * Handle any pending events in blocking mode.
+ *
+ * Like libusb_handle_events(), with the addition of a completed parameter
+ * to allow for race free waiting for the completion of a specific transfer.
+ *
+ * See libusb_handle_events_timeout_completed() for details on the completed
+ * parameter.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param completed pointer to completion integer to check, or NULL
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
+ * \ref libusb_mtasync
+ */
+int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
+ int *completed)
+{
+ struct timeval tv;
+ tv.tv_sec = 60;
+ tv.tv_usec = 0;
+ return libusb_handle_events_timeout_completed(ctx, &tv, completed);
+}
+
+/** \ingroup libusb_poll
+ * Handle any pending events by polling file descriptors, without checking if
+ * any other threads are already doing so. Must be called with the event lock
+ * held, see libusb_lock_events().
+ *
+ * This function is designed to be called under the situation where you have
+ * taken the event lock and are calling poll()/select() directly on libusb's
+ * file descriptors (as opposed to using libusb_handle_events() or similar).
+ * You detect events on libusb's descriptors, so you then call this function
+ * with a zero timeout value (while still holding the event lock).
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param tv the maximum time to block waiting for events, or zero for
+ * non-blocking mode
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
+ * \ref libusb_mtasync
+ */
+int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
+ struct timeval *tv)
+{
+ int r;
+ struct timeval poll_timeout;
+
+ USBI_GET_CONTEXT(ctx);
+ r = get_next_timeout(ctx, tv, &poll_timeout);
+ if (r) {
+ /* timeout already expired */
+ return handle_timeouts(ctx);
+ }
+
+ return handle_events(ctx, &poll_timeout);
+}
+
+/** \ingroup libusb_poll
+ * Determines whether your application must apply special timing considerations
+ * when monitoring libusb's file descriptors.
+ *
+ * This function is only useful for applications which retrieve and poll
+ * libusb's file descriptors in their own main loop (\ref libusb_pollmain).
+ *
+ * Ordinarily, libusb's event handler needs to be called into at specific
+ * moments in time (in addition to times when there is activity on the file
+ * descriptor set). The usual approach is to use libusb_get_next_timeout()
+ * to learn about when the next timeout occurs, and to adjust your
+ * poll()/select() timeout accordingly so that you can make a call into the
+ * library at that time.
+ *
+ * Some platforms supported by libusb do not come with this baggage - any
+ * events relevant to timing will be represented by activity on the file
+ * descriptor set, and libusb_get_next_timeout() will always return 0.
+ * This function allows you to detect whether you are running on such a
+ * platform.
+ *
+ * Since v1.0.5.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \returns 0 if you must call into libusb at times determined by
+ * libusb_get_next_timeout(), or 1 if all timeout events are handled internally
+ * or through regular activity on the file descriptors.
+ * \ref libusb_pollmain "Polling libusb file descriptors for event handling"
+ */
+int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
+{
+#if defined(USBI_TIMERFD_AVAILABLE)
+ USBI_GET_CONTEXT(ctx);
+ return usbi_using_timerfd(ctx);
+#else
+ UNUSED(ctx);
+ return 0;
+#endif
+}
+
+/** \ingroup libusb_poll
+ * Determine the next internal timeout that libusb needs to handle. You only
+ * need to use this function if you are calling poll() or select() or similar
+ * on libusb's file descriptors yourself - you do not need to use it if you
+ * are calling libusb_handle_events() or a variant directly.
+ *
+ * You should call this function in your main loop in order to determine how
+ * long to wait for select() or poll() to return results. libusb needs to be
+ * called into at this timeout, so you should use it as an upper bound on
+ * your select() or poll() call.
+ *
+ * When the timeout has expired, call into libusb_handle_events_timeout()
+ * (perhaps in non-blocking mode) so that libusb can handle the timeout.
+ *
+ * This function may return 1 (success) and an all-zero timeval. If this is
+ * the case, it indicates that libusb has a timeout that has already expired
+ * so you should call libusb_handle_events_timeout() or similar immediately.
+ * A return code of 0 indicates that there are no pending timeouts.
+ *
+ * On some platforms, this function will always returns 0 (no pending
+ * timeouts). See \ref polltime.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param tv output location for a relative time against the current
+ * clock in which libusb must be called into in order to process timeout events
+ * \returns 0 if there are no pending timeouts, 1 if a timeout was returned,
+ * or LIBUSB_ERROR_OTHER on failure
+ */
+int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
+ struct timeval *tv)
+{
+ struct usbi_transfer *transfer;
+ struct timespec cur_ts;
+ struct timeval cur_tv;
+ struct timeval next_timeout = { 0, 0 };
+ int r;
+
+ USBI_GET_CONTEXT(ctx);
+ if (usbi_using_timerfd(ctx))
+ return 0;
+
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
+ if (list_empty(&ctx->flying_transfers)) {
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ usbi_dbg("no URBs, no timeout!");
+ return 0;
+ }
+
+ /* find next transfer which hasn't already been processed as timed out */
+ list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
+ if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
+ continue;
+
+ /* if we've reached transfers of infinte timeout, we're done looking */
+ if (!timerisset(&transfer->timeout))
+ break;
+
+ next_timeout = transfer->timeout;
+ break;
+ }
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
+
+ if (!timerisset(&next_timeout)) {
+ usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
+ return 0;
+ }
+
+ r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
+ if (r < 0) {
+ usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
+ return 0;
+ }
+ TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
+
+ if (!timercmp(&cur_tv, &next_timeout, <)) {
+ usbi_dbg("first timeout already expired");
+ timerclear(tv);
+ } else {
+ timersub(&next_timeout, &cur_tv, tv);
+ usbi_dbg("next timeout in %ld.%06lds", (long)tv->tv_sec, (long)tv->tv_usec);
+ }
+
+ return 1;
+}
+
+/** \ingroup libusb_poll
+ * Register notification functions for file descriptor additions/removals.
+ * These functions will be invoked for every new or removed file descriptor
+ * that libusb uses as an event source.
+ *
+ * To remove notifiers, pass NULL values for the function pointers.
+ *
+ * Note that file descriptors may have been added even before you register
+ * these notifiers (e.g. at libusb_init() time).
+ *
+ * Additionally, note that the removal notifier may be called during
+ * libusb_exit() (e.g. when it is closing file descriptors that were opened
+ * and added to the poll set at libusb_init() time). If you don't want this,
+ * remove the notifiers immediately before calling libusb_exit().
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param added_cb pointer to function for addition notifications
+ * \param removed_cb pointer to function for removal notifications
+ * \param user_data User data to be passed back to callbacks (useful for
+ * passing context information)
+ */
+void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx,
+ libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
+ void *user_data)
+{
+ USBI_GET_CONTEXT(ctx);
+ ctx->fd_added_cb = added_cb;
+ ctx->fd_removed_cb = removed_cb;
+ ctx->fd_cb_user_data = user_data;
+}
+
+/*
+ * Interrupt the iteration of the event handling thread, so that it picks
+ * up the fd change. Callers of this function must hold the event_data_lock.
+ */
+static void usbi_fd_notification(struct libusb_context *ctx)
+{
+ int pending_events;
+
+ /* Record that there is a new poll fd.
+ * Only signal an event if there are no prior pending events. */
+ pending_events = usbi_pending_events(ctx);
+ ctx->event_flags |= USBI_EVENT_POLLFDS_MODIFIED;
+ if (!pending_events)
+ usbi_signal_event(ctx);
+}
+
+/* Add a file descriptor to the list of file descriptors to be monitored.
+ * events should be specified as a bitmask of events passed to poll(), e.g.
+ * POLLIN and/or POLLOUT. */
+int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events)
+{
+ struct usbi_pollfd *ipollfd = malloc(sizeof(*ipollfd));
+ if (!ipollfd)
+ return LIBUSB_ERROR_NO_MEM;
+
+ usbi_dbg("add fd %d events %d", fd, events);
+ ipollfd->pollfd.fd = fd;
+ ipollfd->pollfd.events = events;
+ usbi_mutex_lock(&ctx->event_data_lock);
+ list_add_tail(&ipollfd->list, &ctx->ipollfds);
+ ctx->pollfds_cnt++;
+ usbi_fd_notification(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ if (ctx->fd_added_cb)
+ ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
+ return 0;
+}
+
+/* Remove a file descriptor from the list of file descriptors to be polled. */
+void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
+{
+ struct usbi_pollfd *ipollfd;
+ int found = 0;
+
+ usbi_dbg("remove fd %d", fd);
+ usbi_mutex_lock(&ctx->event_data_lock);
+ list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd)
+ if (ipollfd->pollfd.fd == fd) {
+ found = 1;
+ break;
+ }
+
+ if (!found) {
+ usbi_dbg("couldn't find fd %d to remove", fd);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ return;
+ }
+
+ list_del(&ipollfd->list);
+ list_add_tail(&ipollfd->list, &ctx->removed_ipollfds);
+ ctx->pollfds_cnt--;
+ usbi_fd_notification(ctx);
+ usbi_mutex_unlock(&ctx->event_data_lock);
+
+ if (ctx->fd_removed_cb)
+ ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
+}
+
+/** \ingroup libusb_poll
+ * Retrieve a list of file descriptors that should be polled by your main loop
+ * as libusb event sources.
+ *
+ * The returned list is NULL-terminated and should be freed with libusb_free_pollfds()
+ * when done. The actual list contents must not be touched.
+ *
+ * As file descriptors are a Unix-specific concept, this function is not
+ * available on Windows and will always return NULL.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \returns a NULL-terminated list of libusb_pollfd structures
+ * \returns NULL on error
+ * \returns NULL on platforms where the functionality is not available
+ */
+DEFAULT_VISIBILITY
+const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
+ libusb_context *ctx)
+{
+#ifndef OS_WINDOWS
+ struct libusb_pollfd **ret = NULL;
+ struct usbi_pollfd *ipollfd;
+ size_t i = 0;
+ USBI_GET_CONTEXT(ctx);
+
+ usbi_mutex_lock(&ctx->event_data_lock);
+
+ ret = calloc(ctx->pollfds_cnt + 1, sizeof(struct libusb_pollfd *));
+ if (!ret)
+ goto out;
+
+ list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd)
+ ret[i++] = (struct libusb_pollfd *) ipollfd;
+ ret[ctx->pollfds_cnt] = NULL;
+
+out:
+ usbi_mutex_unlock(&ctx->event_data_lock);
+ return (const struct libusb_pollfd **) ret;
+#else
+ usbi_err(ctx, "external polling of libusb's internal descriptors "\
+ "is not yet supported on Windows platforms");
+ return NULL;
+#endif
+}
+
+/** \ingroup libusb_poll
+ * Free a list of libusb_pollfd structures. This should be called for all
+ * pollfd lists allocated with libusb_get_pollfds().
+ *
+ * Since version 1.0.20, \ref LIBUSB_API_VERSION >= 0x01000104
+ *
+ * It is legal to call this function with a NULL pollfd list. In this case,
+ * the function will simply do nothing.
+ *
+ * \param pollfds the list of libusb_pollfd structures to free
+ */
+void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
+{
+ free((void *)pollfds);
+}
+
+/* Backends may call this from handle_events to report disconnection of a
+ * device. This function ensures transfers get cancelled appropriately.
+ * Callers of this function must hold the events_lock.
+ */
+void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
+{
+ struct usbi_transfer *cur;
+ struct usbi_transfer *to_cancel;
+
+ usbi_dbg("device %d.%d",
+ dev_handle->dev->bus_number, dev_handle->dev->device_address);
+
+ /* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE
+ * status code.
+ *
+ * when we find a transfer for this device on the list, there are two
+ * possible scenarios:
+ * 1. the transfer is currently in-flight, in which case we terminate the
+ * transfer here
+ * 2. the transfer has been added to the flying transfer list by
+ * libusb_submit_transfer, has failed to submit and
+ * libusb_submit_transfer is waiting for us to release the
+ * flying_transfers_lock to remove it, so we ignore it
+ */
+
+ while (1) {
+ to_cancel = NULL;
+ usbi_mutex_lock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
+ list_for_each_entry(cur, &HANDLE_CTX(dev_handle)->flying_transfers, list, struct usbi_transfer)
+ if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == dev_handle) {
+ usbi_mutex_lock(&cur->lock);
+ if (cur->state_flags & USBI_TRANSFER_IN_FLIGHT)
+ to_cancel = cur;
+ usbi_mutex_unlock(&cur->lock);
+
+ if (to_cancel)
+ break;
+ }
+ usbi_mutex_unlock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
+
+ if (!to_cancel)
+ break;
+
+ usbi_dbg("cancelling transfer %p from disconnect",
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel));
+
+ usbi_mutex_lock(&to_cancel->lock);
+ usbi_backend.clear_transfer_priv(to_cancel);
+ usbi_mutex_unlock(&to_cancel->lock);
+ usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
+ }
+
+}
diff --git a/libusb1/libusb-1.0.def b/libusb1/libusb-1.0.def
new file mode 100644
index 0000000..6eba4ff
--- /dev/null
+++ b/libusb1/libusb-1.0.def
@@ -0,0 +1,178 @@
+LIBRARY "libusb-1.0.dll"
+EXPORTS
+ libusb_alloc_streams
+ libusb_alloc_streams@16 = libusb_alloc_streams
+ libusb_alloc_transfer
+ libusb_alloc_transfer@4 = libusb_alloc_transfer
+ libusb_attach_kernel_driver
+ libusb_attach_kernel_driver@8 = libusb_attach_kernel_driver
+ libusb_bulk_transfer
+ libusb_bulk_transfer@24 = libusb_bulk_transfer
+ libusb_cancel_transfer
+ libusb_cancel_transfer@4 = libusb_cancel_transfer
+ libusb_claim_interface
+ libusb_claim_interface@8 = libusb_claim_interface
+ libusb_clear_halt
+ libusb_clear_halt@8 = libusb_clear_halt
+ libusb_close
+ libusb_close@4 = libusb_close
+ libusb_control_transfer
+ libusb_control_transfer@32 = libusb_control_transfer
+ libusb_detach_kernel_driver
+ libusb_detach_kernel_driver@8 = libusb_detach_kernel_driver
+ libusb_dev_mem_alloc
+ libusb_dev_mem_alloc@8 = libusb_dev_mem_alloc
+ libusb_dev_mem_free
+ libusb_dev_mem_free@12 = libusb_dev_mem_free
+ libusb_error_name
+ libusb_error_name@4 = libusb_error_name
+ libusb_event_handler_active
+ libusb_event_handler_active@4 = libusb_event_handler_active
+ libusb_event_handling_ok
+ libusb_event_handling_ok@4 = libusb_event_handling_ok
+ libusb_exit
+ libusb_exit@4 = libusb_exit
+ libusb_free_bos_descriptor
+ libusb_free_bos_descriptor@4 = libusb_free_bos_descriptor
+ libusb_free_config_descriptor
+ libusb_free_config_descriptor@4 = libusb_free_config_descriptor
+ libusb_free_container_id_descriptor
+ libusb_free_container_id_descriptor@4 = libusb_free_container_id_descriptor
+ libusb_free_device_list
+ libusb_free_device_list@8 = libusb_free_device_list
+ libusb_free_pollfds
+ libusb_free_pollfds@4 = libusb_free_pollfds
+ libusb_free_ss_endpoint_companion_descriptor
+ libusb_free_ss_endpoint_companion_descriptor@4 = libusb_free_ss_endpoint_companion_descriptor
+ libusb_free_ss_usb_device_capability_descriptor
+ libusb_free_ss_usb_device_capability_descriptor@4 = libusb_free_ss_usb_device_capability_descriptor
+ libusb_free_streams
+ libusb_free_streams@12 = libusb_free_streams
+ libusb_free_transfer
+ libusb_free_transfer@4 = libusb_free_transfer
+ libusb_free_usb_2_0_extension_descriptor
+ libusb_free_usb_2_0_extension_descriptor@4 = libusb_free_usb_2_0_extension_descriptor
+ libusb_get_active_config_descriptor
+ libusb_get_active_config_descriptor@8 = libusb_get_active_config_descriptor
+ libusb_get_bos_descriptor
+ libusb_get_bos_descriptor@8 = libusb_get_bos_descriptor
+ libusb_get_bus_number
+ libusb_get_bus_number@4 = libusb_get_bus_number
+ libusb_get_config_descriptor
+ libusb_get_config_descriptor@12 = libusb_get_config_descriptor
+ libusb_get_config_descriptor_by_value
+ libusb_get_config_descriptor_by_value@12 = libusb_get_config_descriptor_by_value
+ libusb_get_configuration
+ libusb_get_configuration@8 = libusb_get_configuration
+ libusb_get_container_id_descriptor
+ libusb_get_container_id_descriptor@12 = libusb_get_container_id_descriptor
+ libusb_get_device
+ libusb_get_device@4 = libusb_get_device
+ libusb_get_device_address
+ libusb_get_device_address@4 = libusb_get_device_address
+ libusb_get_device_descriptor
+ libusb_get_device_descriptor@8 = libusb_get_device_descriptor
+ libusb_get_device_list
+ libusb_get_device_list@8 = libusb_get_device_list
+ libusb_get_device_speed
+ libusb_get_device_speed@4 = libusb_get_device_speed
+ libusb_get_max_iso_packet_size
+ libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
+ libusb_get_max_packet_size
+ libusb_get_max_packet_size@8 = libusb_get_max_packet_size
+ libusb_get_next_timeout
+ libusb_get_next_timeout@8 = libusb_get_next_timeout
+ libusb_get_parent
+ libusb_get_parent@4 = libusb_get_parent
+ libusb_get_pollfds
+ libusb_get_pollfds@4 = libusb_get_pollfds
+ libusb_get_port_number
+ libusb_get_port_number@4 = libusb_get_port_number
+ libusb_get_port_numbers
+ libusb_get_port_numbers@12 = libusb_get_port_numbers
+ libusb_get_port_path
+ libusb_get_port_path@16 = libusb_get_port_path
+ libusb_get_ss_endpoint_companion_descriptor
+ libusb_get_ss_endpoint_companion_descriptor@12 = libusb_get_ss_endpoint_companion_descriptor
+ libusb_get_ss_usb_device_capability_descriptor
+ libusb_get_ss_usb_device_capability_descriptor@12 = libusb_get_ss_usb_device_capability_descriptor
+ libusb_get_string_descriptor_ascii
+ libusb_get_string_descriptor_ascii@16 = libusb_get_string_descriptor_ascii
+ libusb_get_usb_2_0_extension_descriptor
+ libusb_get_usb_2_0_extension_descriptor@12 = libusb_get_usb_2_0_extension_descriptor
+ libusb_get_version
+ libusb_get_version@0 = libusb_get_version
+ libusb_handle_events
+ libusb_handle_events@4 = libusb_handle_events
+ libusb_handle_events_completed
+ libusb_handle_events_completed@8 = libusb_handle_events_completed
+ libusb_handle_events_locked
+ libusb_handle_events_locked@8 = libusb_handle_events_locked
+ libusb_handle_events_timeout
+ libusb_handle_events_timeout@8 = libusb_handle_events_timeout
+ libusb_handle_events_timeout_completed
+ libusb_handle_events_timeout_completed@12 = libusb_handle_events_timeout_completed
+ libusb_has_capability
+ libusb_has_capability@4 = libusb_has_capability
+ libusb_hotplug_deregister_callback
+ libusb_hotplug_deregister_callback@8 = libusb_hotplug_deregister_callback
+ libusb_hotplug_register_callback
+ libusb_hotplug_register_callback@36 = libusb_hotplug_register_callback
+ libusb_init
+ libusb_init@4 = libusb_init
+ libusb_interrupt_event_handler
+ libusb_interrupt_event_handler@4 = libusb_interrupt_event_handler
+ libusb_interrupt_transfer
+ libusb_interrupt_transfer@24 = libusb_interrupt_transfer
+ libusb_kernel_driver_active
+ libusb_kernel_driver_active@8 = libusb_kernel_driver_active
+ libusb_lock_event_waiters
+ libusb_lock_event_waiters@4 = libusb_lock_event_waiters
+ libusb_lock_events
+ libusb_lock_events@4 = libusb_lock_events
+ libusb_open
+ libusb_open@8 = libusb_open
+ libusb_open_device_with_vid_pid
+ libusb_open_device_with_vid_pid@12 = libusb_open_device_with_vid_pid
+ libusb_pollfds_handle_timeouts
+ libusb_pollfds_handle_timeouts@4 = libusb_pollfds_handle_timeouts
+ libusb_ref_device
+ libusb_ref_device@4 = libusb_ref_device
+ libusb_release_interface
+ libusb_release_interface@8 = libusb_release_interface
+ libusb_reset_device
+ libusb_reset_device@4 = libusb_reset_device
+ libusb_set_auto_detach_kernel_driver
+ libusb_set_auto_detach_kernel_driver@8 = libusb_set_auto_detach_kernel_driver
+ libusb_set_configuration
+ libusb_set_configuration@8 = libusb_set_configuration
+ libusb_set_debug
+ libusb_set_debug@8 = libusb_set_debug
+ libusb_set_log_cb
+ libusb_set_log_cb@12 = libusb_set_log_cb
+ libusb_set_interface_alt_setting
+ libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
+ libusb_set_option
+ _libusb_set_option = libusb_set_option
+ libusb_set_pollfd_notifiers
+ libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
+ libusb_setlocale
+ libusb_setlocale@4 = libusb_setlocale
+ libusb_strerror
+ libusb_strerror@4 = libusb_strerror
+ libusb_submit_transfer
+ libusb_submit_transfer@4 = libusb_submit_transfer
+ libusb_transfer_get_stream_id
+ libusb_transfer_get_stream_id@4 = libusb_transfer_get_stream_id
+ libusb_transfer_set_stream_id
+ libusb_transfer_set_stream_id@8 = libusb_transfer_set_stream_id
+ libusb_try_lock_events
+ libusb_try_lock_events@4 = libusb_try_lock_events
+ libusb_unlock_event_waiters
+ libusb_unlock_event_waiters@4 = libusb_unlock_event_waiters
+ libusb_unlock_events
+ libusb_unlock_events@4 = libusb_unlock_events
+ libusb_unref_device
+ libusb_unref_device@4 = libusb_unref_device
+ libusb_wait_for_event
+ libusb_wait_for_event@8 = libusb_wait_for_event
diff --git a/libusb1/libusb-1.0.rc b/libusb1/libusb-1.0.rc
new file mode 100644
index 0000000..3dce6d5
--- /dev/null
+++ b/libusb1/libusb-1.0.rc
@@ -0,0 +1,61 @@
+/*
+ * For Windows: input this file to the Resoure Compiler to produce a binary
+ * .res file. This is then embedded in the resultant library (like any other
+ * compilation object).
+ * The information can then be queried using standard APIs and can also be
+ * viewed with utilities such as Windows Explorer.
+ */
+#ifndef _WIN32_WCE
+#include "winresrc.h"
+#endif
+
+#include "version.h"
+#ifndef LIBUSB_VERSIONSTRING
+#define LU_STR(s) #s
+#define LU_XSTR(s) LU_STR(s)
+#if LIBUSB_NANO > 0
+#define LIBUSB_VERSIONSTRING \
+ LU_XSTR(LIBUSB_MAJOR) "." LU_XSTR(LIBUSB_MINOR) "." \
+ LU_XSTR(LIBUSB_MICRO) "." LU_XSTR(LIBUSB_NANO) LIBUSB_RC "\0"
+#else
+#define LIBUSB_VERSIONSTRING \
+ LU_XSTR(LIBUSB_MAJOR) "." LU_XSTR(LIBUSB_MINOR) "." \
+ LU_XSTR(LIBUSB_MICRO) LIBUSB_RC "\0"
+#endif
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION LIBUSB_MAJOR,LIBUSB_MINOR,LIBUSB_MICRO,LIBUSB_NANO
+ PRODUCTVERSION LIBUSB_MAJOR,LIBUSB_MINOR,LIBUSB_MICRO,LIBUSB_NANO
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "libusb.info\0"
+ VALUE "FileDescription", "C library for writing portable USB drivers in userspace\0"
+ VALUE "FileVersion", LIBUSB_VERSIONSTRING
+ VALUE "InternalName", "libusb\0"
+ VALUE "LegalCopyright", "See individual source files, GNU LGPL v2.1 or later.\0"
+ VALUE "LegalTrademarks", "http://www.gnu.org/licenses/lgpl-2.1.html\0"
+ VALUE "OriginalFilename", "libusb-1.0.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "libusb-1.0\0"
+ VALUE "ProductVersion", LIBUSB_VERSIONSTRING
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/libusb1/libusb.h b/libusb1/libusb.h
new file mode 100644
index 0000000..8a6b0bf
--- /dev/null
+++ b/libusb1/libusb.h
@@ -0,0 +1,2066 @@
+/*
+ * Public libusb header file
+ * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
+ * Copyright © 2007-2008 Daniel Drake <dsd@gentoo.org>
+ * Copyright © 2012 Pete Batard <pete@akeo.ie>
+ * Copyright © 2012-2018 Nathan Hjelm <hjelmn@cs.unm.edu>
+ * For more information, please visit: http://libusb.info
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LIBUSB_H
+#define LIBUSB_H
+
+#ifdef _MSC_VER
+/* on MS environments, the inline keyword is available in C++ only */
+#if !defined(__cplusplus)
+#define inline __inline
+#endif
+/* ssize_t is also not available (copy/paste from MinGW) */
+#ifndef _SSIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+#undef ssize_t
+#ifdef _WIN64
+ typedef __int64 ssize_t;
+#else
+ typedef int ssize_t;
+#endif /* _WIN64 */
+#endif /* _SSIZE_T_DEFINED */
+#endif /* _MSC_VER */
+
+/* stdint.h is not available on older MSVC */
+#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H))
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+#else
+#include <stdint.h>
+#endif
+
+#if !defined(_WIN32_WCE)
+#include <sys/types.h>
+#endif
+
+#if defined(__linux__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__)
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+#include <limits.h>
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+#define ZERO_SIZED_ARRAY /* [] - valid C99 code */
+#else
+#define ZERO_SIZED_ARRAY 0 /* [0] - non-standard, but usually working code */
+#endif
+
+/* 'interface' might be defined as a macro on Windows, so we need to
+ * undefine it so as not to break the current libusb API, because
+ * libusb_config_descriptor has an 'interface' member
+ * As this can be problematic if you include windows.h after libusb.h
+ * in your sources, we force windows.h to be included first. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+#include <windows.h>
+#if defined(interface)
+#undef interface
+#endif
+#if !defined(__CYGWIN__)
+#include <winsock.h>
+#endif
+#endif
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define LIBUSB_DEPRECATED_FOR(f) \
+ __attribute__((deprecated("Use " #f " instead")))
+#elif __GNUC__ >= 3
+#define LIBUSB_DEPRECATED_FOR(f) __attribute__((deprecated))
+#else
+#define LIBUSB_DEPRECATED_FOR(f)
+#endif /* __GNUC__ */
+
+/** \def LIBUSB_CALL
+ * \ingroup libusb_misc
+ * libusb's Windows calling convention.
+ *
+ * Under Windows, the selection of available compilers and configurations
+ * means that, unlike other platforms, there is not <em>one true calling
+ * convention</em> (calling convention: the manner in which parameters are
+ * passed to functions in the generated assembly code).
+ *
+ * Matching the Windows API itself, libusb uses the WINAPI convention (which
+ * translates to the <tt>stdcall</tt> convention) and guarantees that the
+ * library is compiled in this way. The public header file also includes
+ * appropriate annotations so that your own software will use the right
+ * convention, even if another convention is being used by default within
+ * your codebase.
+ *
+ * The one consideration that you must apply in your software is to mark
+ * all functions which you use as libusb callbacks with this LIBUSB_CALL
+ * annotation, so that they too get compiled for the correct calling
+ * convention.
+ *
+ * On non-Windows operating systems, this macro is defined as nothing. This
+ * means that you can apply it to your code without worrying about
+ * cross-platform compatibility.
+ */
+/* LIBUSB_CALL must be defined on both definition and declaration of libusb
+ * functions. You'd think that declaration would be enough, but cygwin will
+ * complain about conflicting types unless both are marked this way.
+ * The placement of this macro is important too; it must appear after the
+ * return type, before the function name. See internal documentation for
+ * API_EXPORTED.
+ */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+#define LIBUSB_CALL WINAPI
+#else
+#define LIBUSB_CALL
+#endif
+
+/** \def LIBUSB_API_VERSION
+ * \ingroup libusb_misc
+ * libusb's API version.
+ *
+ * Since version 1.0.13, to help with feature detection, libusb defines
+ * a LIBUSB_API_VERSION macro that gets increased every time there is a
+ * significant change to the API, such as the introduction of a new call,
+ * the definition of a new macro/enum member, or any other element that
+ * libusb applications may want to detect at compilation time.
+ *
+ * The macro is typically used in an application as follows:
+ * \code
+ * #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01001234)
+ * // Use one of the newer features from the libusb API
+ * #endif
+ * \endcode
+ *
+ * Internally, LIBUSB_API_VERSION is defined as follows:
+ * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental)
+ */
+#define LIBUSB_API_VERSION 0x01000107
+
+/* The following is kept for compatibility, but will be deprecated in the future */
+#define LIBUSBX_API_VERSION LIBUSB_API_VERSION
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \ingroup libusb_misc
+ * Convert a 16-bit value from host-endian to little-endian format. On
+ * little endian systems, this function does nothing. On big endian systems,
+ * the bytes are swapped.
+ * \param x the host-endian value to convert
+ * \returns the value in little-endian byte order
+ */
+static inline uint16_t libusb_cpu_to_le16(const uint16_t x)
+{
+ union {
+ uint8_t b8[2];
+ uint16_t b16;
+ } _tmp;
+ _tmp.b8[1] = (uint8_t) (x >> 8);
+ _tmp.b8[0] = (uint8_t) (x & 0xff);
+ return _tmp.b16;
+}
+
+/** \def libusb_le16_to_cpu
+ * \ingroup libusb_misc
+ * Convert a 16-bit value from little-endian to host-endian format. On
+ * little endian systems, this function does nothing. On big endian systems,
+ * the bytes are swapped.
+ * \param x the little-endian value to convert
+ * \returns the value in host-endian byte order
+ */
+#define libusb_le16_to_cpu libusb_cpu_to_le16
+
+/* standard USB stuff */
+
+/** \ingroup libusb_desc
+ * Device and/or Interface Class codes */
+enum libusb_class_code {
+ /** In the context of a \ref libusb_device_descriptor "device descriptor",
+ * this bDeviceClass value indicates that each interface specifies its
+ * own class information and all interfaces operate independently.
+ */
+ LIBUSB_CLASS_PER_INTERFACE = 0,
+
+ /** Audio class */
+ LIBUSB_CLASS_AUDIO = 1,
+
+ /** Communications class */
+ LIBUSB_CLASS_COMM = 2,
+
+ /** Human Interface Device class */
+ LIBUSB_CLASS_HID = 3,
+
+ /** Physical */
+ LIBUSB_CLASS_PHYSICAL = 5,
+
+ /** Printer class */
+ LIBUSB_CLASS_PRINTER = 7,
+
+ /** Image class */
+ LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */
+ LIBUSB_CLASS_IMAGE = 6,
+
+ /** Mass storage class */
+ LIBUSB_CLASS_MASS_STORAGE = 8,
+
+ /** Hub class */
+ LIBUSB_CLASS_HUB = 9,
+
+ /** Data class */
+ LIBUSB_CLASS_DATA = 10,
+
+ /** Smart Card */
+ LIBUSB_CLASS_SMART_CARD = 0x0b,
+
+ /** Content Security */
+ LIBUSB_CLASS_CONTENT_SECURITY = 0x0d,
+
+ /** Video */
+ LIBUSB_CLASS_VIDEO = 0x0e,
+
+ /** Personal Healthcare */
+ LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f,
+
+ /** Diagnostic Device */
+ LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc,
+
+ /** Wireless class */
+ LIBUSB_CLASS_WIRELESS = 0xe0,
+
+ /** Application class */
+ LIBUSB_CLASS_APPLICATION = 0xfe,
+
+ /** Class is vendor-specific */
+ LIBUSB_CLASS_VENDOR_SPEC = 0xff
+};
+
+/** \ingroup libusb_desc
+ * Descriptor types as defined by the USB specification. */
+enum libusb_descriptor_type {
+ /** Device descriptor. See libusb_device_descriptor. */
+ LIBUSB_DT_DEVICE = 0x01,
+
+ /** Configuration descriptor. See libusb_config_descriptor. */
+ LIBUSB_DT_CONFIG = 0x02,
+
+ /** String descriptor */
+ LIBUSB_DT_STRING = 0x03,
+
+ /** Interface descriptor. See libusb_interface_descriptor. */
+ LIBUSB_DT_INTERFACE = 0x04,
+
+ /** Endpoint descriptor. See libusb_endpoint_descriptor. */
+ LIBUSB_DT_ENDPOINT = 0x05,
+
+ /** BOS descriptor */
+ LIBUSB_DT_BOS = 0x0f,
+
+ /** Device Capability descriptor */
+ LIBUSB_DT_DEVICE_CAPABILITY = 0x10,
+
+ /** HID descriptor */
+ LIBUSB_DT_HID = 0x21,
+
+ /** HID report descriptor */
+ LIBUSB_DT_REPORT = 0x22,
+
+ /** Physical descriptor */
+ LIBUSB_DT_PHYSICAL = 0x23,
+
+ /** Hub descriptor */
+ LIBUSB_DT_HUB = 0x29,
+
+ /** SuperSpeed Hub descriptor */
+ LIBUSB_DT_SUPERSPEED_HUB = 0x2a,
+
+ /** SuperSpeed Endpoint Companion descriptor */
+ LIBUSB_DT_SS_ENDPOINT_COMPANION = 0x30
+};
+
+/* Descriptor sizes per descriptor type */
+#define LIBUSB_DT_DEVICE_SIZE 18
+#define LIBUSB_DT_CONFIG_SIZE 9
+#define LIBUSB_DT_INTERFACE_SIZE 9
+#define LIBUSB_DT_ENDPOINT_SIZE 7
+#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
+#define LIBUSB_DT_HUB_NONVAR_SIZE 7
+#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6
+#define LIBUSB_DT_BOS_SIZE 5
+#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3
+
+/* BOS descriptor sizes */
+#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7
+#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10
+#define LIBUSB_BT_CONTAINER_ID_SIZE 20
+
+/* We unwrap the BOS => define its max size */
+#define LIBUSB_DT_BOS_MAX_SIZE ((LIBUSB_DT_BOS_SIZE) +\
+ (LIBUSB_BT_USB_2_0_EXTENSION_SIZE) +\
+ (LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) +\
+ (LIBUSB_BT_CONTAINER_ID_SIZE))
+
+#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
+#define LIBUSB_ENDPOINT_DIR_MASK 0x80
+
+/** \ingroup libusb_desc
+ * Endpoint direction. Values for bit 7 of the
+ * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme.
+ */
+enum libusb_endpoint_direction {
+ /** In: device-to-host */
+ LIBUSB_ENDPOINT_IN = 0x80,
+
+ /** Out: host-to-device */
+ LIBUSB_ENDPOINT_OUT = 0x00
+};
+
+#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */
+
+/** \ingroup libusb_desc
+ * Endpoint transfer type. Values for bits 0:1 of the
+ * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field.
+ */
+enum libusb_transfer_type {
+ /** Control endpoint */
+ LIBUSB_TRANSFER_TYPE_CONTROL = 0,
+
+ /** Isochronous endpoint */
+ LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1,
+
+ /** Bulk endpoint */
+ LIBUSB_TRANSFER_TYPE_BULK = 2,
+
+ /** Interrupt endpoint */
+ LIBUSB_TRANSFER_TYPE_INTERRUPT = 3,
+
+ /** Stream endpoint */
+ LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4,
+};
+
+/** \ingroup libusb_misc
+ * Standard requests, as defined in table 9-5 of the USB 3.0 specifications */
+enum libusb_standard_request {
+ /** Request status of the specific recipient */
+ LIBUSB_REQUEST_GET_STATUS = 0x00,
+
+ /** Clear or disable a specific feature */
+ LIBUSB_REQUEST_CLEAR_FEATURE = 0x01,
+
+ /* 0x02 is reserved */
+
+ /** Set or enable a specific feature */
+ LIBUSB_REQUEST_SET_FEATURE = 0x03,
+
+ /* 0x04 is reserved */
+
+ /** Set device address for all future accesses */
+ LIBUSB_REQUEST_SET_ADDRESS = 0x05,
+
+ /** Get the specified descriptor */
+ LIBUSB_REQUEST_GET_DESCRIPTOR = 0x06,
+
+ /** Used to update existing descriptors or add new descriptors */
+ LIBUSB_REQUEST_SET_DESCRIPTOR = 0x07,
+
+ /** Get the current device configuration value */
+ LIBUSB_REQUEST_GET_CONFIGURATION = 0x08,
+
+ /** Set device configuration */
+ LIBUSB_REQUEST_SET_CONFIGURATION = 0x09,
+
+ /** Return the selected alternate setting for the specified interface */
+ LIBUSB_REQUEST_GET_INTERFACE = 0x0A,
+
+ /** Select an alternate interface for the specified interface */
+ LIBUSB_REQUEST_SET_INTERFACE = 0x0B,
+
+ /** Set then report an endpoint's synchronization frame */
+ LIBUSB_REQUEST_SYNCH_FRAME = 0x0C,
+
+ /** Sets both the U1 and U2 Exit Latency */
+ LIBUSB_REQUEST_SET_SEL = 0x30,
+
+ /** Delay from the time a host transmits a packet to the time it is
+ * received by the device. */
+ LIBUSB_SET_ISOCH_DELAY = 0x31,
+};
+
+/** \ingroup libusb_misc
+ * Request type bits of the
+ * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control
+ * transfers. */
+enum libusb_request_type {
+ /** Standard */
+ LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5),
+
+ /** Class */
+ LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5),
+
+ /** Vendor */
+ LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5),
+
+ /** Reserved */
+ LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5)
+};
+
+/** \ingroup libusb_misc
+ * Recipient bits of the
+ * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control
+ * transfers. Values 4 through 31 are reserved. */
+enum libusb_request_recipient {
+ /** Device */
+ LIBUSB_RECIPIENT_DEVICE = 0x00,
+
+ /** Interface */
+ LIBUSB_RECIPIENT_INTERFACE = 0x01,
+
+ /** Endpoint */
+ LIBUSB_RECIPIENT_ENDPOINT = 0x02,
+
+ /** Other */
+ LIBUSB_RECIPIENT_OTHER = 0x03,
+};
+
+#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C
+
+/** \ingroup libusb_desc
+ * Synchronization type for isochronous endpoints. Values for bits 2:3 of the
+ * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in
+ * libusb_endpoint_descriptor.
+ */
+enum libusb_iso_sync_type {
+ /** No synchronization */
+ LIBUSB_ISO_SYNC_TYPE_NONE = 0,
+
+ /** Asynchronous */
+ LIBUSB_ISO_SYNC_TYPE_ASYNC = 1,
+
+ /** Adaptive */
+ LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2,
+
+ /** Synchronous */
+ LIBUSB_ISO_SYNC_TYPE_SYNC = 3
+};
+
+#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30
+
+/** \ingroup libusb_desc
+ * Usage type for isochronous endpoints. Values for bits 4:5 of the
+ * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in
+ * libusb_endpoint_descriptor.
+ */
+enum libusb_iso_usage_type {
+ /** Data endpoint */
+ LIBUSB_ISO_USAGE_TYPE_DATA = 0,
+
+ /** Feedback endpoint */
+ LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1,
+
+ /** Implicit feedback Data endpoint */
+ LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2,
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the standard USB device descriptor. This
+ * descriptor is documented in section 9.6.1 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_device_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this
+ * context. */
+ uint8_t bDescriptorType;
+
+ /** USB specification release number in binary-coded decimal. A value of
+ * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */
+ uint16_t bcdUSB;
+
+ /** USB-IF class code for the device. See \ref libusb_class_code. */
+ uint8_t bDeviceClass;
+
+ /** USB-IF subclass code for the device, qualified by the bDeviceClass
+ * value */
+ uint8_t bDeviceSubClass;
+
+ /** USB-IF protocol code for the device, qualified by the bDeviceClass and
+ * bDeviceSubClass values */
+ uint8_t bDeviceProtocol;
+
+ /** Maximum packet size for endpoint 0 */
+ uint8_t bMaxPacketSize0;
+
+ /** USB-IF vendor ID */
+ uint16_t idVendor;
+
+ /** USB-IF product ID */
+ uint16_t idProduct;
+
+ /** Device release number in binary-coded decimal */
+ uint16_t bcdDevice;
+
+ /** Index of string descriptor describing manufacturer */
+ uint8_t iManufacturer;
+
+ /** Index of string descriptor describing product */
+ uint8_t iProduct;
+
+ /** Index of string descriptor containing device serial number */
+ uint8_t iSerialNumber;
+
+ /** Number of possible configurations */
+ uint8_t bNumConfigurations;
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the standard USB endpoint descriptor. This
+ * descriptor is documented in section 9.6.6 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_endpoint_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in
+ * this context. */
+ uint8_t bDescriptorType;
+
+ /** The address of the endpoint described by this descriptor. Bits 0:3 are
+ * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction,
+ * see \ref libusb_endpoint_direction.
+ */
+ uint8_t bEndpointAddress;
+
+ /** Attributes which apply to the endpoint when it is configured using
+ * the bConfigurationValue. Bits 0:1 determine the transfer type and
+ * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for
+ * isochronous endpoints and correspond to \ref libusb_iso_sync_type.
+ * Bits 4:5 are also only used for isochronous endpoints and correspond to
+ * \ref libusb_iso_usage_type. Bits 6:7 are reserved.
+ */
+ uint8_t bmAttributes;
+
+ /** Maximum packet size this endpoint is capable of sending/receiving. */
+ uint16_t wMaxPacketSize;
+
+ /** Interval for polling endpoint for data transfers. */
+ uint8_t bInterval;
+
+ /** For audio devices only: the rate at which synchronization feedback
+ * is provided. */
+ uint8_t bRefresh;
+
+ /** For audio devices only: the address if the synch endpoint */
+ uint8_t bSynchAddress;
+
+ /** Extra descriptors. If libusb encounters unknown endpoint descriptors,
+ * it will store them here, should you wish to parse them. */
+ const unsigned char *extra;
+
+ /** Length of the extra descriptors, in bytes. Must be non-negative. */
+ int extra_length;
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the standard USB interface descriptor. This
+ * descriptor is documented in section 9.6.5 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_interface_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE
+ * in this context. */
+ uint8_t bDescriptorType;
+
+ /** Number of this interface */
+ uint8_t bInterfaceNumber;
+
+ /** Value used to select this alternate setting for this interface */
+ uint8_t bAlternateSetting;
+
+ /** Number of endpoints used by this interface (excluding the control
+ * endpoint). */
+ uint8_t bNumEndpoints;
+
+ /** USB-IF class code for this interface. See \ref libusb_class_code. */
+ uint8_t bInterfaceClass;
+
+ /** USB-IF subclass code for this interface, qualified by the
+ * bInterfaceClass value */
+ uint8_t bInterfaceSubClass;
+
+ /** USB-IF protocol code for this interface, qualified by the
+ * bInterfaceClass and bInterfaceSubClass values */
+ uint8_t bInterfaceProtocol;
+
+ /** Index of string descriptor describing this interface */
+ uint8_t iInterface;
+
+ /** Array of endpoint descriptors. This length of this array is determined
+ * by the bNumEndpoints field. */
+ const struct libusb_endpoint_descriptor *endpoint;
+
+ /** Extra descriptors. If libusb encounters unknown interface descriptors,
+ * it will store them here, should you wish to parse them. */
+ const unsigned char *extra;
+
+ /** Length of the extra descriptors, in bytes. Must be non-negative. */
+ int extra_length;
+};
+
+/** \ingroup libusb_desc
+ * A collection of alternate settings for a particular USB interface.
+ */
+struct libusb_interface {
+ /** Array of interface descriptors. The length of this array is determined
+ * by the num_altsetting field. */
+ const struct libusb_interface_descriptor *altsetting;
+
+ /** The number of alternate settings that belong to this interface.
+ * Must be non-negative. */
+ int num_altsetting;
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the standard USB configuration descriptor. This
+ * descriptor is documented in section 9.6.3 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_config_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG
+ * in this context. */
+ uint8_t bDescriptorType;
+
+ /** Total length of data returned for this configuration */
+ uint16_t wTotalLength;
+
+ /** Number of interfaces supported by this configuration */
+ uint8_t bNumInterfaces;
+
+ /** Identifier value for this configuration */
+ uint8_t bConfigurationValue;
+
+ /** Index of string descriptor describing this configuration */
+ uint8_t iConfiguration;
+
+ /** Configuration characteristics */
+ uint8_t bmAttributes;
+
+ /** Maximum power consumption of the USB device from this bus in this
+ * configuration when the device is fully operation. Expressed in units
+ * of 2 mA when the device is operating in high-speed mode and in units
+ * of 8 mA when the device is operating in super-speed mode. */
+ uint8_t MaxPower;
+
+ /** Array of interfaces supported by this configuration. The length of
+ * this array is determined by the bNumInterfaces field. */
+ const struct libusb_interface *interface;
+
+ /** Extra descriptors. If libusb encounters unknown configuration
+ * descriptors, it will store them here, should you wish to parse them. */
+ const unsigned char *extra;
+
+ /** Length of the extra descriptors, in bytes. Must be non-negative. */
+ int extra_length;
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the superspeed endpoint companion
+ * descriptor. This descriptor is documented in section 9.6.7 of
+ * the USB 3.0 specification. All multiple-byte fields are represented in
+ * host-endian format.
+ */
+struct libusb_ss_endpoint_companion_descriptor {
+
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in
+ * this context. */
+ uint8_t bDescriptorType;
+
+
+ /** The maximum number of packets the endpoint can send or
+ * receive as part of a burst. */
+ uint8_t bMaxBurst;
+
+ /** In bulk EP: bits 4:0 represents the maximum number of
+ * streams the EP supports. In isochronous EP: bits 1:0
+ * represents the Mult - a zero based value that determines
+ * the maximum number of packets within a service interval */
+ uint8_t bmAttributes;
+
+ /** The total number of bytes this EP will transfer every
+ * service interval. valid only for periodic EPs. */
+ uint16_t wBytesPerInterval;
+};
+
+/** \ingroup libusb_desc
+ * A generic representation of a BOS Device Capability descriptor. It is
+ * advised to check bDevCapabilityType and call the matching
+ * libusb_get_*_descriptor function to get a structure fully matching the type.
+ */
+struct libusb_bos_dev_capability_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+ * LIBUSB_DT_DEVICE_CAPABILITY in this context. */
+ uint8_t bDescriptorType;
+ /** Device Capability type */
+ uint8_t bDevCapabilityType;
+ /** Device Capability data (bLength - 3 bytes) */
+ uint8_t dev_capability_data[ZERO_SIZED_ARRAY];
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the Binary Device Object Store (BOS) descriptor.
+ * This descriptor is documented in section 9.6.2 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_bos_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS
+ * in this context. */
+ uint8_t bDescriptorType;
+
+ /** Length of this descriptor and all of its sub descriptors */
+ uint16_t wTotalLength;
+
+ /** The number of separate device capability descriptors in
+ * the BOS */
+ uint8_t bNumDeviceCaps;
+
+ /** bNumDeviceCap Device Capability Descriptors */
+ struct libusb_bos_dev_capability_descriptor *dev_capability[ZERO_SIZED_ARRAY];
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the USB 2.0 Extension descriptor
+ * This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_usb_2_0_extension_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+ * LIBUSB_DT_DEVICE_CAPABILITY in this context. */
+ uint8_t bDescriptorType;
+
+ /** Capability type. Will have value
+ * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
+ * LIBUSB_BT_USB_2_0_EXTENSION in this context. */
+ uint8_t bDevCapabilityType;
+
+ /** Bitmap encoding of supported device level features.
+ * A value of one in a bit location indicates a feature is
+ * supported; a value of zero indicates it is not supported.
+ * See \ref libusb_usb_2_0_extension_attributes. */
+ uint32_t bmAttributes;
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the SuperSpeed USB Device Capability descriptor
+ * This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification.
+ * All multiple-byte fields are represented in host-endian format.
+ */
+struct libusb_ss_usb_device_capability_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+ * LIBUSB_DT_DEVICE_CAPABILITY in this context. */
+ uint8_t bDescriptorType;
+
+ /** Capability type. Will have value
+ * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
+ * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context. */
+ uint8_t bDevCapabilityType;
+
+ /** Bitmap encoding of supported device level features.
+ * A value of one in a bit location indicates a feature is
+ * supported; a value of zero indicates it is not supported.
+ * See \ref libusb_ss_usb_device_capability_attributes. */
+ uint8_t bmAttributes;
+
+ /** Bitmap encoding of the speed supported by this device when
+ * operating in SuperSpeed mode. See \ref libusb_supported_speed. */
+ uint16_t wSpeedSupported;
+
+ /** The lowest speed at which all the functionality supported
+ * by the device is available to the user. For example if the
+ * device supports all its functionality when connected at
+ * full speed and above then it sets this value to 1. */
+ uint8_t bFunctionalitySupport;
+
+ /** U1 Device Exit Latency. */
+ uint8_t bU1DevExitLat;
+
+ /** U2 Device Exit Latency. */
+ uint16_t bU2DevExitLat;
+};
+
+/** \ingroup libusb_desc
+ * A structure representing the Container ID descriptor.
+ * This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification.
+ * All multiple-byte fields, except UUIDs, are represented in host-endian format.
+ */
+struct libusb_container_id_descriptor {
+ /** Size of this descriptor (in bytes) */
+ uint8_t bLength;
+
+ /** Descriptor type. Will have value
+ * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
+ * LIBUSB_DT_DEVICE_CAPABILITY in this context. */
+ uint8_t bDescriptorType;
+
+ /** Capability type. Will have value
+ * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
+ * LIBUSB_BT_CONTAINER_ID in this context. */
+ uint8_t bDevCapabilityType;
+
+ /** Reserved field */
+ uint8_t bReserved;
+
+ /** 128 bit UUID */
+ uint8_t ContainerID[16];
+};
+
+/** \ingroup libusb_asyncio
+ * Setup packet for control transfers. */
+struct libusb_control_setup {
+ /** Request type. Bits 0:4 determine recipient, see
+ * \ref libusb_request_recipient. Bits 5:6 determine type, see
+ * \ref libusb_request_type. Bit 7 determines data transfer direction, see
+ * \ref libusb_endpoint_direction.
+ */
+ uint8_t bmRequestType;
+
+ /** Request. If the type bits of bmRequestType are equal to
+ * \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD
+ * "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to
+ * \ref libusb_standard_request. For other cases, use of this field is
+ * application-specific. */
+ uint8_t bRequest;
+
+ /** Value. Varies according to request */
+ uint16_t wValue;
+
+ /** Index. Varies according to request, typically used to pass an index
+ * or offset */
+ uint16_t wIndex;
+
+ /** Number of bytes to transfer */
+ uint16_t wLength;
+};
+
+#define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup))
+
+/* libusb */
+
+struct libusb_context;
+struct libusb_device;
+struct libusb_device_handle;
+
+/** \ingroup libusb_lib
+ * Structure providing the version of the libusb runtime
+ */
+struct libusb_version {
+ /** Library major version. */
+ const uint16_t major;
+
+ /** Library minor version. */
+ const uint16_t minor;
+
+ /** Library micro version. */
+ const uint16_t micro;
+
+ /** Library nano version. */
+ const uint16_t nano;
+
+ /** Library release candidate suffix string, e.g. "-rc4". */
+ const char *rc;
+
+ /** For ABI compatibility only. */
+ const char* describe;
+};
+
+/** \ingroup libusb_lib
+ * Structure representing a libusb session. The concept of individual libusb
+ * sessions allows for your program to use two libraries (or dynamically
+ * load two modules) which both independently use libusb. This will prevent
+ * interference between the individual libusb users - for example
+ * libusb_set_option() will not affect the other user of the library, and
+ * libusb_exit() will not destroy resources that the other user is still
+ * using.
+ *
+ * Sessions are created by libusb_init() and destroyed through libusb_exit().
+ * If your application is guaranteed to only ever include a single libusb
+ * user (i.e. you), you do not have to worry about contexts: pass NULL in
+ * every function call where a context is required. The default context
+ * will be used.
+ *
+ * For more information, see \ref libusb_contexts.
+ */
+typedef struct libusb_context libusb_context;
+
+/** \ingroup libusb_dev
+ * Structure representing a USB device detected on the system. This is an
+ * opaque type for which you are only ever provided with a pointer, usually
+ * originating from libusb_get_device_list().
+ *
+ * Certain operations can be performed on a device, but in order to do any
+ * I/O you will have to first obtain a device handle using libusb_open().
+ *
+ * Devices are reference counted with libusb_ref_device() and
+ * libusb_unref_device(), and are freed when the reference count reaches 0.
+ * New devices presented by libusb_get_device_list() have a reference count of
+ * 1, and libusb_free_device_list() can optionally decrease the reference count
+ * on all devices in the list. libusb_open() adds another reference which is
+ * later destroyed by libusb_close().
+ */
+typedef struct libusb_device libusb_device;
+
+
+/** \ingroup libusb_dev
+ * Structure representing a handle on a USB device. This is an opaque type for
+ * which you are only ever provided with a pointer, usually originating from
+ * libusb_open().
+ *
+ * A device handle is used to perform I/O and other operations. When finished
+ * with a device handle, you should call libusb_close().
+ */
+typedef struct libusb_device_handle libusb_device_handle;
+
+/** \ingroup libusb_dev
+ * Speed codes. Indicates the speed at which the device is operating.
+ */
+enum libusb_speed {
+ /** The OS doesn't report or know the device speed. */
+ LIBUSB_SPEED_UNKNOWN = 0,
+
+ /** The device is operating at low speed (1.5MBit/s). */
+ LIBUSB_SPEED_LOW = 1,
+
+ /** The device is operating at full speed (12MBit/s). */
+ LIBUSB_SPEED_FULL = 2,
+
+ /** The device is operating at high speed (480MBit/s). */
+ LIBUSB_SPEED_HIGH = 3,
+
+ /** The device is operating at super speed (5000MBit/s). */
+ LIBUSB_SPEED_SUPER = 4,
+
+ /** The device is operating at super speed plus (10000MBit/s). */
+ LIBUSB_SPEED_SUPER_PLUS = 5,
+};
+
+/** \ingroup libusb_dev
+ * Supported speeds (wSpeedSupported) bitfield. Indicates what
+ * speeds the device supports.
+ */
+enum libusb_supported_speed {
+ /** Low speed operation supported (1.5MBit/s). */
+ LIBUSB_LOW_SPEED_OPERATION = 1,
+
+ /** Full speed operation supported (12MBit/s). */
+ LIBUSB_FULL_SPEED_OPERATION = 2,
+
+ /** High speed operation supported (480MBit/s). */
+ LIBUSB_HIGH_SPEED_OPERATION = 4,
+
+ /** Superspeed operation supported (5000MBit/s). */
+ LIBUSB_SUPER_SPEED_OPERATION = 8,
+};
+
+/** \ingroup libusb_dev
+ * Masks for the bits of the
+ * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field
+ * of the USB 2.0 Extension descriptor.
+ */
+enum libusb_usb_2_0_extension_attributes {
+ /** Supports Link Power Management (LPM) */
+ LIBUSB_BM_LPM_SUPPORT = 2,
+};
+
+/** \ingroup libusb_dev
+ * Masks for the bits of the
+ * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field
+ * field of the SuperSpeed USB Device Capability descriptor.
+ */
+enum libusb_ss_usb_device_capability_attributes {
+ /** Supports Latency Tolerance Messages (LTM) */
+ LIBUSB_BM_LTM_SUPPORT = 2,
+};
+
+/** \ingroup libusb_dev
+ * USB capability types
+ */
+enum libusb_bos_type {
+ /** Wireless USB device capability */
+ LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1,
+
+ /** USB 2.0 extensions */
+ LIBUSB_BT_USB_2_0_EXTENSION = 2,
+
+ /** SuperSpeed USB device capability */
+ LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3,
+
+ /** Container ID type */
+ LIBUSB_BT_CONTAINER_ID = 4,
+};
+
+/** \ingroup libusb_misc
+ * Error codes. Most libusb functions return 0 on success or one of these
+ * codes on failure.
+ * You can call libusb_error_name() to retrieve a string representation of an
+ * error code or libusb_strerror() to get an end-user suitable description of
+ * an error code.
+ */
+enum libusb_error {
+ /** Success (no error) */
+ LIBUSB_SUCCESS = 0,
+
+ /** Input/output error */
+ LIBUSB_ERROR_IO = -1,
+
+ /** Invalid parameter */
+ LIBUSB_ERROR_INVALID_PARAM = -2,
+
+ /** Access denied (insufficient permissions) */
+ LIBUSB_ERROR_ACCESS = -3,
+
+ /** No such device (it may have been disconnected) */
+ LIBUSB_ERROR_NO_DEVICE = -4,
+
+ /** Entity not found */
+ LIBUSB_ERROR_NOT_FOUND = -5,
+
+ /** Resource busy */
+ LIBUSB_ERROR_BUSY = -6,
+
+ /** Operation timed out */
+ LIBUSB_ERROR_TIMEOUT = -7,
+
+ /** Overflow */
+ LIBUSB_ERROR_OVERFLOW = -8,
+
+ /** Pipe error */
+ LIBUSB_ERROR_PIPE = -9,
+
+ /** System call interrupted (perhaps due to signal) */
+ LIBUSB_ERROR_INTERRUPTED = -10,
+
+ /** Insufficient memory */
+ LIBUSB_ERROR_NO_MEM = -11,
+
+ /** Operation not supported or unimplemented on this platform */
+ LIBUSB_ERROR_NOT_SUPPORTED = -12,
+
+ /* NB: Remember to update LIBUSB_ERROR_COUNT below as well as the
+ message strings in strerror.c when adding new error codes here. */
+
+ /** Other error */
+ LIBUSB_ERROR_OTHER = -99,
+};
+
+/* Total number of error codes in enum libusb_error */
+#define LIBUSB_ERROR_COUNT 14
+
+/** \ingroup libusb_asyncio
+ * Transfer status codes */
+enum libusb_transfer_status {
+ /** Transfer completed without error. Note that this does not indicate
+ * that the entire amount of requested data was transferred. */
+ LIBUSB_TRANSFER_COMPLETED,
+
+ /** Transfer failed */
+ LIBUSB_TRANSFER_ERROR,
+
+ /** Transfer timed out */
+ LIBUSB_TRANSFER_TIMED_OUT,
+
+ /** Transfer was cancelled */
+ LIBUSB_TRANSFER_CANCELLED,
+
+ /** For bulk/interrupt endpoints: halt condition detected (endpoint
+ * stalled). For control endpoints: control request not supported. */
+ LIBUSB_TRANSFER_STALL,
+
+ /** Device was disconnected */
+ LIBUSB_TRANSFER_NO_DEVICE,
+
+ /** Device sent more data than requested */
+ LIBUSB_TRANSFER_OVERFLOW,
+
+ /* NB! Remember to update libusb_error_name()
+ when adding new status codes here. */
+};
+
+/** \ingroup libusb_asyncio
+ * libusb_transfer.flags values */
+enum libusb_transfer_flags {
+ /** Report short frames as errors */
+ LIBUSB_TRANSFER_SHORT_NOT_OK = 1U << 0,
+
+ /** Automatically free() transfer buffer during libusb_free_transfer().
+ * Note that buffers allocated with libusb_dev_mem_alloc() should not
+ * be attempted freed in this way, since free() is not an appropriate
+ * way to release such memory. */
+ LIBUSB_TRANSFER_FREE_BUFFER = 1U << 1,
+
+ /** Automatically call libusb_free_transfer() after callback returns.
+ * If this flag is set, it is illegal to call libusb_free_transfer()
+ * from your transfer callback, as this will result in a double-free
+ * when this flag is acted upon. */
+ LIBUSB_TRANSFER_FREE_TRANSFER = 1U << 2,
+
+ /** Terminate transfers that are a multiple of the endpoint's
+ * wMaxPacketSize with an extra zero length packet. This is useful
+ * when a device protocol mandates that each logical request is
+ * terminated by an incomplete packet (i.e. the logical requests are
+ * not separated by other means).
+ *
+ * This flag only affects host-to-device transfers to bulk and interrupt
+ * endpoints. In other situations, it is ignored.
+ *
+ * This flag only affects transfers with a length that is a multiple of
+ * the endpoint's wMaxPacketSize. On transfers of other lengths, this
+ * flag has no effect. Therefore, if you are working with a device that
+ * needs a ZLP whenever the end of the logical request falls on a packet
+ * boundary, then it is sensible to set this flag on <em>every</em>
+ * transfer (you do not have to worry about only setting it on transfers
+ * that end on the boundary).
+ *
+ * This flag is currently only supported on Linux.
+ * On other systems, libusb_submit_transfer() will return
+ * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set.
+ *
+ * Available since libusb-1.0.9.
+ */
+ LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1U << 3,
+};
+
+/** \ingroup libusb_asyncio
+ * Isochronous packet descriptor. */
+struct libusb_iso_packet_descriptor {
+ /** Length of data to request in this packet */
+ unsigned int length;
+
+ /** Amount of data that was actually transferred */
+ unsigned int actual_length;
+
+ /** Status code for this packet */
+ enum libusb_transfer_status status;
+};
+
+struct libusb_transfer;
+
+/** \ingroup libusb_asyncio
+ * Asynchronous transfer callback function type. When submitting asynchronous
+ * transfers, you pass a pointer to a callback function of this type via the
+ * \ref libusb_transfer::callback "callback" member of the libusb_transfer
+ * structure. libusb will call this function later, when the transfer has
+ * completed or failed. See \ref libusb_asyncio for more information.
+ * \param transfer The libusb_transfer struct the callback function is being
+ * notified about.
+ */
+typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer);
+
+/** \ingroup libusb_asyncio
+ * The generic USB transfer structure. The user populates this structure and
+ * then submits it in order to request a transfer. After the transfer has
+ * completed, the library populates the transfer with the results and passes
+ * it back to the user.
+ */
+struct libusb_transfer {
+ /** Handle of the device that this transfer will be submitted to */
+ libusb_device_handle *dev_handle;
+
+ /** A bitwise OR combination of \ref libusb_transfer_flags. */
+ uint8_t flags;
+
+ /** Address of the endpoint where this transfer will be sent. */
+ unsigned char endpoint;
+
+ /** Type of the endpoint from \ref libusb_transfer_type */
+ unsigned char type;
+
+ /** Timeout for this transfer in milliseconds. A value of 0 indicates no
+ * timeout. */
+ unsigned int timeout;
+
+ /** The status of the transfer. Read-only, and only for use within
+ * transfer callback function.
+ *
+ * If this is an isochronous transfer, this field may read COMPLETED even
+ * if there were errors in the frames. Use the
+ * \ref libusb_iso_packet_descriptor::status "status" field in each packet
+ * to determine if errors occurred. */
+ enum libusb_transfer_status status;
+
+ /** Length of the data buffer. Must be non-negative. */
+ int length;
+
+ /** Actual length of data that was transferred. Read-only, and only for
+ * use within transfer callback function. Not valid for isochronous
+ * endpoint transfers. */
+ int actual_length;
+
+ /** Callback function. This will be invoked when the transfer completes,
+ * fails, or is cancelled. */
+ libusb_transfer_cb_fn callback;
+
+ /** User context data to pass to the callback function. */
+ void *user_data;
+
+ /** Data buffer */
+ unsigned char *buffer;
+
+ /** Number of isochronous packets. Only used for I/O with isochronous
+ * endpoints. Must be non-negative. */
+ int num_iso_packets;
+
+ /** Isochronous packet descriptors, for isochronous transfers only. */
+ struct libusb_iso_packet_descriptor iso_packet_desc[ZERO_SIZED_ARRAY];
+};
+
+/** \ingroup libusb_misc
+ * Capabilities supported by an instance of libusb on the current running
+ * platform. Test if the loaded library supports a given capability by calling
+ * \ref libusb_has_capability().
+ */
+enum libusb_capability {
+ /** The libusb_has_capability() API is available. */
+ LIBUSB_CAP_HAS_CAPABILITY = 0x0000,
+ /** Hotplug support is available on this platform. */
+ LIBUSB_CAP_HAS_HOTPLUG = 0x0001,
+ /** The library can access HID devices without requiring user intervention.
+ * Note that before being able to actually access an HID device, you may
+ * still have to call additional libusb functions such as
+ * \ref libusb_detach_kernel_driver(). */
+ LIBUSB_CAP_HAS_HID_ACCESS = 0x0100,
+ /** The library supports detaching of the default USB driver, using
+ * \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */
+ LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101
+};
+
+/** \ingroup libusb_lib
+ * Log message levels.
+ * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default)
+ * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr
+ * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr
+ * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr
+ * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr
+ */
+enum libusb_log_level {
+ LIBUSB_LOG_LEVEL_NONE = 0,
+ LIBUSB_LOG_LEVEL_ERROR = 1,
+ LIBUSB_LOG_LEVEL_WARNING = 2,
+ LIBUSB_LOG_LEVEL_INFO = 3,
+ LIBUSB_LOG_LEVEL_DEBUG = 4,
+};
+
+/** \ingroup libusb_lib
+ * Log callback mode.
+ * \see libusb_set_log_cb()
+ */
+enum libusb_log_cb_mode {
+
+ /** Callback function handling all log mesages. */
+ LIBUSB_LOG_CB_GLOBAL = 1 << 0,
+
+ /** Callback function handling context related log mesages. */
+ LIBUSB_LOG_CB_CONTEXT = 1 << 1
+};
+
+/** \ingroup libusb_lib
+ * Callback function for handling log messages.
+ * \param ctx the context which is related to the log message, or NULL if it
+ * is a global log message
+ * \param level the log level, see \ref libusb_log_level for a description
+ * \param str the log message
+ * \see libusb_set_log_cb()
+ */
+typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx,
+ enum libusb_log_level level, const char *str);
+
+int LIBUSB_CALL libusb_init(libusb_context **ctx);
+void LIBUSB_CALL libusb_exit(libusb_context *ctx);
+LIBUSB_DEPRECATED_FOR(libusb_set_option)
+void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level);
+void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode);
+const struct libusb_version * LIBUSB_CALL libusb_get_version(void);
+int LIBUSB_CALL libusb_has_capability(uint32_t capability);
+const char * LIBUSB_CALL libusb_error_name(int errcode);
+int LIBUSB_CALL libusb_setlocale(const char *locale);
+const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode);
+
+ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx,
+ libusb_device ***list);
+void LIBUSB_CALL libusb_free_device_list(libusb_device **list,
+ int unref_devices);
+libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev);
+void LIBUSB_CALL libusb_unref_device(libusb_device *dev);
+
+int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev,
+ int *config);
+int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev,
+ struct libusb_device_descriptor *desc);
+int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev,
+ struct libusb_config_descriptor **config);
+int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev,
+ uint8_t config_index, struct libusb_config_descriptor **config);
+int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev,
+ uint8_t bConfigurationValue, struct libusb_config_descriptor **config);
+void LIBUSB_CALL libusb_free_config_descriptor(
+ struct libusb_config_descriptor *config);
+int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor(
+ struct libusb_context *ctx,
+ const struct libusb_endpoint_descriptor *endpoint,
+ struct libusb_ss_endpoint_companion_descriptor **ep_comp);
+void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor(
+ struct libusb_ss_endpoint_companion_descriptor *ep_comp);
+int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
+ struct libusb_bos_descriptor **bos);
+void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos);
+int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor(
+ struct libusb_context *ctx,
+ struct libusb_bos_dev_capability_descriptor *dev_cap,
+ struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension);
+void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor(
+ struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension);
+int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor(
+ struct libusb_context *ctx,
+ struct libusb_bos_dev_capability_descriptor *dev_cap,
+ struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap);
+void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor(
+ struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap);
+int LIBUSB_CALL libusb_get_container_id_descriptor(struct libusb_context *ctx,
+ struct libusb_bos_dev_capability_descriptor *dev_cap,
+ struct libusb_container_id_descriptor **container_id);
+void LIBUSB_CALL libusb_free_container_id_descriptor(
+ struct libusb_container_id_descriptor *container_id);
+uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev);
+uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev);
+int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t* port_numbers, int port_numbers_len);
+LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers)
+int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t* path, uint8_t path_length);
+libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev);
+uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev);
+int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev);
+int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev,
+ unsigned char endpoint);
+int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev,
+ unsigned char endpoint);
+
+int LIBUSB_CALL libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle);
+int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **dev_handle);
+void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);
+libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle);
+
+int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev_handle,
+ int configuration);
+int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev_handle,
+ int interface_number);
+int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev_handle,
+ int interface_number);
+
+libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
+ libusb_context *ctx, uint16_t vendor_id, uint16_t product_id);
+
+int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev_handle,
+ int interface_number, int alternate_setting);
+int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev_handle,
+ unsigned char endpoint);
+int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev_handle);
+
+int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev_handle,
+ uint32_t num_streams, unsigned char *endpoints, int num_endpoints);
+int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev_handle,
+ unsigned char *endpoints, int num_endpoints);
+
+unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle,
+ size_t length);
+int LIBUSB_CALL libusb_dev_mem_free(libusb_device_handle *dev_handle,
+ unsigned char *buffer, size_t length);
+
+int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev_handle,
+ int interface_number);
+int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
+ int interface_number);
+int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev_handle,
+ int interface_number);
+int LIBUSB_CALL libusb_set_auto_detach_kernel_driver(
+ libusb_device_handle *dev_handle, int enable);
+
+/* async I/O */
+
+/** \ingroup libusb_asyncio
+ * Get the data section of a control transfer. This convenience function is here
+ * to remind you that the data does not start until 8 bytes into the actual
+ * buffer, as the setup packet comes first.
+ *
+ * Calling this function only makes sense from a transfer callback function,
+ * or situations where you have already allocated a suitably sized buffer at
+ * transfer->buffer.
+ *
+ * \param transfer a transfer
+ * \returns pointer to the first byte of the data section
+ */
+static inline unsigned char *libusb_control_transfer_get_data(
+ struct libusb_transfer *transfer)
+{
+ return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
+}
+
+/** \ingroup libusb_asyncio
+ * Get the control setup packet of a control transfer. This convenience
+ * function is here to remind you that the control setup occupies the first
+ * 8 bytes of the transfer data buffer.
+ *
+ * Calling this function only makes sense from a transfer callback function,
+ * or situations where you have already allocated a suitably sized buffer at
+ * transfer->buffer.
+ *
+ * \param transfer a transfer
+ * \returns a casted pointer to the start of the transfer data buffer
+ */
+static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
+ struct libusb_transfer *transfer)
+{
+ return (struct libusb_control_setup *)(void *) transfer->buffer;
+}
+
+/** \ingroup libusb_asyncio
+ * Helper function to populate the setup packet (first 8 bytes of the data
+ * buffer) for a control transfer. The wIndex, wValue and wLength values should
+ * be given in host-endian byte order.
+ *
+ * \param buffer buffer to output the setup packet into
+ * This pointer must be aligned to at least 2 bytes boundary.
+ * \param bmRequestType see the
+ * \ref libusb_control_setup::bmRequestType "bmRequestType" field of
+ * \ref libusb_control_setup
+ * \param bRequest see the
+ * \ref libusb_control_setup::bRequest "bRequest" field of
+ * \ref libusb_control_setup
+ * \param wValue see the
+ * \ref libusb_control_setup::wValue "wValue" field of
+ * \ref libusb_control_setup
+ * \param wIndex see the
+ * \ref libusb_control_setup::wIndex "wIndex" field of
+ * \ref libusb_control_setup
+ * \param wLength see the
+ * \ref libusb_control_setup::wLength "wLength" field of
+ * \ref libusb_control_setup
+ */
+static inline void libusb_fill_control_setup(unsigned char *buffer,
+ uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
+ uint16_t wLength)
+{
+ struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer;
+ setup->bmRequestType = bmRequestType;
+ setup->bRequest = bRequest;
+ setup->wValue = libusb_cpu_to_le16(wValue);
+ setup->wIndex = libusb_cpu_to_le16(wIndex);
+ setup->wLength = libusb_cpu_to_le16(wLength);
+}
+
+struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets);
+int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer);
+int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer);
+void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer);
+void LIBUSB_CALL libusb_transfer_set_stream_id(
+ struct libusb_transfer *transfer, uint32_t stream_id);
+uint32_t LIBUSB_CALL libusb_transfer_get_stream_id(
+ struct libusb_transfer *transfer);
+
+/** \ingroup libusb_asyncio
+ * Helper function to populate the required \ref libusb_transfer fields
+ * for a control transfer.
+ *
+ * If you pass a transfer buffer to this function, the first 8 bytes will
+ * be interpreted as a control setup packet, and the wLength field will be
+ * used to automatically populate the \ref libusb_transfer::length "length"
+ * field of the transfer. Therefore the recommended approach is:
+ * -# Allocate a suitably sized data buffer (including space for control setup)
+ * -# Call libusb_fill_control_setup()
+ * -# If this is a host-to-device transfer with a data stage, put the data
+ * in place after the setup packet
+ * -# Call this function
+ * -# Call libusb_submit_transfer()
+ *
+ * It is also legal to pass a NULL buffer to this function, in which case this
+ * function will not attempt to populate the length field. Remember that you
+ * must then populate the buffer and length fields later.
+ *
+ * \param transfer the transfer to populate
+ * \param dev_handle handle of the device that will handle the transfer
+ * \param buffer data buffer. If provided, this function will interpret the
+ * first 8 bytes as a setup packet and infer the transfer length from that.
+ * This pointer must be aligned to at least 2 bytes boundary.
+ * \param callback callback function to be invoked on transfer completion
+ * \param user_data user data to pass to callback function
+ * \param timeout timeout for the transfer in milliseconds
+ */
+static inline void libusb_fill_control_transfer(
+ struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
+ unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data,
+ unsigned int timeout)
+{
+ struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer;
+ transfer->dev_handle = dev_handle;
+ transfer->endpoint = 0;
+ transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL;
+ transfer->timeout = timeout;
+ transfer->buffer = buffer;
+ if (setup)
+ transfer->length = (int) (LIBUSB_CONTROL_SETUP_SIZE
+ + libusb_le16_to_cpu(setup->wLength));
+ transfer->user_data = user_data;
+ transfer->callback = callback;
+}
+
+/** \ingroup libusb_asyncio
+ * Helper function to populate the required \ref libusb_transfer fields
+ * for a bulk transfer.
+ *
+ * \param transfer the transfer to populate
+ * \param dev_handle handle of the device that will handle the transfer
+ * \param endpoint address of the endpoint where this transfer will be sent
+ * \param buffer data buffer
+ * \param length length of data buffer
+ * \param callback callback function to be invoked on transfer completion
+ * \param user_data user data to pass to callback function
+ * \param timeout timeout for the transfer in milliseconds
+ */
+static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
+ libusb_device_handle *dev_handle, unsigned char endpoint,
+ unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
+ void *user_data, unsigned int timeout)
+{
+ transfer->dev_handle = dev_handle;
+ transfer->endpoint = endpoint;
+ transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
+ transfer->timeout = timeout;
+ transfer->buffer = buffer;
+ transfer->length = length;
+ transfer->user_data = user_data;
+ transfer->callback = callback;
+}
+
+/** \ingroup libusb_asyncio
+ * Helper function to populate the required \ref libusb_transfer fields
+ * for a bulk transfer using bulk streams.
+ *
+ * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
+ *
+ * \param transfer the transfer to populate
+ * \param dev_handle handle of the device that will handle the transfer
+ * \param endpoint address of the endpoint where this transfer will be sent
+ * \param stream_id bulk stream id for this transfer
+ * \param buffer data buffer
+ * \param length length of data buffer
+ * \param callback callback function to be invoked on transfer completion
+ * \param user_data user data to pass to callback function
+ * \param timeout timeout for the transfer in milliseconds
+ */
+static inline void libusb_fill_bulk_stream_transfer(
+ struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
+ unsigned char endpoint, uint32_t stream_id,
+ unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
+ void *user_data, unsigned int timeout)
+{
+ libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer,
+ length, callback, user_data, timeout);
+ transfer->type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
+ libusb_transfer_set_stream_id(transfer, stream_id);
+}
+
+/** \ingroup libusb_asyncio
+ * Helper function to populate the required \ref libusb_transfer fields
+ * for an interrupt transfer.
+ *
+ * \param transfer the transfer to populate
+ * \param dev_handle handle of the device that will handle the transfer
+ * \param endpoint address of the endpoint where this transfer will be sent
+ * \param buffer data buffer
+ * \param length length of data buffer
+ * \param callback callback function to be invoked on transfer completion
+ * \param user_data user data to pass to callback function
+ * \param timeout timeout for the transfer in milliseconds
+ */
+static inline void libusb_fill_interrupt_transfer(
+ struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
+ unsigned char endpoint, unsigned char *buffer, int length,
+ libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
+{
+ transfer->dev_handle = dev_handle;
+ transfer->endpoint = endpoint;
+ transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
+ transfer->timeout = timeout;
+ transfer->buffer = buffer;
+ transfer->length = length;
+ transfer->user_data = user_data;
+ transfer->callback = callback;
+}
+
+/** \ingroup libusb_asyncio
+ * Helper function to populate the required \ref libusb_transfer fields
+ * for an isochronous transfer.
+ *
+ * \param transfer the transfer to populate
+ * \param dev_handle handle of the device that will handle the transfer
+ * \param endpoint address of the endpoint where this transfer will be sent
+ * \param buffer data buffer
+ * \param length length of data buffer
+ * \param num_iso_packets the number of isochronous packets
+ * \param callback callback function to be invoked on transfer completion
+ * \param user_data user data to pass to callback function
+ * \param timeout timeout for the transfer in milliseconds
+ */
+static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
+ libusb_device_handle *dev_handle, unsigned char endpoint,
+ unsigned char *buffer, int length, int num_iso_packets,
+ libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
+{
+ transfer->dev_handle = dev_handle;
+ transfer->endpoint = endpoint;
+ transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
+ transfer->timeout = timeout;
+ transfer->buffer = buffer;
+ transfer->length = length;
+ transfer->num_iso_packets = num_iso_packets;
+ transfer->user_data = user_data;
+ transfer->callback = callback;
+}
+
+/** \ingroup libusb_asyncio
+ * Convenience function to set the length of all packets in an isochronous
+ * transfer, based on the num_iso_packets field in the transfer structure.
+ *
+ * \param transfer a transfer
+ * \param length the length to set in each isochronous packet descriptor
+ * \see libusb_get_max_packet_size()
+ */
+static inline void libusb_set_iso_packet_lengths(
+ struct libusb_transfer *transfer, unsigned int length)
+{
+ int i;
+ for (i = 0; i < transfer->num_iso_packets; i++)
+ transfer->iso_packet_desc[i].length = length;
+}
+
+/** \ingroup libusb_asyncio
+ * Convenience function to locate the position of an isochronous packet
+ * within the buffer of an isochronous transfer.
+ *
+ * This is a thorough function which loops through all preceding packets,
+ * accumulating their lengths to find the position of the specified packet.
+ * Typically you will assign equal lengths to each packet in the transfer,
+ * and hence the above method is sub-optimal. You may wish to use
+ * libusb_get_iso_packet_buffer_simple() instead.
+ *
+ * \param transfer a transfer
+ * \param packet the packet to return the address of
+ * \returns the base address of the packet buffer inside the transfer buffer,
+ * or NULL if the packet does not exist.
+ * \see libusb_get_iso_packet_buffer_simple()
+ */
+static inline unsigned char *libusb_get_iso_packet_buffer(
+ struct libusb_transfer *transfer, unsigned int packet)
+{
+ int i;
+ size_t offset = 0;
+ int _packet;
+
+ /* oops..slight bug in the API. packet is an unsigned int, but we use
+ * signed integers almost everywhere else. range-check and convert to
+ * signed to avoid compiler warnings. FIXME for libusb-2. */
+ if (packet > INT_MAX)
+ return NULL;
+ _packet = (int) packet;
+
+ if (_packet >= transfer->num_iso_packets)
+ return NULL;
+
+ for (i = 0; i < _packet; i++)
+ offset += transfer->iso_packet_desc[i].length;
+
+ return transfer->buffer + offset;
+}
+
+/** \ingroup libusb_asyncio
+ * Convenience function to locate the position of an isochronous packet
+ * within the buffer of an isochronous transfer, for transfers where each
+ * packet is of identical size.
+ *
+ * This function relies on the assumption that every packet within the transfer
+ * is of identical size to the first packet. Calculating the location of
+ * the packet buffer is then just a simple calculation:
+ * <tt>buffer + (packet_size * packet)</tt>
+ *
+ * Do not use this function on transfers other than those that have identical
+ * packet lengths for each packet.
+ *
+ * \param transfer a transfer
+ * \param packet the packet to return the address of
+ * \returns the base address of the packet buffer inside the transfer buffer,
+ * or NULL if the packet does not exist.
+ * \see libusb_get_iso_packet_buffer()
+ */
+static inline unsigned char *libusb_get_iso_packet_buffer_simple(
+ struct libusb_transfer *transfer, unsigned int packet)
+{
+ int _packet;
+
+ /* oops..slight bug in the API. packet is an unsigned int, but we use
+ * signed integers almost everywhere else. range-check and convert to
+ * signed to avoid compiler warnings. FIXME for libusb-2. */
+ if (packet > INT_MAX)
+ return NULL;
+ _packet = (int) packet;
+
+ if (_packet >= transfer->num_iso_packets)
+ return NULL;
+
+ return transfer->buffer + ((int) transfer->iso_packet_desc[0].length * _packet);
+}
+
+/* sync I/O */
+
+int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle,
+ uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
+ unsigned char *data, uint16_t wLength, unsigned int timeout);
+
+int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle,
+ unsigned char endpoint, unsigned char *data, int length,
+ int *actual_length, unsigned int timeout);
+
+int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle,
+ unsigned char endpoint, unsigned char *data, int length,
+ int *actual_length, unsigned int timeout);
+
+/** \ingroup libusb_desc
+ * Retrieve a descriptor from the default control pipe.
+ * This is a convenience function which formulates the appropriate control
+ * message to retrieve the descriptor.
+ *
+ * \param dev_handle a device handle
+ * \param desc_type the descriptor type, see \ref libusb_descriptor_type
+ * \param desc_index the index of the descriptor to retrieve
+ * \param data output buffer for descriptor
+ * \param length size of data buffer
+ * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
+ */
+static inline int libusb_get_descriptor(libusb_device_handle *dev_handle,
+ uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length)
+{
+ return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
+ LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index),
+ 0, data, (uint16_t) length, 1000);
+}
+
+/** \ingroup libusb_desc
+ * Retrieve a descriptor from a device.
+ * This is a convenience function which formulates the appropriate control
+ * message to retrieve the descriptor. The string returned is Unicode, as
+ * detailed in the USB specifications.
+ *
+ * \param dev_handle a device handle
+ * \param desc_index the index of the descriptor to retrieve
+ * \param langid the language ID for the string descriptor
+ * \param data output buffer for descriptor
+ * \param length size of data buffer
+ * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
+ * \see libusb_get_string_descriptor_ascii()
+ */
+static inline int libusb_get_string_descriptor(libusb_device_handle *dev_handle,
+ uint8_t desc_index, uint16_t langid, unsigned char *data, int length)
+{
+ return libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
+ LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index),
+ langid, data, (uint16_t) length, 1000);
+}
+
+int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
+ uint8_t desc_index, unsigned char *data, int length);
+
+/* polling and timeouts */
+
+int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx);
+void LIBUSB_CALL libusb_lock_events(libusb_context *ctx);
+void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx);
+int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx);
+int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx);
+void LIBUSB_CALL libusb_interrupt_event_handler(libusb_context *ctx);
+void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx);
+void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx);
+int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv);
+
+int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx,
+ struct timeval *tv);
+int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx,
+ struct timeval *tv, int *completed);
+int LIBUSB_CALL libusb_handle_events(libusb_context *ctx);
+int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed);
+int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx,
+ struct timeval *tv);
+int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx);
+int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx,
+ struct timeval *tv);
+
+/** \ingroup libusb_poll
+ * File descriptor for polling
+ */
+struct libusb_pollfd {
+ /** Numeric file descriptor */
+ int fd;
+
+ /** Event flags to poll for from <poll.h>. POLLIN indicates that you
+ * should monitor this file descriptor for becoming ready to read from,
+ * and POLLOUT indicates that you should monitor this file descriptor for
+ * nonblocking write readiness. */
+ short events;
+};
+
+/** \ingroup libusb_poll
+ * Callback function, invoked when a new file descriptor should be added
+ * to the set of file descriptors monitored for events.
+ * \param fd the new file descriptor
+ * \param events events to monitor for, see \ref libusb_pollfd for a
+ * description
+ * \param user_data User data pointer specified in
+ * libusb_set_pollfd_notifiers() call
+ * \see libusb_set_pollfd_notifiers()
+ */
+typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events,
+ void *user_data);
+
+/** \ingroup libusb_poll
+ * Callback function, invoked when a file descriptor should be removed from
+ * the set of file descriptors being monitored for events. After returning
+ * from this callback, do not use that file descriptor again.
+ * \param fd the file descriptor to stop monitoring
+ * \param user_data User data pointer specified in
+ * libusb_set_pollfd_notifiers() call
+ * \see libusb_set_pollfd_notifiers()
+ */
+typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data);
+
+const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
+ libusb_context *ctx);
+void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds);
+void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
+ libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
+ void *user_data);
+
+/** \ingroup libusb_hotplug
+ * Callback handle.
+ *
+ * Callbacks handles are generated by libusb_hotplug_register_callback()
+ * and can be used to deregister callbacks. Callback handles are unique
+ * per libusb_context and it is safe to call libusb_hotplug_deregister_callback()
+ * on an already deregisted callback.
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ *
+ * For more information, see \ref libusb_hotplug.
+ */
+typedef int libusb_hotplug_callback_handle;
+
+/** \ingroup libusb_hotplug
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ *
+ * Flags for hotplug events */
+typedef enum {
+ /** Default value when not using any flags. */
+ LIBUSB_HOTPLUG_NO_FLAGS = 0U,
+
+ /** Arm the callback and fire it for all matching currently attached devices. */
+ LIBUSB_HOTPLUG_ENUMERATE = 1U << 0,
+} libusb_hotplug_flag;
+
+/** \ingroup libusb_hotplug
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ *
+ * Hotplug events */
+typedef enum {
+ /** A device has been plugged in and is ready to use */
+ LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01U,
+
+ /** A device has left and is no longer available.
+ * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device.
+ * It is safe to call libusb_get_device_descriptor on a device that has left */
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02U,
+} libusb_hotplug_event;
+
+/** \ingroup libusb_hotplug
+ * Wildcard matching for hotplug events */
+#define LIBUSB_HOTPLUG_MATCH_ANY -1
+
+/** \ingroup libusb_hotplug
+ * Hotplug callback function type. When requesting hotplug event notifications,
+ * you pass a pointer to a callback function of this type.
+ *
+ * This callback may be called by an internal event thread and as such it is
+ * recommended the callback do minimal processing before returning.
+ *
+ * libusb will call this function later, when a matching event had happened on
+ * a matching device. See \ref libusb_hotplug for more information.
+ *
+ * It is safe to call either libusb_hotplug_register_callback() or
+ * libusb_hotplug_deregister_callback() from within a callback function.
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ *
+ * \param ctx context of this notification
+ * \param device libusb_device this event occurred on
+ * \param event event that occurred
+ * \param user_data user data provided when this callback was registered
+ * \returns bool whether this callback is finished processing events.
+ * returning 1 will cause this callback to be deregistered
+ */
+typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx,
+ libusb_device *device,
+ libusb_hotplug_event event,
+ void *user_data);
+
+/** \ingroup libusb_hotplug
+ * Register a hotplug callback function
+ *
+ * Register a callback with the libusb_context. The callback will fire
+ * when a matching event occurs on a matching device. The callback is
+ * armed until either it is deregistered with libusb_hotplug_deregister_callback()
+ * or the supplied callback returns 1 to indicate it is finished processing events.
+ *
+ * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be
+ * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices
+ * already plugged into the machine. Note that libusb modifies its internal
+ * device list from a separate thread, while calling hotplug callbacks from
+ * libusb_handle_events(), so it is possible for a device to already be present
+ * on, or removed from, its internal device list, while the hotplug callbacks
+ * still need to be dispatched. This means that when using \ref
+ * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival
+ * of the same device, once from libusb_hotplug_register_callback() and once
+ * from libusb_handle_events(); and/or your callback may be called for the
+ * removal of a device for which an arrived call was never made.
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ *
+ * \param[in] ctx context to register this callback with
+ * \param[in] events bitwise or of events that will trigger this callback. See \ref
+ * libusb_hotplug_event
+ * \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag
+ * \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
+ * \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
+ * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY
+ * \param[in] cb_fn the function to be invoked on a matching event/device
+ * \param[in] user_data user data to pass to the callback function
+ * \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL)
+ * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure
+ */
+int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx,
+ libusb_hotplug_event events,
+ libusb_hotplug_flag flags,
+ int vendor_id, int product_id,
+ int dev_class,
+ libusb_hotplug_callback_fn cb_fn,
+ void *user_data,
+ libusb_hotplug_callback_handle *callback_handle);
+
+/** \ingroup libusb_hotplug
+ * Deregisters a hotplug callback.
+ *
+ * Deregister a callback from a libusb_context. This function is safe to call from within
+ * a hotplug callback.
+ *
+ * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102
+ *
+ * \param[in] ctx context this callback is registered with
+ * \param[in] callback_handle the handle of the callback to deregister
+ */
+void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx,
+ libusb_hotplug_callback_handle callback_handle);
+
+/** \ingroup libusb_lib
+ * Available option values for libusb_set_option().
+ */
+enum libusb_option {
+ /** Set the log message verbosity.
+ *
+ * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever
+ * printed. If you choose to increase the message verbosity level, ensure
+ * that your application does not close the stderr file descriptor.
+ *
+ * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative
+ * with its message logging and most of the time, will only log messages that
+ * explain error conditions and other oddities. This will help you debug
+ * your software.
+ *
+ * If the LIBUSB_DEBUG environment variable was set when libusb was
+ * initialized, this function does nothing: the message verbosity is fixed
+ * to the value in the environment variable.
+ *
+ * If libusb was compiled without any message logging, this function does
+ * nothing: you'll never get any messages.
+ *
+ * If libusb was compiled with verbose debug message logging, this function
+ * does nothing: you'll always get messages from all levels.
+ */
+ LIBUSB_OPTION_LOG_LEVEL,
+
+ /** Use the UsbDk backend for a specific context, if available.
+ *
+ * This option should be set immediately after calling libusb_init(), otherwise
+ * unspecified behavior may occur.
+ *
+ * Only valid on Windows.
+ */
+ LIBUSB_OPTION_USE_USBDK,
+};
+
+int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libusb1/libusbi.h b/libusb1/libusbi.h
new file mode 100644
index 0000000..0a677bd
--- /dev/null
+++ b/libusb1/libusbi.h
@@ -0,0 +1,1210 @@
+/*
+ * Internal header for libusb
+ * Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
+ * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
+ * Copyright © 2019 Nathan Hjelm <hjelmn@cs.umm.edu>
+ * Copyright © 2019 Google LLC. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LIBUSBI_H
+#define LIBUSBI_H
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <time.h>
+#include <stdarg.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_MISSING_H
+#include <missing.h>
+#endif
+
+#include "libusb.h"
+#include "version.h"
+
+/* Attribute to ensure that a structure member is aligned to a natural
+ * pointer alignment. Used for os_priv member. */
+#if defined(_MSC_VER)
+#if defined(_WIN64)
+#define PTR_ALIGNED __declspec(align(8))
+#else
+#define PTR_ALIGNED __declspec(align(4))
+#endif
+#elif defined(__GNUC__) && (__GNUC__ >= 3)
+#define PTR_ALIGNED __attribute__((aligned(sizeof(void *))))
+#else
+#define PTR_ALIGNED
+#endif
+
+/* Inside the libusb code, mark all public functions as follows:
+ * return_type API_EXPORTED function_name(params) { ... }
+ * But if the function returns a pointer, mark it as follows:
+ * DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... }
+ * In the libusb public header, mark all declarations as:
+ * return_type LIBUSB_CALL function_name(params);
+ */
+#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY
+
+/* Macro to decorate printf-like functions, in order to get
+ * compiler warnings about format string mistakes.
+ */
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+#define USBI_PRINTFLIKE(formatarg, firstvararg) \
+ __attribute__((__format__ (__printf__, formatarg, firstvararg)))
+#else
+#define USBI_PRINTFLIKE(formatarg, firstvararg)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEVICE_DESC_LENGTH 18
+
+#define USB_MAXENDPOINTS 32
+#define USB_MAXINTERFACES 32
+#define USB_MAXCONFIG 8
+
+/* Backend specific capabilities */
+#define USBI_CAP_HAS_HID_ACCESS 0x00010000
+#define USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER 0x00020000
+
+/* Maximum number of bytes in a log line */
+#define USBI_MAX_LOG_LEN 1024
+/* Terminator for log lines */
+#define USBI_LOG_LINE_END "\n"
+
+/* The following is used to silence warnings for unused variables */
+#define UNUSED(var) do { (void)(var); } while(0)
+
+#if !defined(ARRAYSIZE)
+#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
+#endif
+
+struct list_head {
+ struct list_head *prev, *next;
+};
+
+/* Get an entry from the list
+ * ptr - the address of this list_head element in "type"
+ * type - the data type that contains "member"
+ * member - the list_head element in "type"
+ */
+#define list_entry(ptr, 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
+ * pos - A structure pointer has a "member" element
+ * head - list head
+ * member - the list_head element in "pos"
+ * type - the type of the first parameter
+ */
+#define list_for_each_entry(pos, head, member, type) \
+ for (pos = list_entry((head)->next, type, member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, type, member))
+
+#define list_for_each_entry_safe(pos, n, head, member, type) \
+ for (pos = list_entry((head)->next, type, member), \
+ n = list_entry(pos->member.next, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, type, member))
+
+#define list_empty(entry) ((entry)->next == (entry))
+
+static inline void list_init(struct list_head *entry)
+{
+ entry->prev = entry->next = entry;
+}
+
+static inline void list_add(struct list_head *entry, struct list_head *head)
+{
+ entry->next = head->next;
+ entry->prev = head;
+
+ head->next->prev = entry;
+ head->next = entry;
+}
+
+static inline void list_add_tail(struct list_head *entry,
+ struct list_head *head)
+{
+ entry->next = head;
+ entry->prev = head->prev;
+
+ head->prev->next = entry;
+ head->prev = entry;
+}
+
+static inline void list_del(struct list_head *entry)
+{
+ entry->next->prev = entry->prev;
+ entry->prev->next = entry->next;
+ entry->next = entry->prev = NULL;
+}
+
+static inline void list_cut(struct list_head *list, struct list_head *head)
+{
+ if (list_empty(head))
+ return;
+
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = head->prev;
+ list->prev->next = list;
+
+ list_init(head);
+}
+
+static inline void *usbi_reallocf(void *ptr, size_t size)
+{
+ void *ret = realloc(ptr, size);
+ if (!ret)
+ free(ptr);
+ return ret;
+}
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *mptr = (ptr); \
+ (type *)( (char *)mptr - offsetof(type,member) );})
+
+#ifndef CLAMP
+#define CLAMP(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? (max) : (val)))
+#endif
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
+
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+#define TIMEVAL_TV_SEC_TYPE long
+#else
+#define TIMEVAL_TV_SEC_TYPE time_t
+#endif
+
+/* Some platforms don't have this define */
+#ifndef TIMESPEC_TO_TIMEVAL
+#define TIMESPEC_TO_TIMEVAL(tv, ts) \
+ do { \
+ (tv)->tv_sec = (TIMEVAL_TV_SEC_TYPE) (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+ } while (0)
+#endif
+
+#ifdef ENABLE_LOGGING
+
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+#define snprintf usbi_snprintf
+#define vsnprintf usbi_vsnprintf
+int usbi_snprintf(char *dst, size_t size, const char *format, ...);
+int usbi_vsnprintf(char *dst, size_t size, const char *format, va_list ap);
+#define LIBUSB_PRINTF_WIN32
+#endif /* defined(_MSC_VER) && (_MSC_VER < 1900) */
+
+void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
+ const char *function, const char *format, ...) USBI_PRINTFLIKE(4, 5);
+
+void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
+ const char *function, const char *format, va_list args) USBI_PRINTFLIKE(4, 0);
+
+#if !defined(_MSC_VER) || (_MSC_VER >= 1400)
+
+#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__)
+
+#define usbi_err(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
+#define usbi_warn(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
+#define usbi_info(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_INFO, __VA_ARGS__)
+#define usbi_dbg(...) _usbi_log(NULL, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__)
+
+#else /* !defined(_MSC_VER) || (_MSC_VER >= 1400) */
+
+#define LOG_BODY(ctxt, level) \
+{ \
+ va_list args; \
+ va_start(args, format); \
+ usbi_log_v(ctxt, level, "", format, args); \
+ va_end(args); \
+}
+
+static inline void usbi_err(struct libusb_context *ctx, const char *format, ...)
+ LOG_BODY(ctx, LIBUSB_LOG_LEVEL_ERROR)
+static inline void usbi_warn(struct libusb_context *ctx, const char *format, ...)
+ LOG_BODY(ctx, LIBUSB_LOG_LEVEL_WARNING)
+static inline void usbi_info(struct libusb_context *ctx, const char *format, ...)
+ LOG_BODY(ctx, LIBUSB_LOG_LEVEL_INFO)
+static inline void usbi_dbg(const char *format, ...)
+ LOG_BODY(NULL, LIBUSB_LOG_LEVEL_DEBUG)
+
+#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1400) */
+
+#else /* ENABLE_LOGGING */
+
+#define usbi_err(ctx, ...) do { (void)ctx; } while (0)
+#define usbi_warn(ctx, ...) do { (void)ctx; } while (0)
+#define usbi_info(ctx, ...) do { (void)ctx; } while (0)
+#define usbi_dbg(...) do {} while (0)
+
+#endif /* ENABLE_LOGGING */
+
+#define USBI_GET_CONTEXT(ctx) \
+ do { \
+ if (!(ctx)) \
+ (ctx) = usbi_default_context; \
+ } while(0)
+
+#define DEVICE_CTX(dev) ((dev)->ctx)
+#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))
+#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))
+#define ITRANSFER_CTX(transfer) \
+ (TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)))
+
+#define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN))
+#define IS_EPOUT(ep) (!IS_EPIN(ep))
+#define IS_XFERIN(xfer) (0 != ((xfer)->endpoint & LIBUSB_ENDPOINT_IN))
+#define IS_XFEROUT(xfer) (!IS_XFERIN(xfer))
+
+/* Internal abstraction for thread synchronization */
+#if defined(THREADS_POSIX)
+#include "os/threads_posix.h"
+#elif defined(OS_WINDOWS) || defined(OS_WINCE)
+#include "os/threads_windows.h"
+#endif
+
+extern struct libusb_context *usbi_default_context;
+
+/* Forward declaration for use in context (fully defined inside poll abstraction) */
+struct pollfd;
+
+struct libusb_context {
+#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
+ enum libusb_log_level debug;
+ int debug_fixed;
+ libusb_log_cb log_handler;
+#endif
+
+ /* internal event pipe, used for signalling occurrence of an internal event. */
+ int event_pipe[2];
+
+ struct list_head usb_devs;
+ usbi_mutex_t usb_devs_lock;
+
+ /* A list of open handles. Backends are free to traverse this if required.
+ */
+ struct list_head open_devs;
+ usbi_mutex_t open_devs_lock;
+
+ /* A list of registered hotplug callbacks */
+ struct list_head hotplug_cbs;
+ libusb_hotplug_callback_handle next_hotplug_cb_handle;
+ usbi_mutex_t hotplug_cbs_lock;
+
+ /* this is a list of in-flight transfer handles, sorted by timeout
+ * expiration. URBs to timeout the soonest are placed at the beginning of
+ * the list, URBs that will time out later are placed after, and urbs with
+ * infinite timeout are always placed at the very end. */
+ struct list_head flying_transfers;
+ /* Note paths taking both this and usbi_transfer->lock must always
+ * take this lock first */
+ usbi_mutex_t flying_transfers_lock;
+
+ /* user callbacks for pollfd changes */
+ libusb_pollfd_added_cb fd_added_cb;
+ libusb_pollfd_removed_cb fd_removed_cb;
+ void *fd_cb_user_data;
+
+ /* ensures that only one thread is handling events at any one time */
+ usbi_mutex_t events_lock;
+
+ /* used to see if there is an active thread doing event handling */
+ int event_handler_active;
+
+ /* A thread-local storage key to track which thread is performing event
+ * handling */
+ usbi_tls_key_t event_handling_key;
+
+ /* used to wait for event completion in threads other than the one that is
+ * event handling */
+ usbi_mutex_t event_waiters_lock;
+ usbi_cond_t event_waiters_cond;
+
+ /* A lock to protect internal context event data. */
+ usbi_mutex_t event_data_lock;
+
+ /* A bitmask of flags that are set to indicate specific events that need to
+ * be handled. Protected by event_data_lock. */
+ unsigned int event_flags;
+
+ /* 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. Protected by event_data_lock. */
+ struct list_head ipollfds;
+ /* list of pollfds that have been removed. keeps track of pollfd changes
+ * between the poll call and */
+ struct list_head removed_ipollfds;
+ struct pollfd *pollfds;
+ POLL_NFDS_TYPE pollfds_cnt;
+
+ /* 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
+ /* used for timeout handling, if supported by OS.
+ * this timerfd is maintained to trigger on the next pending timeout */
+ int timerfd;
+#endif
+
+ struct list_head list;
+
+ PTR_ALIGNED unsigned char os_priv[ZERO_SIZED_ARRAY];
+};
+
+enum usbi_event_flags {
+ /* The list of pollfds has been modified */
+ USBI_EVENT_POLLFDS_MODIFIED = 1U << 0,
+
+ /* The user has interrupted the event handler */
+ USBI_EVENT_USER_INTERRUPT = 1U << 1,
+
+ /* A hotplug callback deregistration is pending */
+ USBI_EVENT_HOTPLUG_CB_DEREGISTERED = 1U << 2,
+};
+
+/* Macros for managing event handling state */
+#define usbi_handling_events(ctx) \
+ (usbi_tls_key_get((ctx)->event_handling_key) != NULL)
+
+#define usbi_start_event_handling(ctx) \
+ usbi_tls_key_set((ctx)->event_handling_key, ctx)
+
+#define usbi_end_event_handling(ctx) \
+ usbi_tls_key_set((ctx)->event_handling_key, NULL)
+
+/* Update the following macro if new event sources are added */
+#define usbi_pending_events(ctx) \
+ ((ctx)->event_flags || (ctx)->device_close \
+ || !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers))
+
+#ifdef USBI_TIMERFD_AVAILABLE
+#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0)
+#else
+#define usbi_using_timerfd(ctx) (0)
+#endif
+
+struct libusb_device {
+ /* lock protects refcnt, everything else is finalized at initialization
+ * time */
+ usbi_mutex_t lock;
+ int refcnt;
+
+ struct libusb_context *ctx;
+
+ uint8_t bus_number;
+ uint8_t port_number;
+ struct libusb_device* parent_dev;
+ uint8_t device_address;
+ uint8_t num_configurations;
+ enum libusb_speed speed;
+
+ struct list_head list;
+ unsigned long session_data;
+
+ struct libusb_device_descriptor device_descriptor;
+ int attached;
+
+ PTR_ALIGNED unsigned char os_priv[ZERO_SIZED_ARRAY];
+};
+
+struct libusb_device_handle {
+ /* lock protects claimed_interfaces */
+ usbi_mutex_t lock;
+ unsigned long claimed_interfaces;
+
+ struct list_head list;
+ struct libusb_device *dev;
+ int auto_detach_kernel_driver;
+
+ PTR_ALIGNED unsigned char os_priv[ZERO_SIZED_ARRAY];
+};
+
+enum {
+ USBI_CLOCK_MONOTONIC,
+ USBI_CLOCK_REALTIME
+};
+
+/* in-memory transfer layout:
+ *
+ * 1. struct usbi_transfer
+ * 2. struct libusb_transfer (which includes iso packets) [variable size]
+ * 3. os private data [variable size]
+ *
+ * from a libusb_transfer, you can get the usbi_transfer by rewinding the
+ * appropriate number of bytes.
+ * the usbi_transfer includes the number of allocated packets, so you can
+ * determine the size of the transfer and hence the start and length of the
+ * OS-private data.
+ */
+
+struct usbi_transfer {
+ int num_iso_packets;
+ struct list_head list;
+ struct list_head completed_list;
+ struct timeval timeout;
+ int transferred;
+ uint32_t stream_id;
+ uint8_t state_flags; /* Protected by usbi_transfer->lock */
+ uint8_t timeout_flags; /* Protected by the flying_stransfers_lock */
+
+ /* this lock is held during libusb_submit_transfer() and
+ * libusb_cancel_transfer() (allowing the OS backend to prevent duplicate
+ * cancellation, submission-during-cancellation, etc). the OS backend
+ * should also take this lock in the handle_events path, to prevent the user
+ * cancelling the transfer from another thread while you are processing
+ * its completion (presumably there would be races within your OS backend
+ * if this were possible).
+ * Note paths taking both this and the flying_transfers_lock must
+ * always take the flying_transfers_lock first */
+ usbi_mutex_t lock;
+};
+
+enum usbi_transfer_state_flags {
+ /* Transfer successfully submitted by backend */
+ USBI_TRANSFER_IN_FLIGHT = 1U << 0,
+
+ /* Cancellation was requested via libusb_cancel_transfer() */
+ USBI_TRANSFER_CANCELLING = 1U << 1,
+
+ /* Operation on the transfer failed because the device disappeared */
+ USBI_TRANSFER_DEVICE_DISAPPEARED = 1U << 2,
+};
+
+enum usbi_transfer_timeout_flags {
+ /* Set by backend submit_transfer() if the OS handles timeout */
+ USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1U << 0,
+
+ /* The transfer timeout has been handled */
+ USBI_TRANSFER_TIMEOUT_HANDLED = 1U << 1,
+
+ /* The transfer timeout was successfully processed */
+ USBI_TRANSFER_TIMED_OUT = 1U << 2,
+};
+
+#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
+ ((struct libusb_transfer *)(((unsigned char *)(transfer)) \
+ + sizeof(struct usbi_transfer)))
+#define LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer) \
+ ((struct usbi_transfer *)(((unsigned char *)(transfer)) \
+ - sizeof(struct usbi_transfer)))
+
+static inline void *usbi_transfer_get_os_priv(struct usbi_transfer *transfer)
+{
+ assert(transfer->num_iso_packets >= 0);
+ return ((unsigned char *)transfer) + sizeof(struct usbi_transfer)
+ + sizeof(struct libusb_transfer)
+ + ((size_t)transfer->num_iso_packets
+ * sizeof(struct libusb_iso_packet_descriptor));
+}
+
+/* bus structures */
+
+/* All standard descriptors have these 2 fields in common */
+struct usb_descriptor_header {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+};
+
+/* shared data and functions */
+
+int usbi_io_init(struct libusb_context *ctx);
+void usbi_io_exit(struct libusb_context *ctx);
+
+struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
+ unsigned long session_id);
+struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
+ unsigned long session_id);
+int usbi_sanitize_device(struct libusb_device *dev);
+void usbi_handle_disconnect(struct libusb_device_handle *dev_handle);
+
+int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
+ enum libusb_transfer_status status);
+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,
+ void *dest, int host_endian);
+int usbi_device_cache_descriptor(libusb_device *dev);
+int usbi_get_config_index_by_value(struct libusb_device *dev,
+ uint8_t bConfigurationValue, int *idx);
+
+void usbi_connect_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) */
+#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) ||\
+ defined(OS_HAIKU) || defined(OS_SUNOS)
+#include <unistd.h>
+#include "os/poll_posix.h"
+#elif defined(OS_WINDOWS) || defined(OS_WINCE)
+#include "os/poll_windows.h"
+#endif
+
+struct usbi_pollfd {
+ /* must come first */
+ struct libusb_pollfd pollfd;
+
+ struct list_head list;
+};
+
+int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
+void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
+
+/* device discovery */
+
+/* we traverse usbfs without knowing how many devices we are going to find.
+ * so we create this discovered_devs model which is similar to a linked-list
+ * which grows when required. it can be freed once discovery has completed,
+ * eliminating the need for a list node in the libusb_device structure
+ * itself. */
+struct discovered_devs {
+ size_t len;
+ size_t capacity;
+ struct libusb_device *devices[ZERO_SIZED_ARRAY];
+};
+
+struct discovered_devs *discovered_devs_append(
+ struct discovered_devs *discdevs, struct libusb_device *dev);
+
+/* OS abstraction */
+
+/* This is the interface that OS backends need to implement.
+ * All fields are mandatory, except ones explicitly noted as optional. */
+struct usbi_os_backend {
+ /* A human-readable name for your backend, e.g. "Linux usbfs" */
+ const char *name;
+
+ /* Binary mask for backend specific capabilities */
+ uint32_t caps;
+
+ /* Perform initialization of your backend. You might use this function
+ * to determine specific capabilities of the system, allocate required
+ * data structures for later, etc.
+ *
+ * This function is called when a libusb user initializes the library
+ * prior to use.
+ *
+ * Return 0 on success, or a LIBUSB_ERROR code on failure.
+ */
+ int (*init)(struct libusb_context *ctx);
+
+ /* Deinitialization. Optional. This function should destroy anything
+ * that was set up by init.
+ *
+ * This function is called when the user deinitializes the library.
+ */
+ void (*exit)(struct libusb_context *ctx);
+
+ /* Set a backend-specific option. Optional.
+ *
+ * This function is called when the user calls libusb_set_option() and
+ * the option is not handled by the core library.
+ *
+ * Return 0 on success, or a LIBUSB_ERROR code on failure.
+ */
+ int (*set_option)(struct libusb_context *ctx, enum libusb_option option,
+ va_list args);
+
+ /* Enumerate all the USB devices on the system, returning them in a list
+ * of discovered devices.
+ *
+ * Your implementation should enumerate all devices on the system,
+ * regardless of whether they have been seen before or not.
+ *
+ * When you have found a device, compute a session ID for it. The session
+ * ID should uniquely represent that particular device for that particular
+ * connection session since boot (i.e. if you disconnect and reconnect a
+ * device immediately after, it should be assigned a different session ID).
+ * If your OS cannot provide a unique session ID as described above,
+ * presenting a session ID of (bus_number << 8 | device_address) should
+ * be sufficient. Bus numbers and device addresses wrap and get reused,
+ * but that is an unlikely case.
+ *
+ * After computing a session ID for a device, call
+ * usbi_get_device_by_session_id(). This function checks if libusb already
+ * knows about the device, and if so, it provides you with a reference
+ * to a libusb_device structure for it.
+ *
+ * If usbi_get_device_by_session_id() returns NULL, it is time to allocate
+ * a new device structure for the device. Call usbi_alloc_device() to
+ * obtain a new libusb_device structure with reference count 1. Populate
+ * the bus_number and device_address attributes of the new device, and
+ * perform any other internal backend initialization you need to do. At
+ * this point, you should be ready to provide device descriptors and so
+ * on through the get_*_descriptor functions. Finally, call
+ * usbi_sanitize_device() to perform some final sanity checks on the
+ * device. Assuming all of the above succeeded, we can now continue.
+ * If any of the above failed, remember to unreference the device that
+ * was returned by usbi_alloc_device().
+ *
+ * At this stage we have a populated libusb_device structure (either one
+ * that was found earlier, or one that we have just allocated and
+ * populated). This can now be added to the discovered devices list
+ * using discovered_devs_append(). Note that discovered_devs_append()
+ * may reallocate the list, returning a new location for it, and also
+ * note that reallocation can fail. Your backend should handle these
+ * error conditions appropriately.
+ *
+ * This function should not generate any bus I/O and should not block.
+ * If I/O is required (e.g. reading the active configuration value), it is
+ * OK to ignore these suggestions :)
+ *
+ * This function is executed when the user wishes to retrieve a list
+ * of USB devices connected to the system.
+ *
+ * If the backend has hotplug support, this function is not used!
+ *
+ * Return 0 on success, or a LIBUSB_ERROR code on failure.
+ */
+ int (*get_device_list)(struct libusb_context *ctx,
+ struct discovered_devs **discdevs);
+
+ /* Apps which were written before hotplug support, may listen for
+ * hotplug events on their own and call libusb_get_device_list on
+ * device addition. In this case libusb_get_device_list will likely
+ * return a list without the new device in there, as the hotplug
+ * event thread will still be busy enumerating the device, which may
+ * take a while, or may not even have seen the event yet.
+ *
+ * To avoid this libusb_get_device_list will call this optional
+ * function for backends with hotplug support before copying
+ * ctx->usb_devs to the user. In this function the backend should
+ * ensure any pending hotplug events are fully processed before
+ * returning.
+ *
+ * Optional, should be implemented by backends with hotplug support.
+ */
+ void (*hotplug_poll)(void);
+
+ /* Wrap a platform-specific device handle for I/O and other USB
+ * operations. The device handle is preallocated for you.
+ *
+ * Your backend should allocate any internal resources required for I/O
+ * and other operations so that those operations can happen (hopefully)
+ * without hiccup. This is also a good place to inform libusb that it
+ * should monitor certain file descriptors related to this device -
+ * see the usbi_add_pollfd() function.
+ *
+ * Your backend should also initialize the device structure
+ * (dev_handle->dev), which is NULL at the beginning of the call.
+ *
+ * This function should not generate any bus I/O and should not block.
+ *
+ * This function is called when the user attempts to wrap an existing
+ * platform-specific device handle for a device.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_ACCESS if the user has insufficient permissions
+ * - another LIBUSB_ERROR code on other failure
+ *
+ * Do not worry about freeing the handle on failed open, the upper layers
+ * do this for you.
+ */
+ int (*wrap_sys_device)(struct libusb_context *ctx,
+ struct libusb_device_handle *dev_handle, intptr_t sys_dev);
+
+ /* Open a device for I/O and other USB operations. The device handle
+ * is preallocated for you, you can retrieve the device in question
+ * through handle->dev.
+ *
+ * Your backend should allocate any internal resources required for I/O
+ * and other operations so that those operations can happen (hopefully)
+ * without hiccup. This is also a good place to inform libusb that it
+ * should monitor certain file descriptors related to this device -
+ * see the usbi_add_pollfd() function.
+ *
+ * This function should not generate any bus I/O and should not block.
+ *
+ * This function is called when the user attempts to obtain a device
+ * handle for a device.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_ACCESS if the user has insufficient permissions
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since
+ * discovery
+ * - another LIBUSB_ERROR code on other failure
+ *
+ * Do not worry about freeing the handle on failed open, the upper layers
+ * do this for you.
+ */
+ int (*open)(struct libusb_device_handle *dev_handle);
+
+ /* Close a device such that the handle cannot be used again. Your backend
+ * should destroy any resources that were allocated in the open path.
+ * This may also be a good place to call usbi_remove_pollfd() to inform
+ * libusb of any file descriptors associated with this device that should
+ * no longer be monitored.
+ *
+ * This function is called when the user closes a device handle.
+ */
+ void (*close)(struct libusb_device_handle *dev_handle);
+
+ /* Retrieve the device descriptor from a device.
+ *
+ * The descriptor should be retrieved from memory, NOT via bus I/O to the
+ * device. This means that you may have to cache it in a private structure
+ * during get_device_list enumeration. Alternatively, you may be able
+ * to retrieve it from a kernel interface (some Linux setups can do this)
+ * still without generating bus I/O.
+ *
+ * This function is expected to write DEVICE_DESC_LENGTH (18) bytes into
+ * buffer, which is guaranteed to be big enough.
+ *
+ * This function is called when sanity-checking a device before adding
+ * it to the list of discovered devices, and also when the user requests
+ * to read the device descriptor.
+ *
+ * This function is expected to return the descriptor in bus-endian format
+ * (LE). If it returns the multi-byte values in host-endian format,
+ * set the host_endian output parameter to "1".
+ *
+ * Return 0 on success or a LIBUSB_ERROR code on failure.
+ */
+ int (*get_device_descriptor)(struct libusb_device *device,
+ unsigned char *buffer, int *host_endian);
+
+ /* Get the ACTIVE configuration descriptor for a device.
+ *
+ * The descriptor should be retrieved from memory, NOT via bus I/O to the
+ * device. This means that you may have to cache it in a private structure
+ * during get_device_list enumeration. You may also have to keep track
+ * of which configuration is active when the user changes it.
+ *
+ * This function is expected to write len bytes of data into buffer, which
+ * is guaranteed to be big enough. If you can only do a partial write,
+ * return an error code.
+ *
+ * This function is expected to return the descriptor in bus-endian format
+ * (LE). If it returns the multi-byte values in host-endian format,
+ * set the host_endian output parameter to "1".
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*get_active_config_descriptor)(struct libusb_device *device,
+ unsigned char *buffer, size_t len, int *host_endian);
+
+ /* Get a specific configuration descriptor for a device.
+ *
+ * The descriptor should be retrieved from memory, NOT via bus I/O to the
+ * device. This means that you may have to cache it in a private structure
+ * during get_device_list enumeration.
+ *
+ * The requested descriptor is expressed as a zero-based index (i.e. 0
+ * indicates that we are requesting the first descriptor). The index does
+ * not (necessarily) equal the bConfigurationValue of the configuration
+ * being requested.
+ *
+ * This function is expected to write len bytes of data into buffer, which
+ * is guaranteed to be big enough. If you can only do a partial write,
+ * return an error code.
+ *
+ * This function is expected to return the descriptor in bus-endian format
+ * (LE). If it returns the multi-byte values in host-endian format,
+ * set the host_endian output parameter to "1".
+ *
+ * Return the length read on success or a LIBUSB_ERROR code on failure.
+ */
+ int (*get_config_descriptor)(struct libusb_device *device,
+ uint8_t config_index, unsigned char *buffer, size_t len,
+ int *host_endian);
+
+ /* Like get_config_descriptor but then by bConfigurationValue instead
+ * of by index.
+ *
+ * Optional, if not present the core will call get_config_descriptor
+ * for all configs until it finds the desired bConfigurationValue.
+ *
+ * Returns a pointer to the raw-descriptor in *buffer, this memory
+ * is valid as long as device is valid.
+ *
+ * Returns the length of the returned raw-descriptor on success,
+ * or a LIBUSB_ERROR code on failure.
+ */
+ int (*get_config_descriptor_by_value)(struct libusb_device *device,
+ uint8_t bConfigurationValue, unsigned char **buffer,
+ int *host_endian);
+
+ /* Get the bConfigurationValue for the active configuration for a device.
+ * Optional. This should only be implemented if you can retrieve it from
+ * cache (don't generate I/O).
+ *
+ * If you cannot retrieve this from cache, either do not implement this
+ * function, or return LIBUSB_ERROR_NOT_SUPPORTED. This will cause
+ * libusb to retrieve the information through a standard control transfer.
+ *
+ * This function must be non-blocking.
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - LIBUSB_ERROR_NOT_SUPPORTED if the value cannot be retrieved without
+ * blocking
+ * - another LIBUSB_ERROR code on other failure.
+ */
+ int (*get_configuration)(struct libusb_device_handle *dev_handle, int *config);
+
+ /* Set the active configuration for a device.
+ *
+ * A configuration value of -1 should put the device in unconfigured state.
+ *
+ * This function can block.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
+ * - LIBUSB_ERROR_BUSY if interfaces are currently claimed (and hence
+ * configuration cannot be changed)
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure.
+ */
+ int (*set_configuration)(struct libusb_device_handle *dev_handle, int config);
+
+ /* Claim an interface. When claimed, the application can then perform
+ * I/O to an interface's endpoints.
+ *
+ * This function should not generate any bus I/O and should not block.
+ * Interface claiming is a logical operation that simply ensures that
+ * no other drivers/applications are using the interface, and after
+ * claiming, no other drivers/applications can use the interface because
+ * we now "own" it.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if the interface does not exist
+ * - LIBUSB_ERROR_BUSY if the interface is in use by another driver/app
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*claim_interface)(struct libusb_device_handle *dev_handle, int interface_number);
+
+ /* Release a previously claimed interface.
+ *
+ * This function should also generate a SET_INTERFACE control request,
+ * resetting the alternate setting of that interface to 0. It's OK for
+ * this function to block as a result.
+ *
+ * You will only ever be asked to release an interface which was
+ * successfully claimed earlier.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*release_interface)(struct libusb_device_handle *dev_handle, int interface_number);
+
+ /* Set the alternate setting for an interface.
+ *
+ * You will only ever be asked to set the alternate setting for an
+ * interface which was successfully claimed earlier.
+ *
+ * It's OK for this function to block.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if the alternate setting does not exist
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*set_interface_altsetting)(struct libusb_device_handle *dev_handle,
+ int interface_number, int altsetting);
+
+ /* Clear a halt/stall condition on an endpoint.
+ *
+ * It's OK for this function to block.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*clear_halt)(struct libusb_device_handle *dev_handle,
+ unsigned char endpoint);
+
+ /* Perform a USB port reset to reinitialize a device.
+ *
+ * If possible, the device handle should still be usable after the reset
+ * completes, assuming that the device descriptors did not change during
+ * reset and all previous interface state can be restored.
+ *
+ * If something changes, or you cannot easily locate/verify the resetted
+ * device, return LIBUSB_ERROR_NOT_FOUND. This prompts the application
+ * to close the old handle and re-enumerate the device.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the device
+ * has been disconnected since it was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*reset_device)(struct libusb_device_handle *dev_handle);
+
+ /* Alloc num_streams usb3 bulk streams on the passed in endpoints */
+ int (*alloc_streams)(struct libusb_device_handle *dev_handle,
+ uint32_t num_streams, unsigned char *endpoints, int num_endpoints);
+
+ /* Free usb3 bulk streams allocated with alloc_streams */
+ int (*free_streams)(struct libusb_device_handle *dev_handle,
+ unsigned char *endpoints, int num_endpoints);
+
+ /* Allocate persistent DMA memory for the given device, suitable for
+ * zerocopy. May return NULL on failure. Optional to implement.
+ */
+ unsigned char *(*dev_mem_alloc)(struct libusb_device_handle *handle,
+ size_t len);
+
+ /* Free memory allocated by dev_mem_alloc. */
+ int (*dev_mem_free)(struct libusb_device_handle *handle,
+ unsigned char *buffer, size_t len);
+
+ /* Determine if a kernel driver is active on an interface. Optional.
+ *
+ * The presence of a kernel driver on an interface indicates that any
+ * calls to claim_interface would fail with the LIBUSB_ERROR_BUSY code.
+ *
+ * Return:
+ * - 0 if no driver is active
+ * - 1 if a driver is active
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*kernel_driver_active)(struct libusb_device_handle *dev_handle,
+ int interface_number);
+
+ /* Detach a kernel driver from an interface. Optional.
+ *
+ * After detaching a kernel driver, the interface should be available
+ * for claim.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
+ * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*detach_kernel_driver)(struct libusb_device_handle *dev_handle,
+ int interface_number);
+
+ /* Attach a kernel driver to an interface. Optional.
+ *
+ * Reattach a kernel driver to the device.
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
+ * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it
+ * was opened
+ * - LIBUSB_ERROR_BUSY if a program or driver has claimed the interface,
+ * preventing reattachment
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*attach_kernel_driver)(struct libusb_device_handle *dev_handle,
+ int interface_number);
+
+ /* Destroy a device. Optional.
+ *
+ * This function is called when the last reference to a device is
+ * destroyed. It should free any resources allocated in the get_device_list
+ * path.
+ */
+ void (*destroy_device)(struct libusb_device *dev);
+
+ /* Submit a transfer. Your implementation should take the transfer,
+ * morph it into whatever form your platform requires, and submit it
+ * asynchronously.
+ *
+ * This function must not block.
+ *
+ * This function gets called with the flying_transfers_lock locked!
+ *
+ * Return:
+ * - 0 on success
+ * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * - another LIBUSB_ERROR code on other failure
+ */
+ int (*submit_transfer)(struct usbi_transfer *itransfer);
+
+ /* Cancel a previously submitted transfer.
+ *
+ * This function must not block. The transfer cancellation must complete
+ * later, resulting in a call to usbi_handle_transfer_cancellation()
+ * from the context of handle_events.
+ */
+ int (*cancel_transfer)(struct usbi_transfer *itransfer);
+
+ /* Clear a transfer as if it has completed or cancelled, but do not
+ * report any completion/cancellation to the library. You should free
+ * all private data from the transfer as if you were just about to report
+ * completion or cancellation.
+ *
+ * This function might seem a bit out of place. It is used when libusb
+ * detects a disconnected device - it calls this function for all pending
+ * transfers before reporting completion (with the disconnect code) to
+ * the user. Maybe we can improve upon this internal interface in future.
+ */
+ void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
+
+ /* Handle any pending events on file descriptors. Optional.
+ *
+ * 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)
+ * as a result of the poll() system call. The num_ready parameter
+ * indicates the number of file descriptors that have reported events
+ * (i.e. the poll() return value). This should be enough information
+ * for you to determine which actions need to be taken on the currently
+ * active transfers.
+ *
+ * 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.
+ *
+ * This function should also be able to detect disconnection of the
+ * device, reporting that situation with usbi_handle_disconnect().
+ *
+ * When processing an event related to a transfer, you probably want to
+ * take usbi_transfer.lock to prevent races. See the documentation for
+ * the usbi_transfer structure.
+ *
+ * Return 0 on success, or a LIBUSB_ERROR code on failure.
+ */
+ int (*handle_events)(struct libusb_context *ctx,
+ 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
+ by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
+
+ Description of clocks:
+ USBI_CLOCK_REALTIME : clock returns time since system epoch.
+ USBI_CLOCK_MONOTONIC: clock returns time since unspecified start
+ time (usually boot).
+ */
+ int (*clock_gettime)(int clkid, struct timespec *tp);
+
+#ifdef USBI_TIMERFD_AVAILABLE
+ /* clock ID of the clock that should be used for timerfd */
+ clockid_t (*get_timerfd_clockid)(void);
+#endif
+
+ /* Number of bytes to reserve for per-context private backend data.
+ * This private data area is accessible through the "os_priv" field of
+ * struct libusb_context. */
+ size_t context_priv_size;
+
+ /* Number of bytes to reserve for per-device private backend data.
+ * This private data area is accessible through the "os_priv" field of
+ * struct libusb_device. */
+ size_t device_priv_size;
+
+ /* Number of bytes to reserve for per-handle private backend data.
+ * This private data area is accessible through the "os_priv" field of
+ * struct libusb_device. */
+ size_t device_handle_priv_size;
+
+ /* Number of bytes to reserve for per-transfer private backend data.
+ * This private data area is accessible by calling
+ * usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance.
+ */
+ size_t transfer_priv_size;
+};
+
+extern const struct usbi_os_backend usbi_backend;
+
+extern struct list_head active_contexts_list;
+extern usbi_mutex_static_t active_contexts_lock;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libusb1/linux/config.h b/libusb1/linux/config.h
new file mode 100644
index 0000000..c380a8b
--- /dev/null
+++ b/libusb1/linux/config.h
@@ -0,0 +1,163 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Default visibility */
+#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
+
+/* Start with debug message logging enabled */
+/* #undef ENABLE_DEBUG_LOGGING */
+
+/* Message logging */
+#define ENABLE_LOGGING 1
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+/* #undef HAVE_ASM_TYPES_H */
+
+/* Define to 1 if you have the declaration of `TFD_CLOEXEC', and to 0 if you
+ don't. */
+#define HAVE_DECL_TFD_CLOEXEC 1
+
+/* Define to 1 if you have the declaration of `TFD_NONBLOCK', and to 0 if you
+ don't. */
+#define HAVE_DECL_TFD_NONBLOCK 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `udev' library (-ludev). */
+#define HAVE_LIBUDEV 1
+
+/* Define to 1 if you have the <libudev.h> header file. */
+#define HAVE_LIBUDEV_H 1
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+/* #undef HAVE_LINUX_NETLINK_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `pipe2' function. */
+#define HAVE_PIPE2 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if the system has the type `struct timespec'. */
+#define HAVE_STRUCT_TIMESPEC 1
+
+/* syslog() function available */
+/* #undef HAVE_SYSLOG_FUNC */
+
+/* Define to 1 if you have the <syslog.h> header file. */
+/* #undef HAVE_SYSLOG_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+/* #undef HAVE_SYS_SOCKET_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Darwin backend */
+/* #undef OS_DARWIN */
+
+/* Haiku backend */
+/* #undef OS_HAIKU */
+
+/* Linux backend */
+#define OS_LINUX 1
+
+/* NetBSD backend */
+/* #undef OS_NETBSD */
+
+/* OpenBSD backend */
+/* #undef OS_OPENBSD */
+
+/* SunOS backend */
+/* #undef OS_SUNOS */
+
+/* Windows backend */
+/* #undef OS_WINDOWS */
+
+/* Name of package */
+#define PACKAGE "libusb"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "libusb-devel@lists.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libusb"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libusb 1.0.23-rc3"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libusb"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://libusb.info"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.0.23-rc3"
+
+/* type of second poll() argument */
+#define POLL_NFDS_TYPE nfds_t
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Use POSIX Threads */
+#define THREADS_POSIX 1
+
+/* timerfd headers available */
+#define USBI_TIMERFD_AVAILABLE 1
+
+/* Enable output to system log */
+/* #undef USE_SYSTEM_LOGGING_FACILITY */
+
+/* Use udev for device enumeration/hotplug */
+#define USE_UDEV 1
+
+/* Version number of package */
+#define VERSION "1.0.23-rc3"
+
+/* Oldest Windows version supported */
+/* #undef WINVER */
+
+/* Use GNU extensions */
+#define _GNU_SOURCE 1
+
+/* Oldest Windows version supported */
+/* #undef _WIN32_WINNT */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
diff --git a/libusb1/linux_google.c b/libusb1/linux_google.c
new file mode 100644
index 0000000..472a4bb
--- /dev/null
+++ b/libusb1/linux_google.c
@@ -0,0 +1,61 @@
+/*
+ * Linux-specific functions for libusb.
+ */
+
+#include "libusbi.h"
+
+extern int sysfs_can_relate_devices;
+extern int linux_get_device_address(
+ struct libusb_context *ctx, int detached,
+ uint8_t *busnum, uint8_t *devaddr,const char *dev_node,
+ const char *sys_name);
+extern int linux_enumerate_device(
+ struct libusb_context *ctx,
+ uint8_t busnum, uint8_t devaddr, const char *sysfs_dir);
+
+/**
+ * Returns a USB device currently attached to the system. This is
+ * your entry point into connecting to that USB device.
+ *
+ * This return value of this function indicates whether the device was found or
+ * not. Success is a 0, other values indicate failure.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param devname SYSFS device name to check
+ * \param device output location for the device. Must be later freed with
+ * libusb_unref_device().
+ * \returns 0 for success.
+ * \ref libusb_error according to errors encountered by the backend.
+ */
+int libusb_ext_get_one_device(libusb_context *ctx, const char* devname,
+ libusb_device **device)
+{
+ if (!sysfs_can_relate_devices) {
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+ }
+
+ int r = 0;
+ uint8_t busnum, devaddr;
+ USBI_GET_CONTEXT(ctx);
+
+ r = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname);
+ if (r < 0) {
+ return r;
+ }
+
+ r = linux_enumerate_device(ctx, busnum & 0xff, devaddr & 0xff, devname);
+ if (r < 0) {
+ return r;
+ }
+
+ struct libusb_device *it;
+ usbi_mutex_lock(&ctx->usb_devs_lock);
+ list_for_each_entry(it, &ctx->usb_devs, list, struct libusb_device) {
+ if (it->bus_number == busnum && it->device_address == devaddr) {
+ *device = it;
+ }
+ }
+ usbi_mutex_unlock(&ctx->usb_devs_lock);
+
+ return LIBUSB_SUCCESS;
+}
diff --git a/libusb1/linux_google.h b/libusb1/linux_google.h
new file mode 100644
index 0000000..87f3ffb
--- /dev/null
+++ b/libusb1/linux_google.h
@@ -0,0 +1,24 @@
+#ifndef THIRD_PARTY_LIBUSB_LIBUSB1_LINUX_GOOGLE_H_
+#define THIRD_PARTY_LIBUSB_LIBUSB1_LINUX_GOOGLE_H_
+
+struct libusb_context;
+struct libusb_device;
+
+/**
+ * Returns a USB device currently attached to the system. This is
+ * your entry point into connecting to that USB device.
+ *
+ * This return value of this function indicates whether the device was found or
+ * not. Success is a 0, other values indicate failure.
+ *
+ * \param ctx the context to operate on, or NULL for the default context
+ * \param devname SYSFS device name to check
+ * \param device output location for the device. Must be later freed with
+ * libusb_unref_device().
+ * \returns 0 for success.
+ * \ref libusb_error according to errors encountered by the backend.
+ */
+int libusb_ext_get_one_device(libusb_context *ctx, const char* devname,
+ libusb_device **device);
+
+#endif // THIRD_PARTY_LIBUSB_LIBUSB1_LINUX_GOOGLE_H_
diff --git a/libusb1/msvc/config.h b/libusb1/msvc/config.h
new file mode 100644
index 0000000..b20d99b
--- /dev/null
+++ b/libusb1/msvc/config.h
@@ -0,0 +1,51 @@
+/* config.h. Manual config for MSVC. */
+
+#ifndef _MSC_VER
+#warn "msvc/config.h shouldn't be included for your development environment."
+#error "Please make sure the msvc/ directory is removed from your build path."
+#endif
+
+/* Visual Studio 2015 and later defines timespec */
+#if (_MSC_VER >= 1900)
+#define _TIMESPEC_DEFINED 1
+#endif
+
+/* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */
+#pragma warning(disable:4200)
+/* Disable: warning C4324: structure was padded due to __declspec(align()) */
+#pragma warning(disable:4324)
+/* Disable: warning C6258: Using TerminateThread does not allow proper thread clean up */
+#pragma warning(disable:6258)
+/* Disable: warning C4996: 'GetVersionA': was declared deprecated */
+#pragma warning(disable:4996)
+
+#if defined(_PREFAST_)
+/* Disable "Banned API" errors when using the MS's WDK OACR/Prefast */
+#pragma warning(disable:28719)
+/* Disable "The function 'InitializeCriticalSection' must be called from within a try/except block" */
+#pragma warning(disable:28125)
+#endif
+
+/* Default visibility */
+#define DEFAULT_VISIBILITY /**/
+
+/* Enable global message logging */
+#define ENABLE_LOGGING 1
+
+/* Uncomment to start with debug message logging enabled */
+// #define ENABLE_DEBUG_LOGGING 1
+
+/* Uncomment to enabling logging to system log */
+// #define USE_SYSTEM_LOGGING_FACILITY
+
+/* type of second poll() argument */
+#define POLL_NFDS_TYPE unsigned int
+
+/* Windows/WinCE backend */
+#if defined(_WIN32_WCE)
+#define OS_WINCE 1
+#define HAVE_MISSING_H
+#else
+#define OS_WINDOWS 1
+#define HAVE_SYS_TYPES_H 1
+#endif
diff --git a/libusb1/msvc/errno.h b/libusb1/msvc/errno.h
new file mode 100644
index 0000000..07d15e3
--- /dev/null
+++ b/libusb1/msvc/errno.h
@@ -0,0 +1,102 @@
+/*
+ * errno.h
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Error numbers and access to error reporting.
+ *
+ */
+
+#ifndef _ERRNO_H_
+#define _ERRNO_H_
+
+#include <crtdefs.h>
+
+/*
+ * Error numbers.
+ * TODO: Can't be sure of some of these assignments, I guessed from the
+ * names given by strerror and the defines in the Cygnus errno.h. A lot
+ * of the names from the Cygnus errno.h are not represented, and a few
+ * of the descriptions returned by strerror do not obviously match
+ * their error naming.
+ */
+#define EPERM 1 /* Operation not permitted */
+#define ENOFILE 2 /* No such file or directory */
+#define ENOENT 2
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted function call */
+#define EIO 5 /* Input/output error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Arg list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file descriptor */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Resource temporarily unavailable */
+#define ENOMEM 12 /* Not enough space */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+/* 15 - Unknown Error */
+#define EBUSY 16 /* strerror reports "Resource device" */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Improper link (cross-device link?) */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* Too many open files in system */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Inappropriate I/O control operation */
+/* 26 - Unknown Error */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Domain error (math functions) */
+#define ERANGE 34 /* Result too large (possibly too small) */
+/* 35 - Unknown Error */
+#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */
+#define EDEADLK 36
+#if 0
+/* 37 - Unknown Error */
+#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */
+#define ENOLCK 39 /* No locks available (46 in Cyg?) */
+#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */
+#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */
+#define EILSEQ 42 /* Illegal byte sequence */
+#endif
+
+/*
+ * NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the
+ * sockets.h header provided with windows32api-0.1.2.
+ * You should go and put an #if 0 ... #endif around the whole block
+ * of errors (look at the comment above them).
+ */
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see
+ * stdlib.h.
+ */
+#if defined(_UWIN) || defined(_WIN32_WCE)
+#undef errno
+extern int errno;
+#else
+_CRTIMP int* __cdecl _errno(void);
+#define errno (*_errno())
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* Not _ERRNO_H_ */
\ No newline at end of file
diff --git a/libusb1/msvc/inttypes.h b/libusb1/msvc/inttypes.h
new file mode 100644
index 0000000..289bb50
--- /dev/null
+++ b/libusb1/msvc/inttypes.h
@@ -0,0 +1,295 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file was original part of the w64 mingw-runtime package.
+ */
+
+/*
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * Modified for libusb/MSVC: Pete Batard <pbatard@gmail.com>
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Date: 2010-04-02
+ */
+
+#ifndef _MSC_VER
+#error This header should only be used with Microsoft compilers
+#endif
+
+/* 7.8 Format conversion of integer types <inttypes.h> */
+
+#ifndef _INTTYPES_H_
+#define _INTTYPES_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+ } imaxdiv_t;
+
+
+/* 7.8.1 Macros for format specifiers
+ *
+ * MS runtime does not yet understand C9x standard "ll"
+ * length specifier. It appears to treat "ll" as "l".
+ * The non-standard I64 length specifier causes warning in GCC,
+ * but understood by MS runtime functions.
+ */
+
+/* fprintf macros for signed types */
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "I64d"
+
+#define PRIdLEAST8 "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 "I64d"
+
+#define PRIdFAST8 "d"
+#define PRIdFAST16 "d"
+#define PRIdFAST32 "d"
+#define PRIdFAST64 "I64d"
+
+#define PRIdMAX "I64d"
+
+#define PRIi8 "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 "I64i"
+
+#define PRIiLEAST8 "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 "I64i"
+
+#define PRIiFAST8 "i"
+#define PRIiFAST16 "i"
+#define PRIiFAST32 "i"
+#define PRIiFAST64 "I64i"
+
+#define PRIiMAX "I64i"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "I64o"
+
+#define PRIoLEAST8 "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 "I64o"
+
+#define PRIoFAST8 "o"
+#define PRIoFAST16 "o"
+#define PRIoFAST32 "o"
+#define PRIoFAST64 "I64o"
+
+#define PRIoMAX "I64o"
+
+/* fprintf macros for unsigned types */
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "I64u"
+
+
+#define PRIuLEAST8 "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 "I64u"
+
+#define PRIuFAST8 "u"
+#define PRIuFAST16 "u"
+#define PRIuFAST32 "u"
+#define PRIuFAST64 "I64u"
+
+#define PRIuMAX "I64u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "I64x"
+
+#define PRIxLEAST8 "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 "I64x"
+
+#define PRIxFAST8 "x"
+#define PRIxFAST16 "x"
+#define PRIxFAST32 "x"
+#define PRIxFAST64 "I64x"
+
+#define PRIxMAX "I64x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "I64X"
+
+#define PRIXLEAST8 "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 "I64X"
+
+#define PRIXFAST8 "X"
+#define PRIXFAST16 "X"
+#define PRIXFAST32 "X"
+#define PRIXFAST64 "I64X"
+
+#define PRIXMAX "I64X"
+
+/*
+ * fscanf macros for signed int types
+ * NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
+ * (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
+ * no length identifiers
+ */
+
+#define SCNd16 "hd"
+#define SCNd32 "d"
+#define SCNd64 "I64d"
+
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 "I64d"
+