summaryrefslogtreecommitdiff
path: root/Documentation/DocBook/usb.tmpl
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/DocBook/usb.tmpl
downloadlwn-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.tmpl979
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>&lt;linux/usb_ch9.h&gt;</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 &lt;linux/usb.h&gt;
+#include &lt;linux/usbdevice_fs.h&gt;
+#include &lt;asm/byteorder.h&gt;</programlisting>
+ The standard USB device model requests, from "Chapter 9" of
+ the USB 2.0 specification, are automatically included from
+ the <filename>&lt;linux/usb_ch9.h&gt;</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, &amp;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>&lt;linux/usb.h&gt;</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
+-->