| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | |
| "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | |
| <book id="Linux-USB-API"> | |
| <bookinfo> | |
| <title>The Linux-USB Host Side API</title> | |
| <legalnotice> | |
| <para> | |
| This documentation is free software; you can redistribute | |
| it and/or modify it under the terms of the GNU General Public | |
| License as published by the Free Software Foundation; either | |
| version 2 of the License, or (at your option) any later | |
| version. | |
| </para> | |
| <para> | |
| This program is distributed in the hope that it will be | |
| useful, but WITHOUT ANY WARRANTY; without even the implied | |
| warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| See the GNU General Public License for more details. | |
| </para> | |
| <para> | |
| You should have received a copy of the GNU General Public | |
| License along with this program; if not, write to the Free | |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
| MA 02111-1307 USA | |
| </para> | |
| <para> | |
| For more details see the file COPYING in the source | |
| distribution of Linux. | |
| </para> | |
| </legalnotice> | |
| </bookinfo> | |
| <toc></toc> | |
| <chapter id="intro"> | |
| <title>Introduction to USB on Linux</title> | |
| <para>A Universal Serial Bus (USB) is used to connect a host, | |
| such as a PC or workstation, to a number of peripheral | |
| devices. USB uses a tree structure, with the host at the | |
| root (the system's master), hubs as interior nodes, and | |
| peripheral devices as leaves (and slaves). | |
| Modern PCs support several such trees of USB devices, usually | |
| one USB 2.0 tree (480 Mbit/sec each) with | |
| a few USB 1.1 trees (12 Mbit/sec each) that are used when you | |
| connect a USB 1.1 device directly to the machine's "root hub". | |
| </para> | |
| <para>That master/slave asymmetry was designed in part for | |
| ease of use. It is not physically possible to assemble | |
| (legal) USB cables incorrectly: all upstream "to-the-host" | |
| connectors are the rectangular type, matching the sockets on | |
| root hubs, and the downstream type are the squarish type | |
| (or they are built in to the peripheral). | |
| Software doesn't need to deal with distributed autoconfiguration | |
| since the pre-designated master node manages all that. | |
| At the electrical level, bus protocol overhead is reduced by | |
| eliminating arbitration and moving scheduling into host software. | |
| </para> | |
| <para>USB 1.0 was announced in January 1996, and was revised | |
| as USB 1.1 (with improvements in hub specification and | |
| support for interrupt-out transfers) in September 1998. | |
| USB 2.0 was released in April 2000, including high speed | |
| transfers and transaction translating hubs (used for USB 1.1 | |
| and 1.0 backward compatibility). | |
| </para> | |
| <para>USB support was added to Linux early in the 2.2 kernel series | |
| shortly before the 2.3 development forked off. Updates | |
| from 2.3 were regularly folded back into 2.2 releases, bringing | |
| new features such as <filename>/sbin/hotplug</filename> support, | |
| more drivers, and more robustness. | |
| The 2.5 kernel series continued such improvements, and also | |
| worked on USB 2.0 support, | |
| higher performance, | |
| better consistency between host controller drivers, | |
| API simplification (to make bugs less likely), | |
| and providing internal "kerneldoc" documentation. | |
| </para> | |
| <para>Linux can run inside USB devices as well as on | |
| the hosts that control the devices. | |
| Because the Linux 2.x USB support evolved to support mass market | |
| platforms such as Apple Macintosh or PC-compatible systems, | |
| it didn't address design concerns for those types of USB systems. | |
| So it can't be used inside mass-market PDAs, or other peripherals. | |
| USB device drivers running inside those Linux peripherals | |
| don't do the same things as the ones running inside hosts, | |
| and so they've been given a different name: | |
| they're called <emphasis>gadget drivers</emphasis>. | |
| This document does not present gadget drivers. | |
| </para> | |
| </chapter> | |
| <chapter id="host"> | |
| <title>USB Host-Side API Model</title> | |
| <para>Within the kernel, | |
| host-side drivers for USB devices talk to the "usbcore" APIs. | |
| There are two types of public "usbcore" APIs, targetted at two different | |
| layers of USB driver. Those are | |
| <emphasis>general purpose</emphasis> drivers, exposed through | |
| driver frameworks such as block, character, or network devices; | |
| and drivers that are <emphasis>part of the core</emphasis>, | |
| which are involved in managing a USB bus. | |
| Such core drivers include the <emphasis>hub</emphasis> driver, | |
| which manages trees of USB devices, and several different kinds | |
| of <emphasis>host controller driver (HCD)</emphasis>, | |
| which control individual busses. | |
| </para> | |
| <para>The device model seen by USB drivers is relatively complex. | |
| </para> | |
| <itemizedlist> | |
| <listitem><para>USB supports four kinds of data transfer | |
| (control, bulk, interrupt, and isochronous). Two transfer | |
| types use bandwidth as it's available (control and bulk), | |
| while the other two types of transfer (interrupt and isochronous) | |
| are scheduled to provide guaranteed bandwidth. | |
| </para></listitem> | |
| <listitem><para>The device description model includes one or more | |
| "configurations" per device, only one of which is active at a time. | |
| Devices that are capable of high speed operation must also support | |
| full speed configurations, along with a way to ask about the | |
| "other speed" configurations that might be used. | |
| </para></listitem> | |
| <listitem><para>Configurations have one or more "interface", each | |
| of which may have "alternate settings". Interfaces may be | |
| standardized by USB "Class" specifications, or may be specific to | |
| a vendor or device.</para> | |
| <para>USB device drivers actually bind to interfaces, not devices. | |
| Think of them as "interface drivers", though you | |
| may not see many devices where the distinction is important. | |
| <emphasis>Most USB devices are simple, with only one configuration, | |
| one interface, and one alternate setting.</emphasis> | |
| </para></listitem> | |
| <listitem><para>Interfaces have one or more "endpoints", each of | |
| which supports one type and direction of data transfer such as | |
| "bulk out" or "interrupt in". The entire configuration may have | |
| up to sixteen endpoints in each direction, allocated as needed | |
| among all the interfaces. | |
| </para></listitem> | |
| <listitem><para>Data transfer on USB is packetized; each endpoint | |
| has a maximum packet size. | |
| Drivers must often be aware of conventions such as flagging the end | |
| of bulk transfers using "short" (including zero length) packets. | |
| </para></listitem> | |
| <listitem><para>The Linux USB API supports synchronous calls for | |
| control and bulk messaging. | |
| It also supports asynchnous calls for all kinds of data transfer, | |
| using request structures called "URBs" (USB Request Blocks). | |
| </para></listitem> | |
| </itemizedlist> | |
| <para>Accordingly, the USB Core API exposed to device drivers | |
| covers quite a lot of territory. You'll probably need to consult | |
| the USB 2.0 specification, available online from www.usb.org at | |
| no cost, as well as class or device specifications. | |
| </para> | |
| <para>The only host-side drivers that actually touch hardware | |
| (reading/writing registers, handling IRQs, and so on) are the HCDs. | |
| In theory, all HCDs provide the same functionality through the same | |
| API. In practice, that's becoming more true on the 2.5 kernels, | |
| but there are still differences that crop up especially with | |
| fault handling. Different controllers don't necessarily report | |
| the same aspects of failures, and recovery from faults (including | |
| software-induced ones like unlinking an URB) isn't yet fully | |
| consistent. | |
| Device driver authors should make a point of doing disconnect | |
| testing (while the device is active) with each different host | |
| controller driver, to make sure drivers don't have bugs of | |
| their own as well as to make sure they aren't relying on some | |
| HCD-specific behavior. | |
| (You will need external USB 1.1 and/or | |
| USB 2.0 hubs to perform all those tests.) | |
| </para> | |
| </chapter> | |
| <chapter><title>USB-Standard Types</title> | |
| <para>In <filename><linux/usb_ch9.h></filename> you will find | |
| the USB data types defined in chapter 9 of the USB specification. | |
| These data types are used throughout USB, and in APIs including | |
| this host side API, gadget APIs, and usbfs. | |
| </para> | |
| !Iinclude/linux/usb_ch9.h | |
| </chapter> | |
| <chapter><title>Host-Side Data Types and Macros</title> | |
| <para>The host side API exposes several layers to drivers, some of | |
| which are more necessary than others. | |
| These support lifecycle models for host side drivers | |
| and devices, and support passing buffers through usbcore to | |
| some HCD that performs the I/O for the device driver. | |
| </para> | |
| !Iinclude/linux/usb.h | |
| </chapter> | |
| <chapter><title>USB Core APIs</title> | |
| <para>There are two basic I/O models in the USB API. | |
| The most elemental one is asynchronous: drivers submit requests | |
| in the form of an URB, and the URB's completion callback | |
| handle the next step. | |
| All USB transfer types support that model, although there | |
| are special cases for control URBs (which always have setup | |
| and status stages, but may not have a data stage) and | |
| isochronous URBs (which allow large packets and include | |
| per-packet fault reports). | |
| Built on top of that is synchronous API support, where a | |
| driver calls a routine that allocates one or more URBs, | |
| submits them, and waits until they complete. | |
| There are synchronous wrappers for single-buffer control | |
| and bulk transfers (which are awkward to use in some | |
| driver disconnect scenarios), and for scatterlist based | |
| streaming i/o (bulk or interrupt). | |
| </para> | |
| <para>USB drivers need to provide buffers that can be | |
| used for DMA, although they don't necessarily need to | |
| provide the DMA mapping themselves. | |
| There are APIs to use used when allocating DMA buffers, | |
| which can prevent use of bounce buffers on some systems. | |
| In some cases, drivers may be able to rely on 64bit DMA | |
| to eliminate another kind of bounce buffer. | |
| </para> | |
| !Edrivers/usb/core/urb.c | |
| !Edrivers/usb/core/message.c | |
| !Edrivers/usb/core/file.c | |
| !Edrivers/usb/core/usb.c | |
| !Edrivers/usb/core/hub.c | |
| </chapter> | |
| <chapter><title>Host Controller APIs</title> | |
| <para>These APIs are only for use by host controller drivers, | |
| most of which implement standard register interfaces such as | |
| EHCI, OHCI, or UHCI. | |
| UHCI was one of the first interfaces, designed by Intel and | |
| also used by VIA; it doesn't do much in hardware. | |
| OHCI was designed later, to have the hardware do more work | |
| (bigger transfers, tracking protocol state, and so on). | |
| EHCI was designed with USB 2.0; its design has features that | |
| resemble OHCI (hardware does much more work) as well as | |
| UHCI (some parts of ISO support, TD list processing). | |
| </para> | |
| <para>There are host controllers other than the "big three", | |
| although most PCI based controllers (and a few non-PCI based | |
| ones) use one of those interfaces. | |
| Not all host controllers use DMA; some use PIO, and there | |
| is also a simulator. | |
| </para> | |
| <para>The same basic APIs are available to drivers for all | |
| those controllers. | |
| For historical reasons they are in two layers: | |
| <structname>struct usb_bus</structname> is a rather thin | |
| layer that became available in the 2.2 kernels, while | |
| <structname>struct usb_hcd</structname> is a more featureful | |
| layer (available in later 2.4 kernels and in 2.5) that | |
| lets HCDs share common code, to shrink driver size | |
| and significantly reduce hcd-specific behaviors. | |
| </para> | |
| !Edrivers/usb/core/hcd.c | |
| !Edrivers/usb/core/hcd-pci.c | |
| !Edrivers/usb/core/buffer.c | |
| </chapter> | |
| <chapter> | |
| <title>The USB Filesystem (usbfs)</title> | |
| <para>This chapter presents the Linux <emphasis>usbfs</emphasis>. | |
| You may prefer to avoid writing new kernel code for your | |
| USB driver; that's the problem that usbfs set out to solve. | |
| User mode device drivers are usually packaged as applications | |
| or libraries, and may use usbfs through some programming library | |
| that wraps it. Such libraries include | |
| <ulink url="http://libusb.sourceforge.net">libusb</ulink> | |
| for C/C++, and | |
| <ulink url="http://jUSB.sourceforge.net">jUSB</ulink> for Java. | |
| </para> | |
| <note><title>Unfinished</title> | |
| <para>This particular documentation is incomplete, | |
| especially with respect to the asynchronous mode. | |
| As of kernel 2.5.66 the code and this (new) documentation | |
| need to be cross-reviewed. | |
| </para> | |
| </note> | |
| <para>Configure usbfs into Linux kernels by enabling the | |
| <emphasis>USB filesystem</emphasis> option (CONFIG_USB_DEVICEFS), | |
| and you get basic support for user mode USB device drivers. | |
| Until relatively recently it was often (confusingly) called | |
| <emphasis>usbdevfs</emphasis> although it wasn't solving what | |
| <emphasis>devfs</emphasis> was. | |
| Every USB device will appear in usbfs, regardless of whether or | |
| not it has a kernel driver; but only devices with kernel drivers | |
| show up in devfs. | |
| </para> | |
| <sect1> | |
| <title>What files are in "usbfs"?</title> | |
| <para>Conventionally mounted at | |
| <filename>/proc/bus/usb</filename>, usbfs | |
| features include: | |
| <itemizedlist> | |
| <listitem><para><filename>/proc/bus/usb/devices</filename> | |
| ... a text file | |
| showing each of the USB devices on known to the kernel, | |
| and their configuration descriptors. | |
| You can also poll() this to learn about new devices. | |
| </para></listitem> | |
| <listitem><para><filename>/proc/bus/usb/BBB/DDD</filename> | |
| ... magic files | |
| exposing the each device's configuration descriptors, and | |
| supporting a series of ioctls for making device requests, | |
| including I/O to devices. (Purely for access by programs.) | |
| </para></listitem> | |
| </itemizedlist> | |
| </para> | |
| <para> Each bus is given a number (BBB) based on when it was | |
| enumerated; within each bus, each device is given a similar | |
| number (DDD). | |
| Those BBB/DDD paths are not "stable" identifiers; | |
| expect them to change even if you always leave the devices | |
| plugged in to the same hub port. | |
| <emphasis>Don't even think of saving these in application | |
| configuration files.</emphasis> | |
| Stable identifiers are available, for user mode applications | |
| that want to use them. HID and networking devices expose | |
| these stable IDs, so that for example you can be sure that | |
| you told the right UPS to power down its second server. | |
| "usbfs" doesn't (yet) expose those IDs. | |
| </para> | |
| </sect1> | |
| <sect1> | |
| <title>Mounting and Access Control</title> | |
| <para>There are a number of mount options for usbfs, which will | |
| be of most interest to you if you need to override the default | |
| access control policy. | |
| That policy is that only root may read or write device files | |
| (<filename>/proc/bus/BBB/DDD</filename>) although anyone may read | |
| the <filename>devices</filename> | |
| or <filename>drivers</filename> files. | |
| I/O requests to the device also need the CAP_SYS_RAWIO capability, | |
| </para> | |
| <para>The significance of that is that by default, all user mode | |
| device drivers need super-user privileges. | |
| You can change modes or ownership in a driver setup | |
| when the device hotplugs, or maye just start the | |
| driver right then, as a privileged server (or some activity | |
| within one). | |
| That's the most secure approach for multi-user systems, | |
| but for single user systems ("trusted" by that user) | |
| it's more convenient just to grant everyone all access | |
| (using the <emphasis>devmode=0666</emphasis> option) | |
| so the driver can start whenever it's needed. | |
| </para> | |
| <para>The mount options for usbfs, usable in /etc/fstab or | |
| in command line invocations of <emphasis>mount</emphasis>, are: | |
| <variablelist> | |
| <varlistentry> | |
| <term><emphasis>busgid</emphasis>=NNNNN</term> | |
| <listitem><para>Controls the GID used for the | |
| /proc/bus/usb/BBB | |
| directories. (Default: 0)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>busmode</emphasis>=MMM</term> | |
| <listitem><para>Controls the file mode used for the | |
| /proc/bus/usb/BBB | |
| directories. (Default: 0555) | |
| </para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>busuid</emphasis>=NNNNN</term> | |
| <listitem><para>Controls the UID used for the | |
| /proc/bus/usb/BBB | |
| directories. (Default: 0)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>devgid</emphasis>=NNNNN</term> | |
| <listitem><para>Controls the GID used for the | |
| /proc/bus/usb/BBB/DDD | |
| files. (Default: 0)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>devmode</emphasis>=MMM</term> | |
| <listitem><para>Controls the file mode used for the | |
| /proc/bus/usb/BBB/DDD | |
| files. (Default: 0644)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>devuid</emphasis>=NNNNN</term> | |
| <listitem><para>Controls the UID used for the | |
| /proc/bus/usb/BBB/DDD | |
| files. (Default: 0)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>listgid</emphasis>=NNNNN</term> | |
| <listitem><para>Controls the GID used for the | |
| /proc/bus/usb/devices and drivers files. | |
| (Default: 0)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>listmode</emphasis>=MMM</term> | |
| <listitem><para>Controls the file mode used for the | |
| /proc/bus/usb/devices and drivers files. | |
| (Default: 0444)</para></listitem></varlistentry> | |
| <varlistentry><term><emphasis>listuid</emphasis>=NNNNN</term> | |
| <listitem><para>Controls the UID used for the | |
| /proc/bus/usb/devices and drivers files. | |
| (Default: 0)</para></listitem></varlistentry> | |
| </variablelist> | |
| </para> | |
| <para>Note that many Linux distributions hard-wire the mount options | |
| for usbfs in their init scripts, such as | |
| <filename>/etc/rc.d/rc.sysinit</filename>, | |
| rather than making it easy to set this per-system | |
| policy in <filename>/etc/fstab</filename>. | |
| </para> | |
| </sect1> | |
| <sect1> | |
| <title>/proc/bus/usb/devices</title> | |
| <para>This file is handy for status viewing tools in user | |
| mode, which can scan the text format and ignore most of it. | |
| More detailed device status (including class and vendor | |
| status) is available from device-specific files. | |
| For information about the current format of this file, | |
| see the | |
| <filename>Documentation/usb/proc_usb_info.txt</filename> | |
| file in your Linux kernel sources. | |
| </para> | |
| <para>Otherwise the main use for this file from programs | |
| is to poll() it to get notifications of usb devices | |
| as they're plugged or unplugged. | |
| To see what changed, you'd need to read the file and | |
| compare "before" and "after" contents, scan the filesystem, | |
| or see its hotplug event. | |
| </para> | |
| </sect1> | |
| <sect1> | |
| <title>/proc/bus/usb/BBB/DDD</title> | |
| <para>Use these files in one of these basic ways: | |
| </para> | |
| <para><emphasis>They can be read,</emphasis> | |
| producing first the device descriptor | |
| (18 bytes) and then the descriptors for the current configuration. | |
| See the USB 2.0 spec for details about those binary data formats. | |
| You'll need to convert most multibyte values from little endian | |
| format to your native host byte order, although a few of the | |
| fields in the device descriptor (both of the BCD-encoded fields, | |
| and the vendor and product IDs) will be byteswapped for you. | |
| Note that configuration descriptors include descriptors for | |
| interfaces, altsettings, endpoints, and maybe additional | |
| class descriptors. | |
| </para> | |
| <para><emphasis>Perform USB operations</emphasis> using | |
| <emphasis>ioctl()</emphasis> requests to make endpoint I/O | |
| requests (synchronously or asynchronously) or manage | |
| the device. | |
| These requests need the CAP_SYS_RAWIO capability, | |
| as well as filesystem access permissions. | |
| Only one ioctl request can be made on one of these | |
| device files at a time. | |
| This means that if you are synchronously reading an endpoint | |
| from one thread, you won't be able to write to a different | |
| endpoint from another thread until the read completes. | |
| This works for <emphasis>half duplex</emphasis> protocols, | |
| but otherwise you'd use asynchronous i/o requests. | |
| </para> | |
| </sect1> | |
| <sect1> | |
| <title>Life Cycle of User Mode Drivers</title> | |
| <para>Such a driver first needs to find a device file | |
| for a device it knows how to handle. | |
| Maybe it was told about it because a | |
| <filename>/sbin/hotplug</filename> event handling agent | |
| chose that driver to handle the new device. | |
| Or maybe it's an application that scans all the | |
| /proc/bus/usb device files, and ignores most devices. | |
| In either case, it should <function>read()</function> all | |
| the descriptors from the device file, | |
| and check them against what it knows how to handle. | |
| It might just reject everything except a particular | |
| vendor and product ID, or need a more complex policy. | |
| </para> | |
| <para>Never assume there will only be one such device | |
| on the system at a time! | |
| If your code can't handle more than one device at | |
| a time, at least detect when there's more than one, and | |
| have your users choose which device to use. | |
| </para> | |
| <para>Once your user mode driver knows what device to use, | |
| it interacts with it in either of two styles. | |
| The simple style is to make only control requests; some | |
| devices don't need more complex interactions than those. | |
| (An example might be software using vendor-specific control | |
| requests for some initialization or configuration tasks, | |
| with a kernel driver for the rest.) | |
| </para> | |
| <para>More likely, you need a more complex style driver: | |
| one using non-control endpoints, reading or writing data | |
| and claiming exclusive use of an interface. | |
| <emphasis>Bulk</emphasis> transfers are easiest to use, | |
| but only their sibling <emphasis>interrupt</emphasis> transfers | |
| work with low speed devices. | |
| Both interrupt and <emphasis>isochronous</emphasis> transfers | |
| offer service guarantees because their bandwidth is reserved. | |
| Such "periodic" transfers are awkward to use through usbfs, | |
| unless you're using the asynchronous calls. However, interrupt | |
| transfers can also be used in a synchronous "one shot" style. | |
| </para> | |
| <para>Your user-mode driver should never need to worry | |
| about cleaning up request state when the device is | |
| disconnected, although it should close its open file | |
| descriptors as soon as it starts seeing the ENODEV | |
| errors. | |
| </para> | |
| </sect1> | |
| <sect1><title>The ioctl() Requests</title> | |
| <para>To use these ioctls, you need to include the following | |
| headers in your userspace program: | |
| <programlisting>#include <linux/usb.h> | |
| #include <linux/usbdevice_fs.h> | |
| #include <asm/byteorder.h></programlisting> | |
| The standard USB device model requests, from "Chapter 9" of | |
| the USB 2.0 specification, are automatically included from | |
| the <filename><linux/usb_ch9.h></filename> header. | |
| </para> | |
| <para>Unless noted otherwise, the ioctl requests | |
| described here will | |
| update the modification time on the usbfs file to which | |
| they are applied (unless they fail). | |
| A return of zero indicates success; otherwise, a | |
| standard USB error code is returned. (These are | |
| documented in | |
| <filename>Documentation/usb/error-codes.txt</filename> | |
| in your kernel sources.) | |
| </para> | |
| <para>Each of these files multiplexes access to several | |
| I/O streams, one per endpoint. | |
| Each device has one control endpoint (endpoint zero) | |
| which supports a limited RPC style RPC access. | |
| Devices are configured | |
| by khubd (in the kernel) setting a device-wide | |
| <emphasis>configuration</emphasis> that affects things | |
| like power consumption and basic functionality. | |
| The endpoints are part of USB <emphasis>interfaces</emphasis>, | |
| which may have <emphasis>altsettings</emphasis> | |
| affecting things like which endpoints are available. | |
| Many devices only have a single configuration and interface, | |
| so drivers for them will ignore configurations and altsettings. | |
| </para> | |
| <sect2> | |
| <title>Management/Status Requests</title> | |
| <para>A number of usbfs requests don't deal very directly | |
| with device I/O. | |
| They mostly relate to device management and status. | |
| These are all synchronous requests. | |
| </para> | |
| <variablelist> | |
| <varlistentry><term>USBDEVFS_CLAIMINTERFACE</term> | |
| <listitem><para>This is used to force usbfs to | |
| claim a specific interface, | |
| which has not previously been claimed by usbfs or any other | |
| kernel driver. | |
| The ioctl parameter is an integer holding the number of | |
| the interface (bInterfaceNumber from descriptor). | |
| </para><para> | |
| Note that if your driver doesn't claim an interface | |
| before trying to use one of its endpoints, and no | |
| other driver has bound to it, then the interface is | |
| automatically claimed by usbfs. | |
| </para><para> | |
| This claim will be released by a RELEASEINTERFACE ioctl, | |
| or by closing the file descriptor. | |
| File modification time is not updated by this request. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_CONNECTINFO</term> | |
| <listitem><para>Says whether the device is lowspeed. | |
| The ioctl parameter points to a structure like this: | |
| <programlisting>struct usbdevfs_connectinfo { | |
| unsigned int devnum; | |
| unsigned char slow; | |
| }; </programlisting> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| <emphasis>You can't tell whether a "not slow" | |
| device is connected at high speed (480 MBit/sec) | |
| or just full speed (12 MBit/sec).</emphasis> | |
| You should know the devnum value already, | |
| it's the DDD value of the device file name. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_GETDRIVER</term> | |
| <listitem><para>Returns the name of the kernel driver | |
| bound to a given interface (a string). Parameter | |
| is a pointer to this structure, which is modified: | |
| <programlisting>struct usbdevfs_getdriver { | |
| unsigned int interface; | |
| char driver[USBDEVFS_MAXDRIVERNAME + 1]; | |
| };</programlisting> | |
| File modification time is not updated by this request. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_IOCTL</term> | |
| <listitem><para>Passes a request from userspace through | |
| to a kernel driver that has an ioctl entry in the | |
| <emphasis>struct usb_driver</emphasis> it registered. | |
| <programlisting>struct usbdevfs_ioctl { | |
| int ifno; | |
| int ioctl_code; | |
| void *data; | |
| }; | |
| /* user mode call looks like this. | |
| * 'request' becomes the driver->ioctl() 'code' parameter. | |
| * the size of 'param' is encoded in 'request', and that data | |
| * is copied to or from the driver->ioctl() 'buf' parameter. | |
| */ | |
| static int | |
| usbdev_ioctl (int fd, int ifno, unsigned request, void *param) | |
| { | |
| struct usbdevfs_ioctl wrapper; | |
| wrapper.ifno = ifno; | |
| wrapper.ioctl_code = request; | |
| wrapper.data = param; | |
| return ioctl (fd, USBDEVFS_IOCTL, &wrapper); | |
| } </programlisting> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| This request lets kernel drivers talk to user mode code | |
| through filesystem operations even when they don't create | |
| a charactor or block special device. | |
| It's also been used to do things like ask devices what | |
| device special file should be used. | |
| Two pre-defined ioctls are used | |
| to disconnect and reconnect kernel drivers, so | |
| that user mode code can completely manage binding | |
| and configuration of devices. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_RELEASEINTERFACE</term> | |
| <listitem><para>This is used to release the claim usbfs | |
| made on interface, either implicitly or because of a | |
| USBDEVFS_CLAIMINTERFACE call, before the file | |
| descriptor is closed. | |
| The ioctl parameter is an integer holding the number of | |
| the interface (bInterfaceNumber from descriptor); | |
| File modification time is not updated by this request. | |
| </para><warning><para> | |
| <emphasis>No security check is made to ensure | |
| that the task which made the claim is the one | |
| which is releasing it. | |
| This means that user mode driver may interfere | |
| other ones. </emphasis> | |
| </para></warning></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_RESETEP</term> | |
| <listitem><para>Resets the data toggle value for an endpoint | |
| (bulk or interrupt) to DATA0. | |
| The ioctl parameter is an integer endpoint number | |
| (1 to 15, as identified in the endpoint descriptor), | |
| with USB_DIR_IN added if the device's endpoint sends | |
| data to the host. | |
| </para><warning><para> | |
| <emphasis>Avoid using this request. | |
| It should probably be removed.</emphasis> | |
| Using it typically means the device and driver will lose | |
| toggle synchronization. If you really lost synchronization, | |
| you likely need to completely handshake with the device, | |
| using a request like CLEAR_HALT | |
| or SET_INTERFACE. | |
| </para></warning></listitem></varlistentry> | |
| </variablelist> | |
| </sect2> | |
| <sect2> | |
| <title>Synchronous I/O Support</title> | |
| <para>Synchronous requests involve the kernel blocking | |
| until until the user mode request completes, either by | |
| finishing successfully or by reporting an error. | |
| In most cases this is the simplest way to use usbfs, | |
| although as noted above it does prevent performing I/O | |
| to more than one endpoint at a time. | |
| </para> | |
| <variablelist> | |
| <varlistentry><term>USBDEVFS_BULK</term> | |
| <listitem><para>Issues a bulk read or write request to the | |
| device. | |
| The ioctl parameter is a pointer to this structure: | |
| <programlisting>struct usbdevfs_bulktransfer { | |
| unsigned int ep; | |
| unsigned int len; | |
| unsigned int timeout; /* in milliseconds */ | |
| void *data; | |
| };</programlisting> | |
| </para><para>The "ep" value identifies a | |
| bulk endpoint number (1 to 15, as identified in an endpoint | |
| descriptor), | |
| masked with USB_DIR_IN when referring to an endpoint which | |
| sends data to the host from the device. | |
| The length of the data buffer is identified by "len"; | |
| Recent kernels support requests up to about 128KBytes. | |
| <emphasis>FIXME say how read length is returned, | |
| and how short reads are handled.</emphasis>. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_CLEAR_HALT</term> | |
| <listitem><para>Clears endpoint halt (stall) and | |
| resets the endpoint toggle. This is only | |
| meaningful for bulk or interrupt endpoints. | |
| The ioctl parameter is an integer endpoint number | |
| (1 to 15, as identified in an endpoint descriptor), | |
| masked with USB_DIR_IN when referring to an endpoint which | |
| sends data to the host from the device. | |
| </para><para> | |
| Use this on bulk or interrupt endpoints which have | |
| stalled, returning <emphasis>-EPIPE</emphasis> status | |
| to a data transfer request. | |
| Do not issue the control request directly, since | |
| that could invalidate the host's record of the | |
| data toggle. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_CONTROL</term> | |
| <listitem><para>Issues a control request to the device. | |
| The ioctl parameter points to a structure like this: | |
| <programlisting>struct usbdevfs_ctrltransfer { | |
| __u8 bRequestType; | |
| __u8 bRequest; | |
| __u16 wValue; | |
| __u16 wIndex; | |
| __u16 wLength; | |
| __u32 timeout; /* in milliseconds */ | |
| void *data; | |
| };</programlisting> | |
| </para><para> | |
| The first eight bytes of this structure are the contents | |
| of the SETUP packet to be sent to the device; see the | |
| USB 2.0 specification for details. | |
| The bRequestType value is composed by combining a | |
| USB_TYPE_* value, a USB_DIR_* value, and a | |
| USB_RECIP_* value (from | |
| <emphasis><linux/usb.h></emphasis>). | |
| If wLength is nonzero, it describes the length of the data | |
| buffer, which is either written to the device | |
| (USB_DIR_OUT) or read from the device (USB_DIR_IN). | |
| </para><para> | |
| At this writing, you can't transfer more than 4 KBytes | |
| of data to or from a device; usbfs has a limit, and | |
| some host controller drivers have a limit. | |
| (That's not usually a problem.) | |
| <emphasis>Also</emphasis> there's no way to say it's | |
| not OK to get a short read back from the device. | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_RESET</term> | |
| <listitem><para>Does a USB level device reset. | |
| The ioctl parameter is ignored. | |
| After the reset, this rebinds all device interfaces. | |
| File modification time is not updated by this request. | |
| </para><warning><para> | |
| <emphasis>Avoid using this call</emphasis> | |
| until some usbcore bugs get fixed, | |
| since it does not fully synchronize device, interface, | |
| and driver (not just usbfs) state. | |
| </para></warning></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_SETINTERFACE</term> | |
| <listitem><para>Sets the alternate setting for an | |
| interface. The ioctl parameter is a pointer to a | |
| structure like this: | |
| <programlisting>struct usbdevfs_setinterface { | |
| unsigned int interface; | |
| unsigned int altsetting; | |
| }; </programlisting> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| Those struct members are from some interface descriptor | |
| applying to the the current configuration. | |
| The interface number is the bInterfaceNumber value, and | |
| the altsetting number is the bAlternateSetting value. | |
| (This resets each endpoint in the interface.) | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_SETCONFIGURATION</term> | |
| <listitem><para>Issues the | |
| <function>usb_set_configuration</function> call | |
| for the device. | |
| The parameter is an integer holding the number of | |
| a configuration (bConfigurationValue from descriptor). | |
| File modification time is not updated by this request. | |
| </para><warning><para> | |
| <emphasis>Avoid using this call</emphasis> | |
| until some usbcore bugs get fixed, | |
| since it does not fully synchronize device, interface, | |
| and driver (not just usbfs) state. | |
| </para></warning></listitem></varlistentry> | |
| </variablelist> | |
| </sect2> | |
| <sect2> | |
| <title>Asynchronous I/O Support</title> | |
| <para>As mentioned above, there are situations where it may be | |
| important to initiate concurrent operations from user mode code. | |
| This is particularly important for periodic transfers | |
| (interrupt and isochronous), but it can be used for other | |
| kinds of USB requests too. | |
| In such cases, the asynchronous requests described here | |
| are essential. Rather than submitting one request and having | |
| the kernel block until it completes, the blocking is separate. | |
| </para> | |
| <para>These requests are packaged into a structure that | |
| resembles the URB used by kernel device drivers. | |
| (No POSIX Async I/O support here, sorry.) | |
| It identifies the endpoint type (USBDEVFS_URB_TYPE_*), | |
| endpoint (number, masked with USB_DIR_IN as appropriate), | |
| buffer and length, and a user "context" value serving to | |
| uniquely identify each request. | |
| (It's usually a pointer to per-request data.) | |
| Flags can modify requests (not as many as supported for | |
| kernel drivers). | |
| </para> | |
| <para>Each request can specify a realtime signal number | |
| (between SIGRTMIN and SIGRTMAX, inclusive) to request a | |
| signal be sent when the request completes. | |
| </para> | |
| <para>When usbfs returns these urbs, the status value | |
| is updated, and the buffer may have been modified. | |
| Except for isochronous transfers, the actual_length is | |
| updated to say how many bytes were transferred; if the | |
| USBDEVFS_URB_DISABLE_SPD flag is set | |
| ("short packets are not OK"), if fewer bytes were read | |
| than were requested then you get an error report. | |
| </para> | |
| <programlisting>struct usbdevfs_iso_packet_desc { | |
| unsigned int length; | |
| unsigned int actual_length; | |
| unsigned int status; | |
| }; | |
| struct usbdevfs_urb { | |
| unsigned char type; | |
| unsigned char endpoint; | |
| int status; | |
| unsigned int flags; | |
| void *buffer; | |
| int buffer_length; | |
| int actual_length; | |
| int start_frame; | |
| int number_of_packets; | |
| int error_count; | |
| unsigned int signr; | |
| void *usercontext; | |
| struct usbdevfs_iso_packet_desc iso_frame_desc[]; | |
| };</programlisting> | |
| <para> For these asynchronous requests, the file modification | |
| time reflects when the request was initiated. | |
| This contrasts with their use with the synchronous requests, | |
| where it reflects when requests complete. | |
| </para> | |
| <variablelist> | |
| <varlistentry><term>USBDEVFS_DISCARDURB</term> | |
| <listitem><para> | |
| <emphasis>TBS</emphasis> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_DISCSIGNAL</term> | |
| <listitem><para> | |
| <emphasis>TBS</emphasis> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_REAPURB</term> | |
| <listitem><para> | |
| <emphasis>TBS</emphasis> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_REAPURBNDELAY</term> | |
| <listitem><para> | |
| <emphasis>TBS</emphasis> | |
| File modification time is not updated by this request. | |
| </para><para> | |
| </para></listitem></varlistentry> | |
| <varlistentry><term>USBDEVFS_SUBMITURB</term> | |
| <listitem><para> | |
| <emphasis>TBS</emphasis> | |
| </para><para> | |
| </para></listitem></varlistentry> | |
| </variablelist> | |
| </sect2> | |
| </sect1> | |
| </chapter> | |
| </book> | |
| <!-- vim:syntax=sgml:sw=4 | |
| --> |