Utility Functions
This section describes several functions that are of general use.
Device Configuration Facilities
This section describes functions related to device configuration.
Getting Interface Numbers
If you are using a multiple-interface device where the usb_mid(7D) driver is
making only one of its interfaces available to the calling driver, you might
need to know the number of the interface to which the calling driver
is bound. Use the usb_get_if_number(9F) function to do any of the following
tasks:
Return the number of the interface to which the calling driver is bound. The usb_get_if_number(9F) function returns an interface number greater than zero in this case.
Discover that the calling driver manages an entire multi-interface device. The driver is bound at the device level so that usb_mid has not split it. The usb_get_if_number(9F) function returns USB_DEVICE_NODE in this case.
Discover that the calling driver manages an entire device by managing the only interface that device offers in its current configuration. The usb_get_if_number(9F) function returns USB_COMBINED_NODE in this case.
Managing Entire Devices
If a driver manages an entire composite device, that driver can bind to
the entire device by using a compatible name that contains vendor ID, product
ID, and revision ID. A driver that is bound to an entire
composite device must manage all the interfaces of that device as a nexus
driver would. In general, you should not bind your driver to an entire
composite device. Instead, you should use the generic multiple-interface driver usb_mid(7D).
Use the usb_owns_device(9F) function to determine whether a driver owns an entire device.
The device might be a composite device. The usb_owns_device(9F) function returns TRUE
if the driver owns the entire device.
Multiple-Configuration Devices
USB devices make only a single configuration available to the host at any
particular time. Most devices support only a single configuration. However, a few USB
devices support multiple configurations.
Any device that has multiple configurations is placed into the first configuration for
which a driver is available. When seeking a match, device configurations are considered
in numeric order. If no matching driver is found, the device is set
to the first configuration. In this case, the usb_mid driver takes over the
device and splits the device into interface nodes. Use the usb_get_cfg(9F) function to
return the current configuration of a device.
You can use either of the following two methods to request a
different configuration. Using either of these two methods to modify the device configuration ensures
that the USBA module remains in sync with the device.
Use the cfgadm_usb(1M) command.
Call the usb_set_cfg(9F) function from the driver.
Because changing device configuration affects an entire device, the client driver must meet all of the following criteria to call the usb_set_cfg(9F) function successfully:
The client driver must own the entire device.
The device must have no child nodes, because other drivers could drive the device through them.
All pipes except the default pipe must be closed.
The device must have multiple configurations.
Caution - Do not change the device configuration by doing a SET_CONFIGURATION USB request
manually. Using a SET_CONFIGURATION request to change the configuration is not supported.
Modifying or Getting the Alternate Setting
A client driver can call the usb_set_alt_if(9F) function to change the selected alternate
setting of the currently selected interface. Be sure to close all pipes that
were opened explicitly. When switching alternate settings, the usb_set_alt_if(9F) function verifies that
only the default pipe is open. Be sure the device is settled before
you call usb_set_alt_if(9F).
Changing the alternate setting can affect which endpoints and which class-specific and vendor-specific
descriptors are available to the driver. See The Descriptor Tree for more information about endpoints and
descriptors.
Call the usb_get_alt_if(9F) function to retrieve the number of the current alternate setting.
Note - When you request a new alternate setting, a new configuration, or a new
interface, all pipes except the default pipe to the device must be closed.
This is because changing an alternate setting, a configuration, or an interface changes
the mode of operation of the device. Also, changing an alternate setting, a
configuration, or an interface changes the device's presentation to the system.
Other Utility Functions
This section describes other functions that are useful in USB device drivers.
Retrieving a String Descriptor
Call the usb_get_string_descr(9F) function to retrieve a string descriptor given its index. Some
configuration, interface, or device descriptors have string IDs associated with them. Such descriptors contain
string index fields with nonzero values. Pass a string index field value to
the usb_get_string_descr(9F) to retrieve the corresponding string.
Pipe Private Data Facility
Each pipe has one pointer of space set aside for the client
driver's private use. Use the usb_pipe_set_private(9F) function to install a value. Use the usb_pipe_get_private(9F)
function to retrieve the value. This facility is useful in callbacks, when pipes
might need to bring their own client-defined state to the callback for specific processing.
Clearing a USB Condition
Use the usb_clr_feature(9F) function to do the following tasks:
Issue a USB CLEAR_FEATURE request to clear a halt condition on an endpoint.
Clear a remote wakeup condition on a device.
Clear a device-specific condition at a device, interface, or endpoint level.
Getting Device, Interface, or Endpoint Status
Use the usb_get_status(9F) function to issue a USB GET_STATUS request to retrieve the
status of a device, interface, or endpoint.
Device status. Self-powered and remote-wakeup-enabled.
Interface status. Returns zero, per USB 2.0 specification.
Endpoint status. Endpoint halted. This status indicates a functional stall. A halt must be cleared before the device can operate again.
A protocol stall indicates that an unsupported control pipe request has been made. A protocol stall is cleared automatically at the beginning of the next control transfer.
Getting the Bus Address of a Device
Use the usb_get_addr(9F) function to get the USB bus address of a
device for debugging purposes. This address maps to a particular USB port.