?? core.c
字號:
/* * Core functions for libusb * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org> * Copyright (c) 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 <poll.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include "libusb.h"#include "libusbi.h"#ifdef OS_LINUXconst struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend;#else#error "Unsupported OS"#endifstruct libusb_context *usbi_default_context = NULL;static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER;/** * \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.sourceforge.net">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://sourceforge.net/mail/?group_id=1674">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 2.0 * Specification</a> which is available for free download. You can probably * find less verbose introductions by searching the web. * * \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 * * \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 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 misc "miscellaneous" documentation page. * * \section msglog Debug message logging * * libusb does not log any messages by default. Your application is therefore * free to close stdout/stderr and those descriptors may be reused without * worry. * * The libusb_set_debug() function can be used to enable stdout/stderr logging * of certain messages. Under standard configuration, libusb doesn't really * log much at all, so you are advised to use this function to enable all * error/warning/informational messages. It will help you debug problems with * your software. * * The LIBUSB_DEBUG environment variable can be used to enable message logging * at run-time. This environment variable should be set to a number, which is * interpreted the same as the libusb_set_debug() parameter. When this * environment variable is set, the message logging verbosity level is fixed * and libusb_set_debug() effectively does nothing. * * libusb can be compiled without any logging functions, useful for embedded * systems. In this case, libusb_set_debug() and the LIBUSB_DEBUG environment * variable have no effects. * * libusb can also be compiled with verbose debugging messages. When the * library is compiled in this way, all messages of all verbosities are always * logged. libusb_set_debug() and the LIBUSB_DEBUG environment variable have * no effects. * * \section remarks Other remarks * * libusb does have imperfections. The \ref caveats "caveats" page attempts * to document these. *//** * \page caveats Caveats * * \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 nohotplug No hotplugging * * libusb-1.0 lacks functionality for providing notifications of when devices * are added or removed. This functionality is planned to be implemented * for libusb-1.1. * * That said, there is basic disconnection handling for open device handles: * - If there are ongoing transfers, libusb's handle_events loop will detect * disconnections and complete ongoing transfers with the * LIBUSB_TRANSFER_NO_DEVICE status code. * - Many functions such as libusb_set_configuration() return the special * LIBUSB_ERROR_NO_DEVICE error code when the device has been disconnected. * * \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. * -# libusb will be unable to change configuration if the device is in * another configuration and other programs or drivers have claimed * interfaces under that configuration. * -# In the case where the desired configuration is already active, libusb * 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.) * * 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:\codecfg = libusb_get_configuration(dev);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. *//** * \page 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_debug() 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(). * * 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. *//** * @defgroup 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 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 deviceslibusb_device **list;libusb_device *found = NULL;size_t cnt = libusb_get_device_list(NULL, &list);size_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 * it's 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 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 8static 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;}/* 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; /* 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; discdevs = realloc(discdevs, sizeof(*discdevs) + (sizeof(void *) * capacity)); if (discdevs) { discdevs->capacity = capacity; discdevs->devices[len] = libusb_ref_device(dev); discdevs->len++; } return discdevs;}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);}/* 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 = malloc(sizeof(*dev) + priv_size); int r; if (!dev)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -