| .. _usb-hostside-api: | 
 |  | 
 | =========================== | 
 | The Linux-USB Host Side API | 
 | =========================== | 
 |  | 
 | Introduction to USB on Linux | 
 | ============================ | 
 |  | 
 | 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 | 
 | a few USB 3.0 (5 GBit/s) or USB 3.1 (10 GBit/s) and some legacy | 
 | USB 2.0 (480 MBit/s) busses just in case. | 
 |  | 
 | That master/slave asymmetry was designed-in for a number of reasons, one | 
 | being ease of use. It is not physically possible to mistake upstream and | 
 | downstream or it does not matter with a type C plug (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. | 
 |  | 
 | Kernel developers added USB support to Linux early in the 2.2 kernel | 
 | series and have been developing it further since then. Besides support | 
 | for each new generation of USB, various host controllers gained support, | 
 | new drivers for peripherals have been added and advanced features for latency | 
 | measurement and improved power management introduced. | 
 |  | 
 | 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: *gadget drivers*. This document does not | 
 | cover gadget drivers. | 
 |  | 
 | USB Host-Side API Model | 
 | ======================= | 
 |  | 
 | Host-side drivers for USB devices talk to the "usbcore" APIs. There are | 
 | two. One is intended for *general-purpose* drivers (exposed through | 
 | driver frameworks), and the other is for drivers that are *part of the | 
 | core*. Such core drivers include the *hub* driver (which manages trees | 
 | of USB devices) and several different kinds of *host controller | 
 | drivers*, which control individual busses. | 
 |  | 
 | The device model seen by USB drivers is relatively complex. | 
 |  | 
 | -  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. | 
 |  | 
 | -  The device description model includes one or more "configurations" | 
 |    per device, only one of which is active at a time. Devices are supposed | 
 |    to be capable of operating at lower than their top | 
 |    speeds and may provide a BOS descriptor showing the lowest speed they | 
 |    remain fully operational at. | 
 |  | 
 | -  From USB 3.0 on configurations have one or more "functions", which | 
 |    provide a common functionality and are grouped together for purposes | 
 |    of power management. | 
 |  | 
 | -  Configurations or functions 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. | 
 |  | 
 |    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. *Most USB devices are simple, | 
 |    with only one function, one configuration, one interface, and one alternate | 
 |    setting.* | 
 |  | 
 | -  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. | 
 |  | 
 | -  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. | 
 |  | 
 | -  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). | 
 |  | 
 | Accordingly, the USB Core API exposed to device drivers covers quite a | 
 | lot of territory. You'll probably need to consult the USB 3.0 | 
 | specification, available online from www.usb.org at no cost, as well as | 
 | class or device specifications. | 
 |  | 
 | 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, but there are still differences | 
 | that crop up especially with fault handling on the less common controllers. | 
 | 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. | 
 |  | 
 | .. _usb_chapter9: | 
 |  | 
 | USB-Standard Types | 
 | ================== | 
 |  | 
 | In ``<linux/usb/ch9.h>`` 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, usb character | 
 | devices and debugfs interfaces. | 
 |  | 
 | .. kernel-doc:: include/linux/usb/ch9.h | 
 |    :internal: | 
 |  | 
 | .. _usb_header: | 
 |  | 
 | Host-Side Data Types and Macros | 
 | =============================== | 
 |  | 
 | 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. | 
 |  | 
 | .. kernel-doc:: include/linux/usb.h | 
 |    :internal: | 
 |  | 
 | USB Core APIs | 
 | ============= | 
 |  | 
 | 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 handles 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). | 
 |  | 
 | 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. | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/urb.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/message.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/file.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/driver.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/usb.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/hub.c | 
 |    :export: | 
 |  | 
 | Host Controller APIs | 
 | ==================== | 
 |  | 
 | These APIs are only for use by host controller drivers, most of which | 
 | implement standard register interfaces such as XHCI, 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). XHCI was designed with USB 3.0. It | 
 | continues to shift support for functionality into hardware. | 
 |  | 
 | 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 and a virtual host controller to pipe USB over the network. | 
 |  | 
 | The same basic APIs are available to drivers for all those controllers. | 
 | For historical reasons they are in two layers: :c:type:`struct | 
 | usb_bus <usb_bus>` is a rather thin layer that became available | 
 | in the 2.2 kernels, while :c:type:`struct usb_hcd <usb_hcd>` | 
 | is a more featureful layer | 
 | that lets HCDs share common code, to shrink driver size and | 
 | significantly reduce hcd-specific behaviors. | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/hcd.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/hcd-pci.c | 
 |    :export: | 
 |  | 
 | .. kernel-doc:: drivers/usb/core/buffer.c | 
 |    :internal: | 
 |  | 
 | The USB character device nodes | 
 | ============================== | 
 |  | 
 | This chapter presents the Linux character device nodes. You may prefer | 
 | to avoid writing new kernel code for your USB driver. User mode device | 
 | drivers are usually packaged as applications or libraries, and may use | 
 | character devices through some programming library that wraps it. | 
 | Such libraries include: | 
 |  | 
 |  - `libusb <http://libusb.sourceforge.net>`__ for C/C++, and | 
 |  - `jUSB <http://jUSB.sourceforge.net>`__ for Java. | 
 |  | 
 | Some old information about it can be seen at the "USB Device Filesystem" | 
 | section of the USB Guide. The latest copy of the USB Guide can be found | 
 | at http://www.linux-usb.org/ | 
 |  | 
 | .. note:: | 
 |  | 
 |   - They were used to be implemented via *usbfs*, but this is not part of | 
 |     the sysfs debug interface. | 
 |  | 
 |    - 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. | 
 |  | 
 | What files are in "devtmpfs"? | 
 | ----------------------------- | 
 |  | 
 | Conventionally mounted at ``/dev/bus/usb/``, usbfs features include: | 
 |  | 
 | -  ``/dev/bus/usb/BBB/DDD`` ... 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.) | 
 |  | 
 | 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. *Don't even | 
 | think of saving these in application configuration files.* 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. Pleast note that it doesn't (yet) expose those IDs. | 
 |  | 
 | /dev/bus/usb/BBB/DDD | 
 | -------------------- | 
 |  | 
 | Use these files in one of these basic ways: | 
 |  | 
 | - *They can be read,* 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. | 
 |  | 
 | - *Perform USB operations* using *ioctl()* 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 | 
 |   *half duplex* protocols, but otherwise you'd use asynchronous i/o | 
 |   requests. | 
 |  | 
 | Each connected USB device has one file.  The ``BBB`` indicates the bus | 
 | number.  The ``DDD`` indicates the device address on that bus.  Both | 
 | of these numbers are assigned sequentially, and can be reused, so | 
 | you can't rely on them for stable access to devices.  For example, | 
 | it's relatively common for devices to re-enumerate while they are | 
 | still connected (perhaps someone jostled their power supply, hub, | 
 | or USB cable), so a device might be ``002/027`` when you first connect | 
 | it and ``002/048`` sometime later. | 
 |  | 
 | These files can be read as binary data.  The binary data consists | 
 | of first the device descriptor, then the descriptors for each | 
 | configuration of the device.  Multi-byte fields in the device descriptor | 
 | are converted to host endianness by the kernel.  The configuration | 
 | descriptors are in bus endian format! The configuration descriptor | 
 | are wTotalLength bytes apart. If a device returns less configuration | 
 | descriptor data than indicated by wTotalLength there will be a hole in | 
 | the file for the missing bytes.  This information is also shown | 
 | in text form by the ``/sys/kernel/debug/usb/devices`` file, described later. | 
 |  | 
 | These files may also be used to write user-level drivers for the USB | 
 | devices.  You would open the ``/dev/bus/usb/BBB/DDD`` file read/write, | 
 | read its descriptors to make sure it's the device you expect, and then | 
 | bind to an interface (or perhaps several) using an ioctl call.  You | 
 | would issue more ioctls to the device to communicate to it using | 
 | control, bulk, or other kinds of USB transfers.  The IOCTLs are | 
 | listed in the ``<linux/usbdevice_fs.h>`` file, and at this writing the | 
 | source code (``linux/drivers/usb/core/devio.c``) is the primary reference | 
 | for how to access devices through those files. | 
 |  | 
 | Note that since by default these ``BBB/DDD`` files are writable only by | 
 | root, only root can write such user mode drivers.  You can selectively | 
 | grant read/write permissions to other users by using ``chmod``.  Also, | 
 | usbfs mount options such as ``devmode=0666`` may be helpful. | 
 |  | 
 |  | 
 | Life Cycle of User Mode Drivers | 
 | ------------------------------- | 
 |  | 
 | 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 ``/sbin/hotplug`` | 
 | event handling agent chose that driver to handle the new device. Or | 
 | maybe it's an application that scans all the ``/dev/bus/usb`` device files, | 
 | and ignores most devices. In either case, it should :c:func:`read()` | 
 | 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. | 
 |  | 
 | 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. | 
 |  | 
 | 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.) | 
 |  | 
 | 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. *Bulk* transfers are easiest to use, but only their sibling | 
 | *interrupt* transfers work with low speed devices. Both interrupt and | 
 | *isochronous* 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. | 
 |  | 
 | 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. | 
 |  | 
 | The ioctl() Requests | 
 | -------------------- | 
 |  | 
 | To use these ioctls, you need to include the following headers in your | 
 | userspace program:: | 
 |  | 
 |     #include <linux/usb.h> | 
 |     #include <linux/usbdevice_fs.h> | 
 |     #include <asm/byteorder.h> | 
 |  | 
 | The standard USB device model requests, from "Chapter 9" of the USB 2.0 | 
 | specification, are automatically included from the ``<linux/usb/ch9.h>`` | 
 | header. | 
 |  | 
 | 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 | 
 | :ref:`usb-error-codes`). | 
 |  | 
 | 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 | 
 | hub_wq (in the kernel) setting a device-wide *configuration* that | 
 | affects things like power consumption and basic functionality. The | 
 | endpoints are part of USB *interfaces*, which may have *altsettings* | 
 | 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. | 
 |  | 
 | Management/Status Requests | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | 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. | 
 |  | 
 | USBDEVFS_CLAIMINTERFACE | 
 |     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). | 
 |  | 
 |     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. | 
 |  | 
 |     This claim will be released by a RELEASEINTERFACE ioctl, or by | 
 |     closing the file descriptor. File modification time is not updated | 
 |     by this request. | 
 |  | 
 | USBDEVFS_CONNECTINFO | 
 |     Says whether the device is lowspeed. The ioctl parameter points to a | 
 |     structure like this:: | 
 |  | 
 | 	struct usbdevfs_connectinfo { | 
 | 		unsigned int   devnum; | 
 | 		unsigned char  slow; | 
 | 	}; | 
 |  | 
 |     File modification time is not updated by this request. | 
 |  | 
 |     *You can't tell whether a "not slow" device is connected at high | 
 |     speed (480 MBit/sec) or just full speed (12 MBit/sec).* You should | 
 |     know the devnum value already, it's the DDD value of the device file | 
 |     name. | 
 |  | 
 | USBDEVFS_GETDRIVER | 
 |     Returns the name of the kernel driver bound to a given interface (a | 
 |     string). Parameter is a pointer to this structure, which is | 
 |     modified:: | 
 |  | 
 | 	struct usbdevfs_getdriver { | 
 | 		unsigned int  interface; | 
 | 		char          driver[USBDEVFS_MAXDRIVERNAME + 1]; | 
 | 	}; | 
 |  | 
 |     File modification time is not updated by this request. | 
 |  | 
 | USBDEVFS_IOCTL | 
 |     Passes a request from userspace through to a kernel driver that has | 
 |     an ioctl entry in the *struct usb_driver* it registered:: | 
 |  | 
 | 	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); | 
 | 	} | 
 |  | 
 |     File modification time is not updated by this request. | 
 |  | 
 |     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. | 
 |  | 
 | USBDEVFS_RELEASEINTERFACE | 
 |     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. | 
 |  | 
 |     .. warning:: | 
 |  | 
 | 	*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.* | 
 |  | 
 | USBDEVFS_RESETEP | 
 |     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. | 
 |  | 
 |     .. Warning:: | 
 |  | 
 | 	*Avoid using this request. It should probably be removed.* 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. | 
 |  | 
 | USBDEVFS_DROP_PRIVILEGES | 
 |     This is used to relinquish the ability to do certain operations | 
 |     which are considered to be privileged on a usbfs file descriptor. | 
 |     This includes claiming arbitrary interfaces, resetting a device on | 
 |     which there are currently claimed interfaces from other users, and | 
 |     issuing USBDEVFS_IOCTL calls. The ioctl parameter is a 32 bit mask | 
 |     of interfaces the user is allowed to claim on this file descriptor. | 
 |     You may issue this ioctl more than one time to narrow said mask. | 
 |  | 
 | Synchronous I/O Support | 
 | ~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | 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. | 
 |  | 
 | USBDEVFS_BULK | 
 |     Issues a bulk read or write request to the device. The ioctl | 
 |     parameter is a pointer to this structure:: | 
 |  | 
 | 	struct usbdevfs_bulktransfer { | 
 | 		unsigned int  ep; | 
 | 		unsigned int  len; | 
 | 		unsigned int  timeout; /* in milliseconds */ | 
 | 		void          *data; | 
 | 	}; | 
 |  | 
 |     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. *FIXME say how read | 
 |     length is returned, and how short reads are handled.*. | 
 |  | 
 | USBDEVFS_CLEAR_HALT | 
 |     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. | 
 |  | 
 |     Use this on bulk or interrupt endpoints which have stalled, | 
 |     returning ``-EPIPE`` 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. | 
 |  | 
 | USBDEVFS_CONTROL | 
 |     Issues a control request to the device. The ioctl parameter points | 
 |     to a structure like this:: | 
 |  | 
 | 	struct usbdevfs_ctrltransfer { | 
 | 		__u8   bRequestType; | 
 | 		__u8   bRequest; | 
 | 		__u16  wValue; | 
 | 		__u16  wIndex; | 
 | 		__u16  wLength; | 
 | 		__u32  timeout;  /* in milliseconds */ | 
 | 		void   *data; | 
 | 	}; | 
 |  | 
 |     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 ``linux/usb.h``). 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). | 
 |  | 
 |     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.) *Also* there's no way | 
 |     to say it's not OK to get a short read back from the device. | 
 |  | 
 | USBDEVFS_RESET | 
 |     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. | 
 |  | 
 | .. warning:: | 
 |  | 
 | 	*Avoid using this call* until some usbcore bugs get fixed, since | 
 | 	it does not fully synchronize device, interface, and driver (not | 
 | 	just usbfs) state. | 
 |  | 
 | USBDEVFS_SETINTERFACE | 
 |     Sets the alternate setting for an interface. The ioctl parameter is | 
 |     a pointer to a structure like this:: | 
 |  | 
 | 	struct usbdevfs_setinterface { | 
 | 		unsigned int  interface; | 
 | 		unsigned int  altsetting; | 
 | 	}; | 
 |  | 
 |     File modification time is not updated by this request. | 
 |  | 
 |     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.) | 
 |  | 
 | USBDEVFS_SETCONFIGURATION | 
 |     Issues the :c:func:`usb_set_configuration()` 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. | 
 |  | 
 | .. warning:: | 
 |  | 
 | 	*Avoid using this call* until some usbcore bugs get fixed, since | 
 | 	it does not fully synchronize device, interface, and driver (not | 
 | 	just usbfs) state. | 
 |  | 
 | Asynchronous I/O Support | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | 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. | 
 |  | 
 | 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). | 
 |  | 
 | Each request can specify a realtime signal number (between SIGRTMIN and | 
 | SIGRTMAX, inclusive) to request a signal be sent when the request | 
 | completes. | 
 |  | 
 | 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:: | 
 |  | 
 |     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[]; | 
 |     }; | 
 |  | 
 | 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. | 
 |  | 
 | USBDEVFS_DISCARDURB | 
 |     *TBS* File modification time is not updated by this request. | 
 |  | 
 | USBDEVFS_DISCSIGNAL | 
 |     *TBS* File modification time is not updated by this request. | 
 |  | 
 | USBDEVFS_REAPURB | 
 |     *TBS* File modification time is not updated by this request. | 
 |  | 
 | USBDEVFS_REAPURBNDELAY | 
 |     *TBS* File modification time is not updated by this request. | 
 |  | 
 | USBDEVFS_SUBMITURB | 
 |     *TBS* | 
 |  | 
 | The USB devices | 
 | =============== | 
 |  | 
 | The USB devices are now exported via debugfs: | 
 |  | 
 | -  ``/sys/kernel/debug/usb/devices`` ... 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. | 
 |  | 
 | /sys/kernel/debug/usb/devices | 
 | ----------------------------- | 
 |  | 
 | 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 below. | 
 |  | 
 | This file, in combination with the poll() system call, can also be used | 
 | to detect when devices are added or removed:: | 
 |  | 
 |     int fd; | 
 |     struct pollfd pfd; | 
 |  | 
 |     fd = open("/sys/kernel/debug/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.) */ | 
 |     } | 
 |  | 
 | 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. | 
 |  | 
 | In this file, each device's output has multiple lines of ASCII output. | 
 |  | 
 | I made it ASCII instead of binary on purpose, so that someone | 
 | can obtain some useful data from it without the use of an | 
 | auxiliary program.  However, with an auxiliary program, the numbers | 
 | in the first 4 columns of each ``T:`` line (topology info: | 
 | Lev, Prnt, Port, Cnt) can be used to build a USB topology diagram. | 
 |  | 
 | Each line is tagged with a one-character ID for that line:: | 
 |  | 
 | 	T = Topology (etc.) | 
 | 	B = Bandwidth (applies only to USB host controllers, which are | 
 | 	virtualized as root hubs) | 
 | 	D = Device descriptor info. | 
 | 	P = Product ID info. (from Device descriptor, but they won't fit | 
 | 	together on one line) | 
 | 	S = String descriptors. | 
 | 	C = Configuration descriptor info. (* = active configuration) | 
 | 	I = Interface descriptor info. | 
 | 	E = Endpoint descriptor info. | 
 |  | 
 | /sys/kernel/debug/usb/devices output format | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | Legend:: | 
 |   d = decimal number (may have leading spaces or 0's) | 
 |   x = hexadecimal number (may have leading spaces or 0's) | 
 |   s = string | 
 |  | 
 |  | 
 |  | 
 | Topology info | 
 | ^^^^^^^^^^^^^ | 
 |  | 
 | :: | 
 |  | 
 | 	T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd | 
 | 	|   |      |      |       |       |      |        |        |__MaxChildren | 
 | 	|   |      |      |       |       |      |        |__Device Speed in Mbps | 
 | 	|   |      |      |       |       |      |__DeviceNumber | 
 | 	|   |      |      |       |       |__Count of devices at this level | 
 | 	|   |      |      |       |__Connector/Port on Parent for this device | 
 | 	|   |      |      |__Parent DeviceNumber | 
 | 	|   |      |__Level in topology for this bus | 
 | 	|   |__Bus number | 
 | 	|__Topology info tag | 
 |  | 
 | Speed may be: | 
 |  | 
 | 	======= ====================================================== | 
 | 	1.5	Mbit/s for low speed USB | 
 | 	12	Mbit/s for full speed USB | 
 | 	480	Mbit/s for high speed USB (added for USB 2.0); | 
 | 		also used for Wireless USB, which has no fixed speed | 
 | 	5000	Mbit/s for SuperSpeed USB (added for USB 3.0) | 
 | 	======= ====================================================== | 
 |  | 
 | For reasons lost in the mists of time, the Port number is always | 
 | too low by 1.  For example, a device plugged into port 4 will | 
 | show up with ``Port=03``. | 
 |  | 
 | Bandwidth info | 
 | ^^^^^^^^^^^^^^ | 
 |  | 
 | :: | 
 |  | 
 | 	B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd | 
 | 	|   |                       |         |__Number of isochronous requests | 
 | 	|   |                       |__Number of interrupt requests | 
 | 	|   |__Total Bandwidth allocated to this bus | 
 | 	|__Bandwidth info tag | 
 |  | 
 | Bandwidth allocation is an approximation of how much of one frame | 
 | (millisecond) is in use.  It reflects only periodic transfers, which | 
 | are the only transfers that reserve bandwidth.  Control and bulk | 
 | transfers use all other bandwidth, including reserved bandwidth that | 
 | is not used for transfers (such as for short packets). | 
 |  | 
 | The percentage is how much of the "reserved" bandwidth is scheduled by | 
 | those transfers.  For a low or full speed bus (loosely, "USB 1.1"), | 
 | 90% of the bus bandwidth is reserved.  For a high speed bus (loosely, | 
 | "USB 2.0") 80% is reserved. | 
 |  | 
 |  | 
 | Device descriptor info & Product ID info | 
 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | :: | 
 |  | 
 | 	D:  Ver=x.xx Cls=xx(s) Sub=xx Prot=xx MxPS=dd #Cfgs=dd | 
 | 	P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx | 
 |  | 
 | where:: | 
 |  | 
 | 	D:  Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd | 
 | 	|   |        |             |      |       |       |__NumberConfigurations | 
 | 	|   |        |             |      |       |__MaxPacketSize of Default Endpoint | 
 | 	|   |        |             |      |__DeviceProtocol | 
 | 	|   |        |             |__DeviceSubClass | 
 | 	|   |        |__DeviceClass | 
 | 	|   |__Device USB version | 
 | 	|__Device info tag #1 | 
 |  | 
 | where:: | 
 |  | 
 | 	P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx | 
 | 	|   |           |           |__Product revision number | 
 | 	|   |           |__Product ID code | 
 | 	|   |__Vendor ID code | 
 | 	|__Device info tag #2 | 
 |  | 
 |  | 
 | String descriptor info | 
 | ^^^^^^^^^^^^^^^^^^^^^^ | 
 | :: | 
 |  | 
 | 	S:  Manufacturer=ssss | 
 | 	|   |__Manufacturer of this device as read from the device. | 
 | 	|      For USB host controller drivers (virtual root hubs) this may | 
 | 	|      be omitted, or (for newer drivers) will identify the kernel | 
 | 	|      version and the driver which provides this hub emulation. | 
 | 	|__String info tag | 
 |  | 
 | 	S:  Product=ssss | 
 | 	|   |__Product description of this device as read from the device. | 
 | 	|      For older USB host controller drivers (virtual root hubs) this | 
 | 	|      indicates the driver; for newer ones, it's a product (and vendor) | 
 | 	|      description that often comes from the kernel's PCI ID database. | 
 | 	|__String info tag | 
 |  | 
 | 	S:  SerialNumber=ssss | 
 | 	|   |__Serial Number of this device as read from the device. | 
 | 	|      For USB host controller drivers (virtual root hubs) this is | 
 | 	|      some unique ID, normally a bus ID (address or slot name) that | 
 | 	|      can't be shared with any other device. | 
 | 	|__String info tag | 
 |  | 
 |  | 
 |  | 
 | Configuration descriptor info | 
 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
 | :: | 
 |  | 
 | 	C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA | 
 | 	| | |       |       |      |__MaxPower in mA | 
 | 	| | |       |       |__Attributes | 
 | 	| | |       |__ConfiguratioNumber | 
 | 	| | |__NumberOfInterfaces | 
 | 	| |__ "*" indicates the active configuration (others are " ") | 
 | 	|__Config info tag | 
 |  | 
 | USB devices may have multiple configurations, each of which act | 
 | rather differently.  For example, a bus-powered configuration | 
 | might be much less capable than one that is self-powered.  Only | 
 | one device configuration can be active at a time; most devices | 
 | have only one configuration. | 
 |  | 
 | Each configuration consists of one or more interfaces.  Each | 
 | interface serves a distinct "function", which is typically bound | 
 | to a different USB device driver.  One common example is a USB | 
 | speaker with an audio interface for playback, and a HID interface | 
 | for use with software volume control. | 
 |  | 
 | Interface descriptor info (can be multiple per Config) | 
 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
 | :: | 
 |  | 
 | 	I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss | 
 | 	| | |      |      |       |             |      |       |__Driver name | 
 | 	| | |      |      |       |             |      |          or "(none)" | 
 | 	| | |      |      |       |             |      |__InterfaceProtocol | 
 | 	| | |      |      |       |             |__InterfaceSubClass | 
 | 	| | |      |      |       |__InterfaceClass | 
 | 	| | |      |      |__NumberOfEndpoints | 
 | 	| | |      |__AlternateSettingNumber | 
 | 	| | |__InterfaceNumber | 
 | 	| |__ "*" indicates the active altsetting (others are " ") | 
 | 	|__Interface info tag | 
 |  | 
 | A given interface may have one or more "alternate" settings. | 
 | For example, default settings may not use more than a small | 
 | amount of periodic bandwidth.  To use significant fractions | 
 | of bus bandwidth, drivers must select a non-default altsetting. | 
 |  | 
 | Only one setting for an interface may be active at a time, and | 
 | only one driver may bind to an interface at a time.  Most devices | 
 | have only one alternate setting per interface. | 
 |  | 
 |  | 
 | Endpoint descriptor info (can be multiple per Interface) | 
 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | :: | 
 |  | 
 | 	E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddss | 
 | 	|   |        |            |         |__Interval (max) between transfers | 
 | 	|   |        |            |__EndpointMaxPacketSize | 
 | 	|   |        |__Attributes(EndpointType) | 
 | 	|   |__EndpointAddress(I=In,O=Out) | 
 | 	|__Endpoint info tag | 
 |  | 
 | The interval is nonzero for all periodic (interrupt or isochronous) | 
 | endpoints.  For high speed endpoints the transfer interval may be | 
 | measured in microseconds rather than milliseconds. | 
 |  | 
 | For high speed periodic endpoints, the ``EndpointMaxPacketSize`` reflects | 
 | the per-microframe data transfer size.  For "high bandwidth" | 
 | endpoints, that can reflect two or three packets (for up to | 
 | 3KBytes every 125 usec) per endpoint. | 
 |  | 
 | With the Linux-USB stack, periodic bandwidth reservations use the | 
 | transfer intervals and sizes provided by URBs, which can be less | 
 | than those found in endpoint descriptor. | 
 |  | 
 | Usage examples | 
 | ~~~~~~~~~~~~~~ | 
 |  | 
 | If a user or script is interested only in Topology info, for | 
 | example, use something like ``grep ^T: /sys/kernel/debug/usb/devices`` | 
 | for only the Topology lines.  A command like | 
 | ``grep -i ^[tdp]: /sys/kernel/debug/usb/devices`` can be used to list | 
 | only the lines that begin with the characters in square brackets, | 
 | where the valid characters are TDPCIE.  With a slightly more able | 
 | script, it can display any selected lines (for example, only T, D, | 
 | and P lines) and change their output format.  (The ``procusb`` | 
 | Perl script is the beginning of this idea.  It will list only | 
 | selected lines [selected from TBDPSCIE] or "All" lines from | 
 | ``/sys/kernel/debug/usb/devices``.) | 
 |  | 
 | The Topology lines can be used to generate a graphic/pictorial | 
 | of the USB devices on a system's root hub.  (See more below | 
 | on how to do this.) | 
 |  | 
 | The Interface lines can be used to determine what driver is | 
 | being used for each device, and which altsetting it activated. | 
 |  | 
 | The Configuration lines could be used to list maximum power | 
 | (in milliamps) that a system's USB devices are using. | 
 | For example, ``grep ^C: /sys/kernel/debug/usb/devices``. | 
 |  | 
 |  | 
 | Here's an example, from a system which has a UHCI root hub, | 
 | an external hub connected to the root hub, and a mouse and | 
 | a serial converter connected to the external hub. | 
 |  | 
 | :: | 
 |  | 
 | 	T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12   MxCh= 2 | 
 | 	B:  Alloc= 28/900 us ( 3%), #Int=  2, #Iso=  0 | 
 | 	D:  Ver= 1.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1 | 
 | 	P:  Vendor=0000 ProdID=0000 Rev= 0.00 | 
 | 	S:  Product=USB UHCI Root Hub | 
 | 	S:  SerialNumber=dce0 | 
 | 	C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr=  0mA | 
 | 	I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub | 
 | 	E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=255ms | 
 |  | 
 | 	T:  Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 4 | 
 | 	D:  Ver= 1.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1 | 
 | 	P:  Vendor=0451 ProdID=1446 Rev= 1.00 | 
 | 	C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA | 
 | 	I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub | 
 | 	E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=255ms | 
 |  | 
 | 	T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5  MxCh= 0 | 
 | 	D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1 | 
 | 	P:  Vendor=04b4 ProdID=0001 Rev= 0.00 | 
 | 	C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA | 
 | 	I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=mouse | 
 | 	E:  Ad=81(I) Atr=03(Int.) MxPS=   3 Ivl= 10ms | 
 |  | 
 | 	T:  Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12   MxCh= 0 | 
 | 	D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1 | 
 | 	P:  Vendor=0565 ProdID=0001 Rev= 1.08 | 
 | 	S:  Manufacturer=Peracom Networks, Inc. | 
 | 	S:  Product=Peracom USB to Serial Converter | 
 | 	C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA | 
 | 	I:  If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial | 
 | 	E:  Ad=81(I) Atr=02(Bulk) MxPS=  64 Ivl= 16ms | 
 | 	E:  Ad=01(O) Atr=02(Bulk) MxPS=  16 Ivl= 16ms | 
 | 	E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=  8ms | 
 |  | 
 |  | 
 | Selecting only the ``T:`` and ``I:`` lines from this (for example, by using | 
 | ``procusb ti``), we have | 
 |  | 
 | :: | 
 |  | 
 | 	T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12   MxCh= 2 | 
 | 	T:  Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 4 | 
 | 	I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub | 
 | 	T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5  MxCh= 0 | 
 | 	I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=mouse | 
 | 	T:  Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12   MxCh= 0 | 
 | 	I:  If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial | 
 |  | 
 |  | 
 | Physically this looks like (or could be converted to):: | 
 |  | 
 |                       +------------------+ | 
 |                       |  PC/root_hub (12)|   Dev# = 1 | 
 |                       +------------------+   (nn) is Mbps. | 
 |     Level 0           |  CN.0   |  CN.1  |   [CN = connector/port #] | 
 |                       +------------------+ | 
 |                           / | 
 |                          / | 
 |             +-----------------------+ | 
 |   Level 1   | Dev#2: 4-port hub (12)| | 
 |             +-----------------------+ | 
 |             |CN.0 |CN.1 |CN.2 |CN.3 | | 
 |             +-----------------------+ | 
 |                 \           \____________________ | 
 |                  \_____                          \ | 
 |                        \                          \ | 
 |                +--------------------+      +--------------------+ | 
 |   Level 2      | Dev# 3: mouse (1.5)|      | Dev# 4: serial (12)| | 
 |                +--------------------+      +--------------------+ | 
 |  | 
 |  | 
 |  | 
 | Or, in a more tree-like structure (ports [Connectors] without | 
 | connections could be omitted):: | 
 |  | 
 | 	PC:  Dev# 1, root hub, 2 ports, 12 Mbps | 
 | 	|_ CN.0:  Dev# 2, hub, 4 ports, 12 Mbps | 
 | 	     |_ CN.0:  Dev #3, mouse, 1.5 Mbps | 
 | 	     |_ CN.1: | 
 | 	     |_ CN.2:  Dev #4, serial, 12 Mbps | 
 | 	     |_ CN.3: | 
 | 	|_ CN.1: |