| <?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 as the |
| root (the system's master), hubs as interior nodes, and |
| peripherals 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 for a number of |
| reasons, one being 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 all downstream connectors are the squarish type |
| (or they are built into the peripheral). |
| Also, the host software doesn't need to deal with distributed |
| auto-configuration since the pre-designated master node manages all that. |
| And finally, at the electrical level, bus protocol overhead is reduced by |
| eliminating arbitration and moving scheduling into the 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, adding high-speed |
| transfers and transaction-translating hubs (used for USB 1.1 |
| and 1.0 backward compatibility). |
| </para> |
| |
| <para>Kernel developers added USB support to Linux early in the 2.2 kernel |
| series, shortly before 2.3 development forked. Updates from 2.3 were |
| regularly folded back into 2.2 releases, which improved reliability and |
| brought <filename>/sbin/hotplug</filename> support as well more drivers. |
| Such improvements were continued in the 2.5 kernel series, where they added |
| USB 2.0 support, improved performance, and made the host controller drivers |
| (HCDs) more consistent. They also simplified the API (to make bugs less |
| likely) and added internal "kerneldoc" documentation. |
| </para> |
| |
| <para>Linux can run inside USB devices as well as on |
| the hosts that control the devices. |
| But USB device drivers running inside those peripherals |
| don't do the same things as the ones running inside hosts, |
| so they've been given a different name: |
| <emphasis>gadget drivers</emphasis>. |
| This document does not cover gadget drivers. |
| </para> |
| |
| </chapter> |
| |
| <chapter id="host"> |
| <title>USB Host-Side API Model</title> |
| |
| <para>Host-side drivers for USB devices talk to the "usbcore" APIs. |
| There are two. One is intended for |
| <emphasis>general-purpose</emphasis> drivers (exposed through |
| driver frameworks), and the other is for drivers that are |
| <emphasis>part of the core</emphasis>. |
| Such core drivers include the <emphasis>hub</emphasis> driver |
| (which manages trees of USB devices) and several different kinds |
| of <emphasis>host controller drivers</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 transfers |
| (control, bulk, interrupt, and isochronous). Two of them (control |
| and bulk) use bandwidth as it's available, |
| while the other two (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 which might be used. |
| </para></listitem> |
| |
| <listitem><para>Configurations have one or more "interfaces", 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 messages. |
| It also supports asynchronous 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 id="types"><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 id="hostside"><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 id="usbcore"><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/driver.c |
| !Edrivers/usb/core/usb.c |
| !Edrivers/usb/core/hub.c |
| </chapter> |
| |
| <chapter id="hcd"><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 |
| !Idrivers/usb/core/buffer.c |
| </chapter> |
| |
| <chapter id="usbfs"> |
| <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. |
| </para> |
| |
| <sect1 id="usbfs-files"> |
| <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 id="usbfs-fstab"> |
| <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 id="usbfs-devices"> |
| <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>This file, in combination with the poll() system call, can |
| also be used to detect when devices are added or removed: |
| <programlisting>int fd; |
| struct pollfd pfd; |
| |
| fd = open("/proc/bus/usb/devices", O_RDONLY); |
| pfd = { fd, POLLIN, 0 }; |
| for (;;) { |
| /* The first time through, this call will return immediately. */ |
| poll(&pfd, 1, -1); |
| |
| /* To see what's changed, compare the file's previous and current |
| contents or scan the filesystem. (Scanning is more precise.) */ |
| }</programlisting> |
| Note that this behavior is intended to be used for informational |
| and debug purposes. It would be more appropriate to use programs |
| such as udev or HAL to initialize a device or start a user-mode |
| helper program, for instance. |
| </para> |
| </sect1> |
| |
| <sect1 id="usbfs-bbbddd"> |
| <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 id="usbfs-lifecycle"> |
| <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 id="usbfs-ioctl"><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 id="usbfs-mgmt"> |
| <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 character 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 id="usbfs-sync"> |
| <title>Synchronous I/O Support</title> |
| |
| <para>Synchronous requests involve the kernel blocking |
| 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 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 id="usbfs-async"> |
| <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 |
| --> |