13.2. USB and Sysfs
Due to the complexity of a single
USB physical device, the
representation of that device in sysfs is also quite complex. Both
the physical USB device (as represented by a
struct usb_device) and the
individual USB interfaces (as represented by a
struct usb_interface) are shown
in sysfs as individual devices. (This is because both of those
structures contain a struct
device structure.) As an example, for a simple USB
mouse that contains only one USB interface, the following would be
the sysfs directory tree for that device:
/sys/devices/pci0000:00/0000:00:09.0/usb2/2-1
|-- 2-1:1.0
| |-- bAlternateSetting
| |-- bInterfaceClass
| |-- bInterfaceNumber
| |-- bInterfaceProtocol
| |-- bInterfaceSubClass
| |-- bNumEndpoints
| |-- detach_state
| |-- iInterface
| `-- power
| `-- state
|-- bConfigurationValue
|-- bDeviceClass
|-- bDeviceProtocol
|-- bDeviceSubClass
|-- bMaxPower
|-- bNumConfigurations
|-- bNumInterfaces
|-- bcdDevice
|-- bmAttributes
|-- detach_state
|-- devnum
|-- idProduct
|-- idVendor
|-- maxchild
|-- power
| `-- state
|-- speed
`-- version
The struct usb_device is
represented in the tree at:
/sys/devices/pci0000:00/0000:00:09.0/usb2/2-1
while the USB interface for the mouse—the interface that the
USB mouse driver is bound to—is located at the directory:
/sys/devices/pci0000:00/0000:00:09.0/usb2/2-1/2-1:1.0
To help understand what this long device path means, we describe how
the kernel labels the USB devices.
The first USB device is a root hub. This is the USB controller,
usually contained in a PCI device. The controller is so named because
it controls the whole USB bus connected to it. The controller is a
bridge between the PCI bus and the USB bus, as well as being the
first USB device on that bus.
All
root hubs are assigned a unique number
by the USB core. In our example, the root hub is called
usb2, as it is the second root hub that was
registered with the USB core. There is no limit on the number of root
hubs that can be contained in a single system at any time.
Every device that is on a USB bus takes the number of the root hub as
the first number in its name. That is followed by a
- character and then the number of the port that
the device is plugged into. As the device in our example is plugged
into the first port, a 1 is added to the name. So
the device name for the main USB mouse device is
2-1. Because this USB device contains one
interface, that causes another device in the tree to be added to the
sysfs path. The naming scheme for USB interfaces is the device name
up to this point: in our example, it's
2-1 followed by a colon and the USB configuration
number, then a period and the interface number. So for this example,
the device name is 2-1:1.0 because it is the first
configuration and has interface number zero.
So to summarize, the USB sysfs device
naming scheme is:
root_hub-hub_port:config.interface
As the devices go further down in the USB tree, and as more and more
USB hubs are used, the hub port number is added to the string
following the previous hub port number in the chain. For a two-deep
tree, the device name looks like:
root_hub-hub_port-hub_port:config.interface
As can be seen in the previous directory listing of the USB device
and interface, all of the USB specific information is available
directly through sysfs (for example, the idVendor, idProduct, and
bMaxPower information). One of these files,
bConfigurationValue, can be written to in order
to change the active USB configuration that is being used. This is
useful for devices that have multiple configurations, when the kernel
is unable to determine what configuration to select in order to
properly operate the device. A number of USB modems need to have the
proper configuration value written to this file in order to have the
correct USB driver bind to the device.
Sysfs does not expose all of the different parts of a USB device, as
it stops at the interface level. Any alternate configurations that
the device may contain are not shown, as well as the details of the
endpoints associated with the interfaces. This information can be
found in the usbfs filesystem, which is mounted
in the /proc/bus/usb/ directory on the system.
The file /proc/bus/usb/devices does show all of
the same information exposed in sysfs, as well as the alternate
configuration and endpoint information for all USB devices that are
present in the system. usbfs also allows
user-space programs to directly talk to USB devices, which has
enabled a lot of kernel drivers to be moved out to user space, where
it is easier to maintain and debug. The USB scanner driver is a good
example of this, as it is no longer present in the kernel because its
functionality is now contained in the user-space SANE library
programs.
|