USB (Universal Serial Bus) is a hardware and protocol
specification for interconnecting various devices to a host
controller. We supply a USB stack that implements the USB
protocol and allows user-written class drivers to
communicate with USB devices.

We also supply a USB driver library (usbd_*())
for class drivers to use in order to communicate with the
USB stack. Note that a class driver can be considered a
“client” of the USB stack.

The stack is implemented as a standalone process that
registers the pathname of /dev/io-usb/io-usb (by
default). Currently, the stack contains the hub class driver
within it.

The client library provides functions to allocate data
buffers in shared memory; the stack manages these data
buffers and gives the client library access to them. This
means that all data transfers must use the provided buffers.

As a result, a class driver must reside on the same
physical node as the USB stack. The clients of the
class driver, however, can be network-distributed. The
advantage of this approach is that no additional memory copy
occurs between the time that the data is received by the USB
stack and the time that it's delivered to the class driver
(and vice versa).

With the QNX Neutrino OS, the USB enumerator attaches to the
USB stack and waits for device insertions. When a device
insertion is detected, the enumerator looks in the
configuration manager's database to see which class driver
it should start. It then starts the appropriate driver,
which provides for that class of device. For example, a USB
Ethernet class driver would register with io-pkt*
and bring the interface up.

For small, deeply embedded systems, the enumerator isn't
required. The class drivers can be started individually
— they'll wait around for their particular devices to
be detected by the stack. At that point, they'll provide the
appropriate services for that class of device, just as if
they'd been started by the enumerator. When a device is
removed, the enumerator will shut down the class driver.

In this context, the term “pipe” is a
USB-specific term that has nothing to do with
standard POSIX “pipes” (as used, for example,
in the command line ls | more). In USB
terminology, a “pipe” is simply a handle;
something that identifies a connection to an endpoint.