14eaae44dSAndrew Thompson.\" 2a5118bdfSAndrew Thompson.\" Copyright (c) 2009 Sylvestre Gallon 34eaae44dSAndrew Thompson.\" 44eaae44dSAndrew Thompson.\" All rights reserved. 54eaae44dSAndrew Thompson.\" 64eaae44dSAndrew Thompson.\" Redistribution and use in source and binary forms, with or without 74eaae44dSAndrew Thompson.\" modification, are permitted provided that the following conditions 84eaae44dSAndrew Thompson.\" are met: 94eaae44dSAndrew Thompson.\" 1. Redistributions of source code must retain the above copyright 104eaae44dSAndrew Thompson.\" notice, this list of conditions and the following disclaimer. 114eaae44dSAndrew Thompson.\" 2. Redistributions in binary form must reproduce the above copyright 124eaae44dSAndrew Thompson.\" notice, this list of conditions and the following disclaimer in the 134eaae44dSAndrew Thompson.\" documentation and/or other materials provided with the distribution. 144eaae44dSAndrew Thompson.\" 154eaae44dSAndrew Thompson.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 164eaae44dSAndrew Thompson.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 174eaae44dSAndrew Thompson.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 184eaae44dSAndrew Thompson.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 194eaae44dSAndrew Thompson.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 204eaae44dSAndrew Thompson.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 214eaae44dSAndrew Thompson.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 224eaae44dSAndrew Thompson.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 234eaae44dSAndrew Thompson.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 244eaae44dSAndrew Thompson.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 254eaae44dSAndrew Thompson.\" SUCH DAMAGE. 264eaae44dSAndrew Thompson.\" 274eaae44dSAndrew Thompson.\" $FreeBSD$ 284eaae44dSAndrew Thompson.\" 290f2c7066SHans Petter Selasky.Dd June 17, 2016 304eaae44dSAndrew Thompson.Dt LIBUSB 3 314eaae44dSAndrew Thompson.Os 324eaae44dSAndrew Thompson.Sh NAME 334eaae44dSAndrew Thompson.Nm libusb 344eaae44dSAndrew Thompson.Nd "USB access library" 354eaae44dSAndrew Thompson.Sh LIBRARY 3611867070SHans Petter SelaskyUSB access library 3711867070SHans Petter Selasky.Pq libusb, -lusb 384eaae44dSAndrew Thompson.Sh SYNOPSIS 39a5118bdfSAndrew Thompson.In libusb.h 404eaae44dSAndrew Thompson.Sh DESCRIPTION 414eaae44dSAndrew ThompsonThe 424eaae44dSAndrew Thompson.Nm 43a5118bdfSAndrew Thompsonlibrary contains interfaces for directly managing a usb device. 44a5118bdfSAndrew ThompsonThe current implementation supports v1.0 of the libusb API. 45930a4206SHans Petter Selasky.Sh LIBRARY INITIALISATION AND DEINITIALISATION 4614b896ceSHans Petter Selasky.Ft "const struct libusb_version *" 4714b896ceSHans Petter Selasky.Fn libusb_get_version "void" 4814b896ceSHans Petter SelaskyThis function returns version information about LibUSB. 4914b896ceSHans Petter Selasky.Pp 50a5118bdfSAndrew Thompson.Ft int 51930a4206SHans Petter Selasky.Fn libusb_init "libusb_context **ctx" 52c8c1f2ecSHans Petter SelaskyThis function initialises libusb. 5311867070SHans Petter SelaskyIt must be called at the beginning 5411867070SHans Petter Selaskyof the program, before other libusb routines are used. 55c8c1f2ecSHans Petter SelaskyThis function returns 0 on success or LIBUSB_ERROR on 56a5118bdfSAndrew Thompsonfailure. 574eaae44dSAndrew Thompson.Pp 58a5118bdfSAndrew Thompson.Ft void 59a5118bdfSAndrew Thompson.Fn libusb_exit "libusb_context *ctx" 60c8c1f2ecSHans Petter SelaskyDeinitialise libusb. 61c8c1f2ecSHans Petter SelaskyMust be called at the end of the application. 6211867070SHans Petter SelaskyOther libusb routines may not be called after this function. 63a5118bdfSAndrew Thompson.Pp 64698e791aSHans Petter Selasky.Ft const char * 65698e791aSHans Petter Selasky.Fn libusb_strerror "int code" 6611867070SHans Petter SelaskyGet the ASCII representation of the error given by the 67698e791aSHans Petter Selasky.Fa code 68698e791aSHans Petter Selaskyargument. 69c61f2561SHans Petter SelaskyThis function does not return NULL. 70c61f2561SHans Petter Selasky.Pp 71c61f2561SHans Petter Selasky.Ft const char * 72c61f2561SHans Petter Selasky.Fn libusb_error_name "int code" 73c61f2561SHans Petter SelaskyGet the ASCII representation of the error enum given by the 74c61f2561SHans Petter Selasky.Fa code 75c61f2561SHans Petter Selaskyargument. 76c61f2561SHans Petter SelaskyThis function does not return NULL. 77698e791aSHans Petter Selasky.Pp 78a5118bdfSAndrew Thompson.Ft void 79a5118bdfSAndrew Thompson.Fn libusb_set_debug "libusb_context *ctx" "int level" 8011867070SHans Petter SelaskySet the debug level to 8111867070SHans Petter Selasky.Fa level . 82a5118bdfSAndrew Thompson.Pp 83a5118bdfSAndrew Thompson.Ft ssize_t 84a5118bdfSAndrew Thompson.Fn libusb_get_device_list "libusb_context *ctx" "libusb_device ***list" 8511867070SHans Petter SelaskyPopulate 86a5118bdfSAndrew Thompson.Fa list 8711867070SHans Petter Selaskywith the list of usb devices available, adding a reference to each 8811867070SHans Petter Selaskydevice in the list. 8911867070SHans Petter SelaskyAll the list entries created by this 9011867070SHans Petter Selaskyfunction must have their reference counter 9111867070SHans Petter Selaskydecremented when you are done with them, 9211867070SHans Petter Selaskyand the list itself must be freed. 93c8c1f2ecSHans Petter SelaskyThis 9411867070SHans Petter Selaskyfunction returns the number of devices in the list or a LIBUSB_ERROR code. 95a5118bdfSAndrew Thompson.Pp 96a5118bdfSAndrew Thompson.Ft void 97a5118bdfSAndrew Thompson.Fn libusb_free_device_list "libusb_device **list" "int unref_devices" 98c8c1f2ecSHans Petter SelaskyFree the list of devices discovered by libusb_get_device_list. 99c8c1f2ecSHans Petter SelaskyIf 100a5118bdfSAndrew Thompson.Fa unref_device 10111867070SHans Petter Selaskyis set to 1 all devices in the list have their reference 10211867070SHans Petter Selaskycounter decremented once. 103a5118bdfSAndrew Thompson.Pp 104a5118bdfSAndrew Thompson.Ft uint8_t 105a5118bdfSAndrew Thompson.Fn libusb_get_bus_number "libusb_device *dev" 106a5118bdfSAndrew ThompsonReturns the number of the bus contained by the device 107a5118bdfSAndrew Thompson.Fa dev . 108a5118bdfSAndrew Thompson.Pp 1090f2c7066SHans Petter Selasky.Ft uint8_t 1100f2c7066SHans Petter Selasky.Fn libusb_get_port_number "libusb_device *dev" 1110f2c7066SHans Petter SelaskyReturns the port number which the device given by 1120f2c7066SHans Petter Selasky.Fa dev 1130f2c7066SHans Petter Selaskyis attached to. 1140f2c7066SHans Petter Selasky.Pp 1155906bf49SEd Maste.Ft int 116a9205626SEd Maste.Fn libusb_get_port_numbers "libusb_device *dev" "uint8_t *buf" "uint8_t bufsize" 1175906bf49SEd MasteStores, in the buffer 1185906bf49SEd Maste.Fa buf 1195906bf49SEd Masteof size 1205906bf49SEd Maste.Fa bufsize , 1215906bf49SEd Mastethe list of all port numbers from root for the device 1225906bf49SEd Maste.Fa dev . 1235906bf49SEd Maste.Pp 124a9205626SEd Maste.Ft int 125a9205626SEd Maste.Fn libusb_get_port_path "libusb_context *ctx" "libusb_device *dev" "uint8_t *buf" "uint8_t bufsize" 126a9205626SEd MasteDeprecated function equivalent to libusb_get_port_numbers. 127a9205626SEd Maste.Pp 128a5118bdfSAndrew Thompson.Ft uint8_t 129a5118bdfSAndrew Thompson.Fn libusb_get_device_address "libusb_device *dev" 130ca96e26aSHans Petter SelaskyReturns the device_address contained by the device 131a5118bdfSAndrew Thompson.Fa dev . 132a5118bdfSAndrew Thompson.Pp 133ca96e26aSHans Petter Selasky.Ft enum libusb_speed 134ca96e26aSHans Petter Selasky.Fn libusb_get_device_speed "libusb_device *dev" 135ca96e26aSHans Petter SelaskyReturns the wire speed at which the device is connected. 136ca96e26aSHans Petter SelaskySee the LIBUSB_SPEED_XXX enums for more information. 137ca96e26aSHans Petter SelaskyLIBUSB_SPEED_UNKNOWN is returned in case of unknown wire speed. 138ca96e26aSHans Petter Selasky.Pp 139a5118bdfSAndrew Thompson.Ft int 140a5118bdfSAndrew Thompson.Fn libusb_get_max_packet_size "libusb_device *dev" "unsigned char endpoint" 141ca96e26aSHans Petter SelaskyReturns the wMaxPacketSize value on success, LIBUSB_ERROR_NOT_FOUND if the 142a5118bdfSAndrew Thompsonendpoint does not exist and LIBUSB_ERROR_OTHERS on other failure. 143a5118bdfSAndrew Thompson.Pp 144748205a3SHans Petter Selasky.Ft int 145748205a3SHans Petter Selasky.Fn libusb_get_max_iso_packet_size "libusb_device *dev" "unsigned char endpoint" 146748205a3SHans Petter SelaskyReturns the packet size multiplied by the packet multiplier on success, 147748205a3SHans Petter SelaskyLIBUSB_ERROR_NOT_FOUND if the endpoint does not exist and 148748205a3SHans Petter SelaskyLIBUSB_ERROR_OTHERS on other failure. 149748205a3SHans Petter Selasky.Pp 150a5118bdfSAndrew Thompson.Ft libusb_device * 151a5118bdfSAndrew Thompson.Fn libusb_ref_device "libusb_device *dev" 152a5118bdfSAndrew ThompsonIncrement the reference counter of the device 153a5118bdfSAndrew Thompson.Fa dev . 154a5118bdfSAndrew Thompson.Pp 155a5118bdfSAndrew Thompson.Ft void 156a5118bdfSAndrew Thompson.Fn libusb_unref_device "libusb_device *dev" 157a5118bdfSAndrew ThompsonDecrement the reference counter of the device 158a5118bdfSAndrew Thompson.Fa dev . 159a5118bdfSAndrew Thompson.Pp 160a5118bdfSAndrew Thompson.Ft int 161a5118bdfSAndrew Thompson.Fn libusb_open "libusb_device *dev" "libusb_device_handle **devh" 162c8c1f2ecSHans Petter SelaskyOpen a device and obtain a device_handle. 163c8c1f2ecSHans Petter SelaskyReturns 0 on success, 16411867070SHans Petter SelaskyLIBUSB_ERROR_NO_MEM on memory allocation problems, LIBUSB_ERROR_ACCESS 16511867070SHans Petter Selaskyon permissions problems, LIBUSB_ERROR_NO_DEVICE if the device has been 16611867070SHans Petter Selaskydisconnected and a LIBUSB_ERROR code on other errors. 167a5118bdfSAndrew Thompson.Pp 168a5118bdfSAndrew Thompson.Ft libusb_device_handle * 169a5118bdfSAndrew Thompson.Fn libusb_open_device_with_vid_pid "libusb_context *ctx" "uint16_t vid" "uint16_t pid" 17011867070SHans Petter SelaskyA convenience function to open a device by vendor and product IDs 171a5118bdfSAndrew Thompson.Fa vid 1724eaae44dSAndrew Thompsonand 173a5118bdfSAndrew Thompson.Fa pid . 174ca96e26aSHans Petter SelaskyReturns NULL on error. 1754eaae44dSAndrew Thompson.Pp 176a5118bdfSAndrew Thompson.Ft void 177a5118bdfSAndrew Thompson.Fn libusb_close "libusb_device_handle *devh" 178a5118bdfSAndrew ThompsonClose a device handle. 1794eaae44dSAndrew Thompson.Pp 180a5118bdfSAndrew Thompson.Ft libusb_device * 181ca96e26aSHans Petter Selasky.Fn libusb_get_device "libusb_device_handle *devh" 182ca96e26aSHans Petter SelaskyGet the device contained by devh. 183ca96e26aSHans Petter SelaskyReturns NULL on error. 1844eaae44dSAndrew Thompson.Pp 185a5118bdfSAndrew Thompson.Ft int 186a5118bdfSAndrew Thompson.Fn libusb_get_configuration "libusb_device_handle *devh" "int *config" 187a3fb6da9SGlen BarberReturns the value of the current configuration. 188c8c1f2ecSHans Petter SelaskyReturns 0 189a5118bdfSAndrew Thompsonon success, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected 190a5118bdfSAndrew Thompsonand a LIBUSB_ERROR code on error. 1914eaae44dSAndrew Thompson.Pp 192a5118bdfSAndrew Thompson.Ft int 193a5118bdfSAndrew Thompson.Fn libusb_set_configuration "libusb_device_handle *devh" "int config" 19411867070SHans Petter SelaskySet the active configuration to 195a5118bdfSAndrew Thompson.Fa config 196a5118bdfSAndrew Thompsonfor the device contained by 197a5118bdfSAndrew Thompson.Fa devh . 198ca96e26aSHans Petter SelaskyThis function returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the requested 199a5118bdfSAndrew Thompsonconfiguration does not exist, LIBUSB_ERROR_BUSY if the interfaces are currently 200a5118bdfSAndrew Thompsonclaimed, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and a 201a5118bdfSAndrew ThompsonLIBUSB_ERROR code on failure. 2024eaae44dSAndrew Thompson.Pp 203a5118bdfSAndrew Thompson.Ft int 204a5118bdfSAndrew Thompson.Fn libusb_claim_interface "libusb_device_handle *devh" "int interface_number" 205a5118bdfSAndrew ThompsonClaim an interface in a given libusb_handle 206a5118bdfSAndrew Thompson.Fa devh . 207c8c1f2ecSHans Petter SelaskyThis is a non-blocking function. 20811867070SHans Petter SelaskyIt returns 0 on success, LIBUSB_ERROR_NOT_FOUND 209a5118bdfSAndrew Thompsonif the requested interface does not exist, LIBUSB_ERROR_BUSY if a program or 210a5118bdfSAndrew Thompsondriver has claimed the interface, LIBUSB_ERROR_NO_DEVICE if the device has 211a5118bdfSAndrew Thompsonbeen disconnected and a LIBUSB_ERROR code on failure. 2124eaae44dSAndrew Thompson.Pp 213a5118bdfSAndrew Thompson.Ft int 214a5118bdfSAndrew Thompson.Fn libusb_release_interface "libusb_device_handle *devh" "int interface_number" 21511867070SHans Petter SelaskyThis function releases an interface. 21611867070SHans Petter SelaskyAll the claimed interfaces on a device must be released 21711867070SHans Petter Selaskybefore closing the device. 218c8c1f2ecSHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_NOT_FOUND if the 219799162a6SJoel Dahlinterface was not claimed, LIBUSB_ERROR_NO_DEVICE if the device has been 220a5118bdfSAndrew Thompsondisconnected and LIBUSB_ERROR on failure. 2214eaae44dSAndrew Thompson.Pp 222a5118bdfSAndrew Thompson.Ft int 223a5118bdfSAndrew Thompson.Fn libusb_set_interface_alt_setting "libusb_device_handle *dev" "int interface_number" "int alternate_setting" 224c8c1f2ecSHans Petter SelaskyActivate an alternate setting for an interface. 225c8c1f2ecSHans Petter SelaskyReturns 0 on success, 226a5118bdfSAndrew ThompsonLIBUSB_ERROR_NOT_FOUND if the interface was not claimed or the requested 227a5118bdfSAndrew Thompsonsetting does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been 22811867070SHans Petter Selaskydisconnected and a LIBUSB_ERROR code on failure. 2294eaae44dSAndrew Thompson.Pp 230a5118bdfSAndrew Thompson.Ft int 231a5118bdfSAndrew Thompson.Fn libusb_clear_halt "libusb_device_handle *devh" "unsigned char endpoint" 232c8c1f2ecSHans Petter SelaskyClear an halt/stall for a endpoint. 233c8c1f2ecSHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_NOT_FOUND 234a5118bdfSAndrew Thompsonif the endpoint does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been 235a5118bdfSAndrew Thompsondisconnected and a LIBUSB_ERROR code on failure. 2364eaae44dSAndrew Thompson.Pp 237a5118bdfSAndrew Thompson.Ft int 238a5118bdfSAndrew Thompson.Fn libusb_reset_device "libusb_device_handle *devh" 239c8c1f2ecSHans Petter SelaskyPerform an USB port reset for an usb device. 240c8c1f2ecSHans Petter SelaskyReturns 0 on success, 241a5118bdfSAndrew ThompsonLIBUSB_ERROR_NOT_FOUND if re-enumeration is required or if the device has 242a5118bdfSAndrew Thompsonbeen disconnected and a LIBUSB_ERROR code on failure. 2434eaae44dSAndrew Thompson.Pp 244a5118bdfSAndrew Thompson.Ft int 245f1b5fa6eSHans Petter Selasky.Fn libusb_check_connected "libusb_device_handle *devh" 24611867070SHans Petter SelaskyTest if the USB device is still connected. 247c8c1f2ecSHans Petter SelaskyReturns 0 on success, 24811867070SHans Petter SelaskyLIBUSB_ERROR_NO_DEVICE if it has been disconnected and a LIBUSB_ERROR 249f1b5fa6eSHans Petter Selaskycode on failure. 250f1b5fa6eSHans Petter Selasky.Pp 251f1b5fa6eSHans Petter Selasky.Ft int 252a5118bdfSAndrew Thompson.Fn libusb_kernel_driver_active "libusb_device_handle *devh" "int interface" 253c8c1f2ecSHans Petter SelaskyDetermine if a driver is active on a interface. 2544d2472aaSHans Petter SelaskyReturns 0 if no kernel driver is active 2554d2472aaSHans Petter Selaskyand 1 if a kernel driver is active, LIBUSB_ERROR_NO_DEVICE 25611867070SHans Petter Selaskyif the device has been disconnected and a LIBUSB_ERROR code on failure. 2574eaae44dSAndrew Thompson.Pp 258a5118bdfSAndrew Thompson.Ft int 259698e791aSHans Petter Selasky.Fn libusb_get_driver "libusb_device_handle *devh" "int interface" "char *name" "int namelen" 260698e791aSHans Petter Selaskyor 261698e791aSHans Petter Selasky.Ft int 262698e791aSHans Petter Selasky.Fn libusb_get_driver_np "libusb_device_handle *devh" "int interface" "char *name" "int namelen" 26311867070SHans Petter SelaskyCopy the name of the driver attached to the given 264698e791aSHans Petter Selasky.Fa device 265698e791aSHans Petter Selaskyand 266698e791aSHans Petter Selasky.Fa interface 26711867070SHans Petter Selaskyinto the buffer 268698e791aSHans Petter Selasky.Fa name 26911867070SHans Petter Selaskyof length 270698e791aSHans Petter Selasky.Fa namelen . 271698e791aSHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_NOT_FOUND if no kernel driver is attached 272698e791aSHans Petter Selaskyto the given interface and LIBUSB_ERROR_INVALID_PARAM if the interface does 273698e791aSHans Petter Selaskynot exist. 274698e791aSHans Petter SelaskyThis function is non-portable. 275698e791aSHans Petter SelaskyThe buffer pointed to by 276698e791aSHans Petter Selasky.Fa name 277698e791aSHans Petter Selaskyis only zero terminated on success. 278698e791aSHans Petter Selasky.Pp 279698e791aSHans Petter Selasky.Ft int 280a5118bdfSAndrew Thompson.Fn libusb_detach_kernel_driver "libusb_device_handle *devh" "int interface" 281698e791aSHans Petter Selaskyor 282698e791aSHans Petter Selasky.Ft int 283698e791aSHans Petter Selasky.Fn libusb_detach_kernel_driver_np "libusb_device_handle *devh" "int interface" 284698e791aSHans Petter SelaskyDetach a kernel driver from an interface. 28511867070SHans Petter SelaskyThis is needed to claim an interface already claimed by a kernel driver. 286698e791aSHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_NOT_FOUND if no kernel driver was active, 287c8c1f2ecSHans Petter SelaskyLIBUSB_ERROR_INVALID_PARAM if the interface does not exist, 288c8c1f2ecSHans Petter SelaskyLIBUSB_ERROR_NO_DEVICE if the device has been disconnected 289c8c1f2ecSHans Petter Selaskyand a LIBUSB_ERROR code on failure. 290c8c1f2ecSHans Petter SelaskyThis function is non-portable. 2914eaae44dSAndrew Thompson.Pp 292a5118bdfSAndrew Thompson.Ft int 293a5118bdfSAndrew Thompson.Fn libusb_attach_kernel_driver "libusb_device_handle *devh" "int interface" 29411867070SHans Petter SelaskyRe-attach an interface kernel driver that was previously detached. 295c8c1f2ecSHans Petter SelaskyReturns 0 on success, 296c8c1f2ecSHans Petter SelaskyLIBUSB_ERROR_INVALID_PARAM if the interface does not exist, 297c8c1f2ecSHans Petter SelaskyLIBUSB_ERROR_NO_DEVICE 29811867070SHans Petter Selaskyif the device has been disconnected, LIBUSB_ERROR_BUSY if the driver cannot be 299a5118bdfSAndrew Thompsonattached because the interface is claimed by a program or driver and a 300a5118bdfSAndrew ThompsonLIBUSB_ERROR code on failure. 301*5b40d960SHans Petter Selasky.Pp 302*5b40d960SHans Petter Selasky.Ft int 303*5b40d960SHans Petter Selasky.Fn libusb_set_auto_detach_kernel_driver "libusb_device_handle *devh" "int enable" 304*5b40d960SHans Petter SelaskyThis function enables automatic kernel interface driver detach when an 305*5b40d960SHans Petter Selaskyinterface is claimed. 306*5b40d960SHans Petter SelaskyWhen the interface is restored the kernel driver is allowed to be re-attached. 307*5b40d960SHans Petter SelaskyIf the 308*5b40d960SHans Petter Selasky.Fa enable 309*5b40d960SHans Petter Selaskyargument is non-zero the feature is enabled. 310*5b40d960SHans Petter SelaskyElse disabled. 311*5b40d960SHans Petter SelaskyReturns 0 on success and a LIBUSB_ERROR code on 312*5b40d960SHans Petter Selaskyfailure. 313a5118bdfSAndrew Thompson.Sh USB DESCRIPTORS 314a5118bdfSAndrew Thompson.Ft int 315a5118bdfSAndrew Thompson.Fn libusb_get_device_descriptor "libusb_device *dev" "libusb_device_descriptor *desc" 316a5118bdfSAndrew ThompsonGet the USB device descriptor for the device 317a5118bdfSAndrew Thompson.Fa dev . 318c8c1f2ecSHans Petter SelaskyThis is a non-blocking function. 319c8c1f2ecSHans Petter SelaskyReturns 0 on success and a LIBUSB_ERROR code on 320a5118bdfSAndrew Thompsonfailure. 3214eaae44dSAndrew Thompson.Pp 322a5118bdfSAndrew Thompson.Ft int 323cb0df9e8SHans Petter Selasky.Fn libusb_get_active_config_descriptor "libusb_device *dev" "struct libusb_config_descriptor **config" 324c8c1f2ecSHans Petter SelaskyGet the USB configuration descriptor for the active configuration. 325c8c1f2ecSHans Petter SelaskyReturns 0 on 32611867070SHans Petter Selaskysuccess, LIBUSB_ERROR_NOT_FOUND if the device is in 32711867070SHans Petter Selaskyan unconfigured state 32811867070SHans Petter Selaskyand a LIBUSB_ERROR code on error. 3294eaae44dSAndrew Thompson.Pp 330a5118bdfSAndrew Thompson.Ft int 331a5118bdfSAndrew Thompson.Fn libusb_get_config_descriptor "libusb_device *dev" "uint8_t config_index" "libusb_config_descriptor **config" 33211867070SHans Petter SelaskyGet a USB configuration descriptor based on its index 333a5118bdfSAndrew Thompson.Fa idx. 334a5118bdfSAndrew ThompsonReturns 0 on success, LIBUSB_ERROR_NOT_FOUND if the configuration does not exist 33511867070SHans Petter Selaskyand a LIBUSB_ERROR code on error. 336545b01adSAndrew Thompson.Pp 337a5118bdfSAndrew Thompson.Ft int 338a5118bdfSAndrew Thompson.Fn libusb_get_config_descriptor_by_value "libusb_device *dev" "uint8 bConfigurationValue" "libusb_config_descriptor **config" 339c8c1f2ecSHans Petter SelaskyGet a USB configuration descriptor with a specific bConfigurationValue. 340c8c1f2ecSHans Petter SelaskyThis is 34111867070SHans Petter Selaskya non-blocking function which does not send a request through the device. 342c8c1f2ecSHans Petter SelaskyReturns 0 343c8c1f2ecSHans Petter Selaskyon success, LIBUSB_ERROR_NOT_FOUND if the configuration 34411867070SHans Petter Selaskydoes not exist and a 345a5118bdfSAndrew ThompsonLIBUSB_ERROR code on failure. 3464eaae44dSAndrew Thompson.Pp 347a5118bdfSAndrew Thompson.Ft void 348390065b1SAlfred Perlstein.Fn libusb_free_config_descriptor "libusb_config_descriptor *config" 349a5118bdfSAndrew ThompsonFree a configuration descriptor. 3504eaae44dSAndrew Thompson.Pp 351a5118bdfSAndrew Thompson.Ft int 35278ed0e49SHans Petter Selasky.Fn libusb_get_string_descriptor "libusb_device_handle *devh" "uint8_t desc_idx" "uint16_t langid" "unsigned char *data" "int length" 35378ed0e49SHans Petter SelaskyRetrieve a string descriptor in raw format. 35478ed0e49SHans Petter SelaskyReturns the number of bytes actually transferred on success 35578ed0e49SHans Petter Selaskyor a negative LIBUSB_ERROR code on failure. 35678ed0e49SHans Petter Selasky.Pp 35778ed0e49SHans Petter Selasky.Ft int 358a5118bdfSAndrew Thompson.Fn libusb_get_string_descriptor_ascii "libusb_device_handle *devh" "uint8_t desc_idx" "unsigned char *data" "int length" 35911867070SHans Petter SelaskyRetrieve a string descriptor in C style ASCII. 36011867070SHans Petter SelaskyReturns the positive number of bytes in the resulting ASCII string 361c8c1f2ecSHans Petter Selaskyon success and a LIBUSB_ERROR code on failure. 3624eaae44dSAndrew Thompson.Pp 3634c0392e6SHans Petter Selasky.Ft int 3644c0392e6SHans Petter Selasky.Fn libusb_parse_ss_endpoint_comp "const void *buf" "int len" "libusb_ss_endpoint_companion_descriptor **ep_comp" 3654c0392e6SHans Petter SelaskyThis function parses the USB 3.0 endpoint companion descriptor in host endian format pointed to by 3664c0392e6SHans Petter Selasky.Fa buf 3674c0392e6SHans Petter Selaskyand having a length of 3684c0392e6SHans Petter Selasky.Fa len . 3694c0392e6SHans Petter SelaskyTypically these arguments are the extra and extra_length fields of the 3704c0392e6SHans Petter Selaskyendpoint descriptor. 3714c0392e6SHans Petter SelaskyOn success the pointer to resulting descriptor is stored at the location given by 3724c0392e6SHans Petter Selasky.Fa ep_comp . 3734c0392e6SHans Petter SelaskyReturns zero on success and a LIBUSB_ERROR code on failure. 3744c0392e6SHans Petter SelaskyOn success the parsed USB 3.0 endpoint companion descriptor must be 3754c0392e6SHans Petter Selaskyfreed using the libusb_free_ss_endpoint_comp function. 3764c0392e6SHans Petter Selasky.Pp 3774c0392e6SHans Petter Selasky.Ft void 3784c0392e6SHans Petter Selasky.Fn libusb_free_ss_endpoint_comp "libusb_ss_endpoint_companion_descriptor *ep_comp" 3794c0392e6SHans Petter SelaskyThis function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor. 3804c0392e6SHans Petter Selasky.Pp 3814c0392e6SHans Petter Selasky.Ft int 3824c0392e6SHans Petter Selasky.Fn libusb_parse_bos_descriptor "const void *buf" "int len" "libusb_bos_descriptor **bos" 3834c0392e6SHans Petter SelaskyThis function parses a Binary Object Store, BOS, descriptor into host endian format pointed to by 3844c0392e6SHans Petter Selasky.Fa buf 3854c0392e6SHans Petter Selaskyand having a length of 3864c0392e6SHans Petter Selasky.Fa len . 3874c0392e6SHans Petter SelaskyOn success the pointer to resulting descriptor is stored at the location given by 3884c0392e6SHans Petter Selasky.Fa bos . 3894c0392e6SHans Petter SelaskyReturns zero on success and a LIBUSB_ERROR code on failure. 3904c0392e6SHans Petter SelaskyOn success the parsed BOS descriptor must be freed using the 3914c0392e6SHans Petter Selaskylibusb_free_bos_descriptor function. 3924c0392e6SHans Petter Selasky.Pp 3934c0392e6SHans Petter Selasky.Ft void 3944c0392e6SHans Petter Selasky.Fn libusb_free_bos_descriptor "libusb_bos_descriptor *bos" 3954c0392e6SHans Petter SelaskyThis function is NULL safe and frees a parsed BOS descriptor. 396a5118bdfSAndrew Thompson.Sh USB ASYNCHRONOUS I/O 397a5118bdfSAndrew Thompson.Ft struct libusb_transfer * 398a5118bdfSAndrew Thompson.Fn libusb_alloc_transfer "int iso_packets" 39911867070SHans Petter SelaskyAllocate a transfer with the number of isochronous packet descriptors 40011867070SHans Petter Selaskyspecified by 40111867070SHans Petter Selasky.Fa iso_packets . 402ca96e26aSHans Petter SelaskyReturns NULL on error. 4034eaae44dSAndrew Thompson.Pp 404a5118bdfSAndrew Thompson.Ft void 405a5118bdfSAndrew Thompson.Fn libusb_free_transfer "struct libusb_transfer *tr" 406a5118bdfSAndrew ThompsonFree a transfer. 4074eaae44dSAndrew Thompson.Pp 408a5118bdfSAndrew Thompson.Ft int 409a5118bdfSAndrew Thompson.Fn libusb_submit_transfer "struct libusb_transfer *tr" 410ca96e26aSHans Petter SelaskyThis function will submit a transfer and returns immediately. 411c8c1f2ecSHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_NO_DEVICE if 41211867070SHans Petter Selaskythe device has been disconnected and a 413a5118bdfSAndrew ThompsonLIBUSB_ERROR code on other failure. 4144eaae44dSAndrew Thompson.Pp 415a5118bdfSAndrew Thompson.Ft int 416a5118bdfSAndrew Thompson.Fn libusb_cancel_transfer "struct libusb_transfer *tr" 41711867070SHans Petter SelaskyThis function asynchronously cancels a transfer. 41811867070SHans Petter SelaskyReturns 0 on success and a LIBUSB_ERROR code on failure. 419a5118bdfSAndrew Thompson.Sh USB SYNCHRONOUS I/O 420a5118bdfSAndrew Thompson.Ft int 421698e791aSHans Petter Selasky.Fn libusb_control_transfer "libusb_device_handle *devh" "uint8_t bmRequestType" "uint8_t bRequest" "uint16_t wValue" "uint16_t wIndex" "unsigned char *data" "uint16_t wLength" "unsigned int timeout" 422ca96e26aSHans Petter SelaskyPerform a USB control transfer. 423ca96e26aSHans Petter SelaskyReturns the actual number of bytes 42411867070SHans Petter Selaskytransferred on success, in the range from and including zero up to and 425c865d740SHans Petter Selaskyincluding 426892f4806SHans Petter Selasky.Fa wLength . 42711867070SHans Petter SelaskyOn error a LIBUSB_ERROR code is returned, for example 42811867070SHans Petter SelaskyLIBUSB_ERROR_TIMEOUT if the transfer timed out, LIBUSB_ERROR_PIPE if the 429c865d740SHans Petter Selaskycontrol request was not supported, LIBUSB_ERROR_NO_DEVICE if the 43011867070SHans Petter Selaskydevice has been disconnected and another LIBUSB_ERROR code on other failures. 43111867070SHans Petter SelaskyThe LIBUSB_ERROR codes are all negative. 4324eaae44dSAndrew Thompson.Pp 433a5118bdfSAndrew Thompson.Ft int 434a5118bdfSAndrew Thompson.Fn libusb_bulk_transfer "struct libusb_device_handle *devh" "unsigned char endpoint" "unsigned char *data" "int length" "int *transferred" "unsigned int timeout" 435892f4806SHans Petter SelaskyPerform an USB bulk transfer. 436892f4806SHans Petter SelaskyA timeout value of zero means no timeout. 437892f4806SHans Petter SelaskyThe timeout value is given in milliseconds. 438892f4806SHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_TIMEOUT 43911867070SHans Petter Selaskyif the transfer timed out, LIBUSB_ERROR_PIPE if the control request was not 440a5118bdfSAndrew Thompsonsupported, LIBUSB_ERROR_OVERFLOW if the device offered more data, 441a5118bdfSAndrew ThompsonLIBUSB_ERROR_NO_DEVICE if the device has been disconnected and 44211867070SHans Petter Selaskya LIBUSB_ERROR code on other failure. 4434eaae44dSAndrew Thompson.Pp 444a5118bdfSAndrew Thompson.Ft int 445a5118bdfSAndrew Thompson.Fn libusb_interrupt_transfer "struct libusb_device_handle *devh" "unsigned char endpoint" "unsigned char *data" "int length" "int *transferred" "unsigned int timeout" 446892f4806SHans Petter SelaskyPerform an USB Interrupt transfer. 447892f4806SHans Petter SelaskyA timeout value of zero means no timeout. 448892f4806SHans Petter SelaskyThe timeout value is given in milliseconds. 449892f4806SHans Petter SelaskyReturns 0 on success, LIBUSB_ERROR_TIMEOUT 45011867070SHans Petter Selaskyif the transfer timed out, LIBUSB_ERROR_PIPE if the control request was not 451a5118bdfSAndrew Thompsonsupported, LIBUSB_ERROR_OVERFLOW if the device offered more data, 452a5118bdfSAndrew ThompsonLIBUSB_ERROR_NO_DEVICE if the device has been disconnected and 45311867070SHans Petter Selaskya LIBUSB_ERROR code on other failure. 454a5118bdfSAndrew Thompson.Sh USB EVENTS 455a5118bdfSAndrew Thompson.Ft int 456a5118bdfSAndrew Thompson.Fn libusb_try_lock_events "libusb_context *ctx" 457ca96e26aSHans Petter SelaskyTry to acquire the event handling lock. 458ca96e26aSHans Petter SelaskyReturns 0 if the lock was obtained and 1 if not. 4594eaae44dSAndrew Thompson.Pp 460a5118bdfSAndrew Thompson.Ft void 461a5118bdfSAndrew Thompson.Fn libusb_lock_events "libusb_context *ctx" 462c8c1f2ecSHans Petter SelaskyAcquire the event handling lock. 463c8c1f2ecSHans Petter SelaskyThis function is blocking. 4644eaae44dSAndrew Thompson.Pp 465a5118bdfSAndrew Thompson.Ft void 466a5118bdfSAndrew Thompson.Fn libusb_unlock_events "libusb_context *ctx" 467c8c1f2ecSHans Petter SelaskyRelease the event handling lock. 468c8c1f2ecSHans Petter SelaskyThis will wake up any thread blocked 46911867070SHans Petter Selaskyon 470d284271aSJoel Dahl.Fn libusb_wait_for_event . 4714eaae44dSAndrew Thompson.Pp 472a5118bdfSAndrew Thompson.Ft int 473a5118bdfSAndrew Thompson.Fn libusb_event_handling_ok "libusb_context *ctx" 474c8c1f2ecSHans Petter SelaskyDetermine if it still OK for this thread to be doing event handling. 475c8c1f2ecSHans Petter SelaskyReturns 1 476c8c1f2ecSHans Petter Selaskyif event handling can start or continue. 477c8c1f2ecSHans Petter SelaskyReturns 0 if this thread must give up 478a5118bdfSAndrew Thompsonthe events lock. 4794eaae44dSAndrew Thompson.Pp 480a5118bdfSAndrew Thompson.Ft int 481a5118bdfSAndrew Thompson.Fn libusb_event_handler_active "libusb_context *ctx" 482c8c1f2ecSHans Petter SelaskyDetermine if an active thread is handling events. 48311867070SHans Petter SelaskyReturns 1 if there is a thread handling events and 0 if there 484a5118bdfSAndrew Thompsonare no threads currently handling events. 4854eaae44dSAndrew Thompson.Pp 486a5118bdfSAndrew Thompson.Ft void 487a5118bdfSAndrew Thompson.Fn libusb_lock_event_waiters "libusb_context *ctx" 488c8c1f2ecSHans Petter SelaskyAcquire the event_waiters lock. 48911867070SHans Petter SelaskyThis lock is designed to be obtained in the 490a5118bdfSAndrew Thompsonsituation where you want to be aware when events are completed, but some other 491a5118bdfSAndrew Thompsonthread is event handling so calling libusb_handle_events() is not allowed. 492545b01adSAndrew Thompson.Pp 493a5118bdfSAndrew Thompson.Ft void 494a5118bdfSAndrew Thompson.Fn libusb_unlock_event_waiters "libusb_context *ctx" 495a5118bdfSAndrew ThompsonRelease the event_waiters lock. 4964eaae44dSAndrew Thompson.Pp 497a5118bdfSAndrew Thompson.Ft int 498a5118bdfSAndrew Thompson.Fn libusb_wait_for_event "libusb_context *ctx" "struct timeval *tv" 499c8c1f2ecSHans Petter SelaskyWait for another thread to signal completion of an event. 500c8c1f2ecSHans Petter SelaskyMust be called 501c8c1f2ecSHans Petter Selaskywith the event waiters lock held, see libusb_lock_event_waiters(). 502c8c1f2ecSHans Petter SelaskyThis will 503a5118bdfSAndrew Thompsonblock until the timeout expires or a transfer completes or a thread releases 504c8c1f2ecSHans Petter Selaskythe event handling lock through libusb_unlock_events(). 505c8c1f2ecSHans Petter SelaskyReturns 0 after a 50611867070SHans Petter Selaskytransfer completes or another thread stops event handling, and 1 if the 507a5118bdfSAndrew Thompsontimeout expired. 5084eaae44dSAndrew Thompson.Pp 509a5118bdfSAndrew Thompson.Ft int 51003205428SHans Petter Selasky.Fn libusb_handle_events_timeout_completed "libusb_context *ctx" "struct timeval *tv" "int *completed" 51103205428SHans Petter SelaskyHandle any pending events by checking if timeouts have expired and by 51203205428SHans Petter Selaskychecking the set of file descriptors for activity. 51303205428SHans Petter SelaskyIf the 51403205428SHans Petter Selasky.Fa completed 51503205428SHans Petter Selaskyargument is not equal to NULL, this function will 51603205428SHans Petter Selaskyloop until a transfer completion callback sets the variable pointed to 51703205428SHans Petter Selaskyby the 51803205428SHans Petter Selasky.Fa completed 51903205428SHans Petter Selaskyargument to non-zero. 52003205428SHans Petter SelaskyIf the 52103205428SHans Petter Selasky.Fa tv 52203205428SHans Petter Selaskyargument is not equal to NULL, this function will return 52303205428SHans Petter SelaskyLIBUSB_ERROR_TIMEOUT after the given timeout. 52403205428SHans Petter SelaskyReturns 0 on success, or a LIBUSB_ERROR code on failure or timeout. 52503205428SHans Petter Selasky.Pp 52603205428SHans Petter Selasky.Ft int 52703205428SHans Petter Selasky.Fn libusb_handle_events_completed "libusb_context *ctx" "int *completed" 52803205428SHans Petter SelaskyHandle any pending events by checking the set of file descriptors for activity. 52903205428SHans Petter SelaskyIf the 53003205428SHans Petter Selasky.Fa completed 53103205428SHans Petter Selaskyargument is not equal to NULL, this function will 53203205428SHans Petter Selaskyloop until a transfer completion callback sets the variable pointed to 53303205428SHans Petter Selaskyby the 53403205428SHans Petter Selasky.Fa completed 53503205428SHans Petter Selaskyargument to non-zero. 53603205428SHans Petter SelaskyReturns 0 on success, or a LIBUSB_ERROR code on failure. 53703205428SHans Petter Selasky.Pp 53803205428SHans Petter Selasky.Ft int 539a5118bdfSAndrew Thompson.Fn libusb_handle_events_timeout "libusb_context *ctx" "struct timeval *tv" 540a5118bdfSAndrew ThompsonHandle any pending events by checking if timeouts have expired and by 541c8c1f2ecSHans Petter Selaskychecking the set of file descriptors for activity. 542c8c1f2ecSHans Petter SelaskyReturns 0 on success, or a 54303205428SHans Petter SelaskyLIBUSB_ERROR code on failure or timeout. 5444eaae44dSAndrew Thompson.Pp 545a5118bdfSAndrew Thompson.Ft int 546a5118bdfSAndrew Thompson.Fn libusb_handle_events "libusb_context *ctx" 547c8c1f2ecSHans Petter SelaskyHandle any pending events in blocking mode with a sensible timeout. 548c8c1f2ecSHans Petter SelaskyReturns 0 54911867070SHans Petter Selaskyon success and a LIBUSB_ERROR code on failure. 5504eaae44dSAndrew Thompson.Pp 551a5118bdfSAndrew Thompson.Ft int 552a5118bdfSAndrew Thompson.Fn libusb_handle_events_locked "libusb_context *ctx" "struct timeval *tv" 5533102cfe2SGlen BarberHandle any pending events by polling file descriptors, without checking if 55411867070SHans Petter Selaskyanother thread is already doing so. 555c8c1f2ecSHans Petter SelaskyMust be called with the event lock held. 5564eaae44dSAndrew Thompson.Pp 557a5118bdfSAndrew Thompson.Ft int 558a5118bdfSAndrew Thompson.Fn libusb_get_next_timeout "libusb_context *ctx" "struct timeval *tv" 559c8c1f2ecSHans Petter SelaskyDetermine the next internal timeout that libusb needs to handle. 560c8c1f2ecSHans Petter SelaskyReturns 0 56111867070SHans Petter Selaskyif there are no pending timeouts, 1 if a timeout was returned, or a LIBUSB_ERROR 56203205428SHans Petter Selaskycode on failure or timeout. 5634eaae44dSAndrew Thompson.Pp 564a5118bdfSAndrew Thompson.Ft void 565a5118bdfSAndrew Thompson.Fn libusb_set_pollfd_notifiers "libusb_context *ctx" "libusb_pollfd_added_cb added_cb" "libusb_pollfd_removed_cb remove_cb" "void *user_data" 566a5118bdfSAndrew ThompsonRegister notification functions for file descriptor additions/removals. 567a5118bdfSAndrew ThompsonThese functions will be invoked for every new or removed file descriptor 568a5118bdfSAndrew Thompsonthat libusb uses as an event source. 5694eaae44dSAndrew Thompson.Pp 570a5118bdfSAndrew Thompson.Ft const struct libusb_pollfd ** 571a5118bdfSAndrew Thompson.Fn libusb_get_pollfds "libusb_context *ctx" 572a5118bdfSAndrew ThompsonRetrive a list of file descriptors that should be polled by your main loop as 573c8c1f2ecSHans Petter Selaskylibusb event sources. 574c8c1f2ecSHans Petter SelaskyReturns a NULL-terminated list on success or NULL on failure. 5754eaae44dSAndrew Thompson.Sh LIBUSB VERSION 0.1 COMPATIBILITY 576a5118bdfSAndrew ThompsonThe library is also compliant with LibUSB version 0.1.12. 577a5118bdfSAndrew Thompson.Pp 5784eaae44dSAndrew Thompson.Fn usb_open 5794eaae44dSAndrew Thompson.Fn usb_close 5804eaae44dSAndrew Thompson.Fn usb_get_string 5814eaae44dSAndrew Thompson.Fn usb_get_string_simple 5824eaae44dSAndrew Thompson.Fn usb_get_descriptor_by_endpoint 5834eaae44dSAndrew Thompson.Fn usb_get_descriptor 5844eaae44dSAndrew Thompson.Fn usb_parse_descriptor 5854eaae44dSAndrew Thompson.Fn usb_parse_configuration 5864eaae44dSAndrew Thompson.Fn usb_destroy_configuration 5874eaae44dSAndrew Thompson.Fn usb_fetch_and_parse_descriptors 5884eaae44dSAndrew Thompson.Fn usb_bulk_write 5894eaae44dSAndrew Thompson.Fn usb_bulk_read 5904eaae44dSAndrew Thompson.Fn usb_interrupt_write 5914eaae44dSAndrew Thompson.Fn usb_interrupt_read 5924eaae44dSAndrew Thompson.Fn usb_control_msg 5934eaae44dSAndrew Thompson.Fn usb_set_configuration 5944eaae44dSAndrew Thompson.Fn usb_claim_interface 5954eaae44dSAndrew Thompson.Fn usb_release_interface 5964eaae44dSAndrew Thompson.Fn usb_set_altinterface 5974eaae44dSAndrew Thompson.Fn usb_resetep 5984eaae44dSAndrew Thompson.Fn usb_clear_halt 5994eaae44dSAndrew Thompson.Fn usb_reset 6004eaae44dSAndrew Thompson.Fn usb_strerror 6014eaae44dSAndrew Thompson.Fn usb_init 6024eaae44dSAndrew Thompson.Fn usb_set_debug 6034eaae44dSAndrew Thompson.Fn usb_find_busses 6044eaae44dSAndrew Thompson.Fn usb_find_devices 6054eaae44dSAndrew Thompson.Fn usb_device 6064eaae44dSAndrew Thompson.Fn usb_get_busses 607f1b5fa6eSHans Petter Selasky.Fn usb_check_connected 6084eb5923dSHans Petter Selasky.Fn usb_get_driver_np 6094eb5923dSHans Petter Selasky.Fn usb_detach_kernel_driver_np 6104eaae44dSAndrew Thompson.Sh SEE ALSO 611a5118bdfSAndrew Thompson.Xr libusb20 3 , 612c54c1f7cSAndrew Thompson.Xr usb 4 , 613c61f2561SHans Petter Selasky.Xr usbconfig 8 , 614c61f2561SHans Petter Selasky.Xr usbdump 8 615a5118bdfSAndrew Thompson.Pp 616a5118bdfSAndrew Thompson.Pa http://libusb.sourceforge.net/ 6174eaae44dSAndrew Thompson.Sh HISTORY 6184eaae44dSAndrew Thompson.Nm 619a5118bdfSAndrew Thompsonsupport first appeared in 620a5118bdfSAndrew Thompson.Fx 8.0 . 621