diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/DocBook/usb.tmpl | |
download | lwn-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz lwn-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'Documentation/DocBook/usb.tmpl')
-rw-r--r-- | Documentation/DocBook/usb.tmpl | 979 |
1 files changed, 979 insertions, 0 deletions
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl new file mode 100644 index 000000000000..f3ef0bf435e9 --- /dev/null +++ b/Documentation/DocBook/usb.tmpl @@ -0,0 +1,979 @@ +<?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 +--> |