|
@@ -1,3 +1,5 @@
|
|
|
+.. _usb-hostside-api:
|
|
|
+
|
|
|
===========================
|
|
|
The Linux-USB Host Side API
|
|
|
===========================
|
|
@@ -102,16 +104,21 @@ 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, and usbfs.
|
|
|
+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
|
|
|
===============================
|
|
|
|
|
@@ -198,173 +205,110 @@ significantly reduce hcd-specific behaviors.
|
|
|
.. kernel-doc:: drivers/usb/core/buffer.c
|
|
|
:internal:
|
|
|
|
|
|
-The USB Filesystem (usbfs)
|
|
|
-==========================
|
|
|
+The USB character device nodes
|
|
|
+==============================
|
|
|
|
|
|
-This chapter presents the Linux *usbfs*. 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
|
|
|
-`libusb <http://libusb.sourceforge.net>`__ for C/C++, and
|
|
|
-`jUSB <http://jUSB.sourceforge.net>`__ for Java.
|
|
|
+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:
|
|
|
|
|
|
- **Note**
|
|
|
+ - `libusb <http://libusb.sourceforge.net>`__ for C/C++, and
|
|
|
+ - `jUSB <http://jUSB.sourceforge.net>`__ for Java.
|
|
|
|
|
|
- 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.
|
|
|
+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/
|
|
|
|
|
|
-Configure usbfs into Linux kernels by enabling the *USB filesystem*
|
|
|
-option (CONFIG_USB_DEVICEFS), and you get basic support for user mode
|
|
|
-USB device drivers. Until relatively recently it was often (confusingly)
|
|
|
-called *usbdevfs* although it wasn't solving what *devfs* was. Every USB
|
|
|
-device will appear in usbfs, regardless of whether or not it has a
|
|
|
-kernel driver.
|
|
|
+.. note::
|
|
|
|
|
|
-What files are in "usbfs"?
|
|
|
---------------------------
|
|
|
+ - They were used to be implemented via *usbfs*, but this is not part of
|
|
|
+ the sysfs debug interface.
|
|
|
|
|
|
-Conventionally mounted at ``/proc/bus/usb``, usbfs features include:
|
|
|
+ - 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.
|
|
|
|
|
|
-- ``/proc/bus/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.
|
|
|
+What files are in "devtmpfs"?
|
|
|
+-----------------------------
|
|
|
|
|
|
-- ``/proc/bus/usb/BBB/DDD`` ... magic files exposing the each device's
|
|
|
+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
|
|
|
+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. "usbfs" doesn't (yet) expose those IDs.
|
|
|
-
|
|
|
-Mounting and Access Control
|
|
|
----------------------------
|
|
|
-
|
|
|
-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
|
|
|
-(``/proc/bus/BBB/DDD``) although anyone may read the ``devices`` or
|
|
|
-``drivers`` files. I/O requests to the device also need the
|
|
|
-CAP_SYS_RAWIO capability,
|
|
|
-
|
|
|
-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 *devmode=0666* option) so the driver can
|
|
|
-start whenever it's needed.
|
|
|
-
|
|
|
-The mount options for usbfs, usable in /etc/fstab or in command line
|
|
|
-invocations of *mount*, are:
|
|
|
-
|
|
|
-*busgid*\ =NNNNN
|
|
|
- Controls the GID used for the /proc/bus/usb/BBB directories.
|
|
|
- (Default: 0)
|
|
|
-
|
|
|
-*busmode*\ =MMM
|
|
|
- Controls the file mode used for the /proc/bus/usb/BBB directories.
|
|
|
- (Default: 0555)
|
|
|
-
|
|
|
-*busuid*\ =NNNNN
|
|
|
- Controls the UID used for the /proc/bus/usb/BBB directories.
|
|
|
- (Default: 0)
|
|
|
-
|
|
|
-*devgid*\ =NNNNN
|
|
|
- Controls the GID used for the /proc/bus/usb/BBB/DDD files. (Default:
|
|
|
- 0)
|
|
|
-
|
|
|
-*devmode*\ =MMM
|
|
|
- Controls the file mode used for the /proc/bus/usb/BBB/DDD files.
|
|
|
- (Default: 0644)
|
|
|
-
|
|
|
-*devuid*\ =NNNNN
|
|
|
- Controls the UID used for the /proc/bus/usb/BBB/DDD files. (Default:
|
|
|
- 0)
|
|
|
-
|
|
|
-*listgid*\ =NNNNN
|
|
|
- Controls the GID used for the /proc/bus/usb/devices and drivers
|
|
|
- files. (Default: 0)
|
|
|
-
|
|
|
-*listmode*\ =MMM
|
|
|
- Controls the file mode used for the /proc/bus/usb/devices and
|
|
|
- drivers files. (Default: 0444)
|
|
|
+second server. Pleast note that it doesn't (yet) expose those IDs.
|
|
|
|
|
|
-*listuid*\ =NNNNN
|
|
|
- Controls the UID used for the /proc/bus/usb/devices and drivers
|
|
|
- files. (Default: 0)
|
|
|
-
|
|
|
-Note that many Linux distributions hard-wire the mount options for usbfs
|
|
|
-in their init scripts, such as ``/etc/rc.d/rc.sysinit``, rather than
|
|
|
-making it easy to set this per-system policy in ``/etc/fstab``.
|
|
|
-
|
|
|
-/proc/bus/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 the
|
|
|
-``Documentation/usb/proc_usb_info.txt`` file in your Linux kernel
|
|
|
-sources.
|
|
|
-
|
|
|
-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("/proc/bus/usb/devices", O_RDONLY);
|
|
|
- pfd = { fd, POLLIN, 0 };
|
|
|
- for (;;) {
|
|
|
- /* The first time through, this call will return immediately. */
|
|
|
- poll(&pfd, 1, -1);
|
|
|
-
|
|
|
- /* To see what's changed, compare the file's previous and current
|
|
|
- contents or scan the filesystem. (Scanning is more precise.) */
|
|
|
- }
|
|
|
-
|
|
|
-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.
|
|
|
-
|
|
|
-/proc/bus/usb/BBB/DDD
|
|
|
----------------------
|
|
|
+/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.
|
|
|
+- *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
|
|
|
-------------------------------
|
|
@@ -372,7 +316,7 @@ 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 /proc/bus/usb device files,
|
|
|
+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
|
|
@@ -407,9 +351,7 @@ The ioctl() Requests
|
|
|
--------------------
|
|
|
|
|
|
To use these ioctls, you need to include the following headers in your
|
|
|
-userspace program:
|
|
|
-
|
|
|
-::
|
|
|
+userspace program::
|
|
|
|
|
|
#include <linux/usb.h>
|
|
|
#include <linux/usbdevice_fs.h>
|
|
@@ -422,8 +364,8 @@ 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
|
|
|
-``Documentation/usb/error-codes.txt`` in your kernel sources.)
|
|
|
+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
|
|
@@ -458,14 +400,12 @@ USBDEVFS_CLAIMINTERFACE
|
|
|
|
|
|
USBDEVFS_CONNECTINFO
|
|
|
Says whether the device is lowspeed. The ioctl parameter points to a
|
|
|
- structure like this:
|
|
|
-
|
|
|
- ::
|
|
|
+ structure like this::
|
|
|
|
|
|
- struct usbdevfs_connectinfo {
|
|
|
- unsigned int devnum;
|
|
|
- unsigned char slow;
|
|
|
- };
|
|
|
+ struct usbdevfs_connectinfo {
|
|
|
+ unsigned int devnum;
|
|
|
+ unsigned char slow;
|
|
|
+ };
|
|
|
|
|
|
File modification time is not updated by this request.
|
|
|
|
|
@@ -477,45 +417,41 @@ USBDEVFS_CONNECTINFO
|
|
|
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:
|
|
|
+ modified::
|
|
|
|
|
|
- ::
|
|
|
-
|
|
|
- struct usbdevfs_getdriver {
|
|
|
- unsigned int interface;
|
|
|
- char driver[USBDEVFS_MAXDRIVERNAME + 1];
|
|
|
- };
|
|
|
+ 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);
|
|
|
- }
|
|
|
+ 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.
|
|
|
|
|
@@ -534,11 +470,11 @@ USBDEVFS_RELEASEINTERFACE
|
|
|
the number of the interface (bInterfaceNumber from descriptor); File
|
|
|
modification time is not updated by this request.
|
|
|
|
|
|
- **Warning**
|
|
|
+ .. 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.*
|
|
|
+ *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
|
|
@@ -546,13 +482,13 @@ USBDEVFS_RESETEP
|
|
|
as identified in the endpoint descriptor), with USB_DIR_IN added
|
|
|
if the device's endpoint sends data to the host.
|
|
|
|
|
|
- **Warning**
|
|
|
+ .. 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.
|
|
|
+ *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
|
|
@@ -574,21 +510,19 @@ a time.
|
|
|
|
|
|
USBDEVFS_BULK
|
|
|
Issues a bulk read or write request to the device. The ioctl
|
|
|
- parameter is a pointer to this structure:
|
|
|
-
|
|
|
- ::
|
|
|
+ parameter is a pointer to this structure::
|
|
|
|
|
|
- struct usbdevfs_bulktransfer {
|
|
|
- unsigned int ep;
|
|
|
- unsigned int len;
|
|
|
- unsigned int timeout; /* in milliseconds */
|
|
|
- void *data;
|
|
|
- };
|
|
|
+ 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
|
|
|
+ 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
|
|
|
+ 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.*.
|
|
|
|
|
@@ -600,31 +534,29 @@ USBDEVFS_CLEAR_HALT
|
|
|
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
|
|
|
+ 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;
|
|
|
- };
|
|
|
+ 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
|
|
|
+ ``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).
|
|
|
|
|
@@ -638,22 +570,20 @@ USBDEVFS_RESET
|
|
|
the reset, this rebinds all device interfaces. File modification
|
|
|
time is not updated by this request.
|
|
|
|
|
|
- **Warning**
|
|
|
+.. 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.
|
|
|
+ *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:
|
|
|
+ a pointer to a structure like this::
|
|
|
|
|
|
- ::
|
|
|
-
|
|
|
- struct usbdevfs_setinterface {
|
|
|
- unsigned int interface;
|
|
|
- unsigned int altsetting;
|
|
|
- };
|
|
|
+ struct usbdevfs_setinterface {
|
|
|
+ unsigned int interface;
|
|
|
+ unsigned int altsetting;
|
|
|
+ };
|
|
|
|
|
|
File modification time is not updated by this request.
|
|
|
|
|
@@ -669,11 +599,11 @@ USBDEVFS_SETCONFIGURATION
|
|
|
configuration (bConfigurationValue from descriptor). File
|
|
|
modification time is not updated by this request.
|
|
|
|
|
|
- **Warning**
|
|
|
+.. 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.
|
|
|
+ *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
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -688,7 +618,7 @@ 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
|
|
|
+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
|
|
@@ -702,30 +632,28 @@ 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.
|
|
|
-
|
|
|
-::
|
|
|
+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;
|
|
|
+ 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[];
|
|
|
+ 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
|
|
@@ -746,3 +674,374 @@ USBDEVFS_REAPURBNDELAY
|
|
|
|
|
|
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 the
|
|
|
+``Documentation/usb/proc_usb_info.txt`` file in your Linux kernel
|
|
|
+sources.
|
|
|
+
|
|
|
+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:
|