The USB family provides support for, and access to, devices attached to a Universal Serial Bus (USB).
Two basic types of drivers are clients of this family: kernel-mode drivers and user-mode drivers. Kernel-mode drivers are required when the clients of the driver also reside in the kernel (such as HID devices, mass storage devices, or networking devices). User-mode drivers are preferred when only one process has access to the device (for example printers and scanners).
Bundle identifier:
com.apple.iokit.IOUSBFamily
Headers in:
Kernel resident: Kernel.framework/Headers/IOKit/usb/
Device interface: IOKit.framework/Headers/usb
References and specifications:
USB.org—http://www.usb.org; see especially USB Common Class Specification, revision 1.0, available for download at http://www.usb.org/developers/devclass_docs/usbccs10.pdf
Apple Developer Connection—http://developer.apple.com/hardwaredrivers/usb/index.html
Class hierarchy:

Device interface:
User mode clients use an API which is part of the I/O Kit framework; this API is defined in IOKit/usb/IOUSBLib.h. Clients use user mode abstractions of the IOUSBDevice and IOUSBInterface classes found in the kernel in order to communicate with the USB device or USB interface.
Kernel-resident drivers:
Kernel drivers for physical USB devices can be written for either USB devices or for USB interfaces. A physical USB device consists of a device descriptor that can describe any number of interfaces. When writing a kernel-resident driver, you need to decide if the driver is to control the whole USB device or if it is to control only an interface of a USB device.
The USB family for kernel-resident drivers consists of three main classes:
IOUSBDevice: The IOUSBDevice class is an abstraction of a physical USB device. There is one IOUSBDevice class instantiated for every USB device connected to the bus. The provider for an IOUSBDevice object is an IOUSBController object (which is an abstraction of a USB controller).
IOUSBInterface: The IOUSBInterface class is an abstraction of one of the interfaces of a USB device. There is one of these classes instantiated for every interface in a device. When it is created, the IOUSBInterface creates IOUSBPipe objects for each endpoint described in the interface descriptor of the interface. The provider for an IOUSBInterface object is an IOUSBDevice object.
IOUSBPipe: The IOUSBPipe class contains the methods that are used for communicating with a USB device or a USB interface. There is one IOUSBPipe object created for the default control endpoint and an additional one for each endpoint described in the interface descriptor. The provider for an IOUSBPipe object is an IOUSBInterface object.
Kernel-resident USB drivers are clients of the family that provides the transport services and are members of the family from which they get their class inheritance. For example, a driver for a USB keyboard is a client of the IOUSBInterface object (that is, the IOUSBInterface object is the provider for the driver) but the keyboard driver is a member of the IOHIDFamily. The USB family provides the mechanism for getting at the key presses in the keyboard. The keyboard driver supports methods from the HID family for sending those key presses to the event system.
As mentioned above, you can write a driver to match against a USB device or a USB interface. The IOUSBDevice or IOUSBInterface classes are the providers for the drivers. The drivers themselves can be members of a separate family (such as the IOHIDFamily or IOAudioFamily) or can be members of the IOService family.
Power management:
All in-kernel USB device drivers should implement at least basic power management to increase power saving in the system. In Mac OS X v10.5, the USB family introduced the IOUSBHubPolicyMaker object, which is an abstraction of a USB hub that includes power-management capabilities. When you develop a USB device driver to run in Mac OS X v10.5 and later and you call joinPMtree, your driver is attached into the power plane as a power child of an IOUSBHubPolicyMaker object. (In earlier versions of Mac OS X, the power parent of a USB device driver was an IOUSBController object representing the controller to which the device was attached.)
Your USB device driver can communicate with its IOUSBHubPolicyMaker object to determine the power state of its hub. This can be useful if, for example, you need to handle an imminent shutdown differently from a restart. The IOUSBHubPolicyMaker object supports the following five power states for a hub:
On. The hub is fully functional and at least one of its ports is active (that is, not suspended).
Sleep. If the hub supports sleep, its ports are inactive and it is not supplying power to any attached devices; if not, the sleep state is identical to the off state.
Doze. This is an idle power-saving state a hub can enter when all its ports are suspended or disconnected and all attached devices are in either the off or doze state. Not all hubs support the doze state.
Off. The hub enters this state when the system is about to shut down.
Restart. This state is identical to the off state, except that a hub enters it when the system is about to restart.
USB devices seldom support more than the first four of these power states, and many support only on, sleep, and off. If you’re developing a driver for a USB device that supports doze, you should call SuspendDevice when you switch the device’s power state to doze, so the hub can suspend the port to which the device is attached. If the drivers for all the devices attached to a hub do this, the hub can enter the doze state, which can result in significant power saving for the system. However, if your driver calls SuspendDevice without also changing the device’s power state to doze, you prevent the hub from entering the doze state and saving power.
If the hub to which your device is attached does not support sleep, the device must go to its off state when the system goes to sleep. Of course, if your device does not support sleep, it must also go to its off state when the system goes to sleep, even if its hub does support sleep.
During a power-state change, note that a USB hub's power state is not updated until the hub receives a powerChangeDone call, which does not happen until after all downstream hubs and devices have received their powerChangeDone calls. This means that if you use the getPowerState call introduced in Mac OS X v10.5 to get an upstream hub’s current power state, you might receive stale power-state information. However, if your device is changing to its on state, you can assume that the upstream hubs are actually on, even if their power-state values haven’t yet been updated.
Driver matching: The USB family uses the USB Common Class Specification, revision 1.0 to match devices and interfaces to drivers (for a link to this specification, see the section above titled “References and specifications”). The driver should use the keys defined in this specification to create a matching dictionary that defines a particular driver personality. There are two tables of keys in the specification. The first table contains keys for finding devices and the second table contains keys for finding interfaces. Both tables present the keys in order of specificity: the first key in each table defines the most specific search and the last key defines the broadest search. Each key consists of the combination of elements listed in the left column of the table.
For a successful match, you must add the elements of exactly one key to your personality. If your personality contains a combination of elements not defined by any key, the matching process will not find your driver. For example, if you’re attempting to match a device and you add values representing that device’s vendor, product, and protocol to your matching dictionary, the matching process is unsuccessful even if a device with those same values in its device descriptor is currently represented by an IOUSBDevice nub in the I/O Registry. This is because there is no key that combines the elements of vendor number, product number, and protocol.
Last updated: 2007-05-17