JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Writing Device Drivers     Oracle Solaris 11.1 Information Library
search filter icon
search icon

Document Information

Preface

Part I Designing Device Drivers for the Oracle Solaris Platform

1.  Overview of Oracle Solaris Device Drivers

2.  Oracle Solaris Kernel and Device Tree

3.  Multithreading

4.  Properties

5.  Managing Events and Queueing Tasks

6.  Driver Autoconfiguration

7.  Device Access: Programmed I/O

8.  Interrupt Handlers

9.  Direct Memory Access (DMA)

10.  Mapping Device and Kernel Memory

11.  Device Context Management

12.  Power Management

13.  Hardening Oracle Solaris Drivers

14.  Layered Driver Interface (LDI)

Part II Designing Specific Kinds of Device Drivers

15.  Drivers for Character Devices

16.  Drivers for Block Devices

17.  SCSI Target Drivers

18.  SCSI Host Bus Adapter Drivers

19.  Drivers for Network Devices

20.  USB Drivers

USB in the Oracle Solaris Environment

USBA 2.0 Framework

USB Client Drivers

Binding Client Drivers

How USB Devices Appear to the System

USB Devices and the Oracle Solaris Device Tree

Compatible Device Names

Devices With Multiple Interfaces

Devices With Interface-Association Descriptors

Checking Device Driver Bindings

Basic Device Access

Before the Client Driver Is Attached

The Descriptor Tree

Registering Drivers to Gain Device Access

Device Communication

USB Endpoints

The Default Pipe

Pipe States

Opening Pipes

Closing Pipes

Data Transfer

Synchronous and Asynchronous Transfers and Callbacks

Requests

Flushing Pipes

Device State Management

Hotplugging USB Devices

Hotplug Callbacks

Hot Insertion

Hot Removal

Hot Reinsertion

Power Management

Device Power Management

System Power Management

Serialization

Utility Functions

Device Configuration Facilities

Getting Interface Numbers

Managing Entire Devices

Multiple-Configuration Devices

Modifying or Getting the Alternate Setting

Other Utility Functions

Retrieving a String Descriptor

Pipe Private Data Facility

Clearing a USB Condition

Getting Device, Interface, or Endpoint Status

Getting the Bus Address of a Device

Sample USB Device Drivers

21.  SR-IOV Drivers

Part III Building a Device Driver

22.  Compiling, Loading, Packaging, and Testing Drivers

23.  Debugging, Testing, and Tuning Device Drivers

24.  Recommended Coding Practices

Part IV Appendixes

A.  Hardware Overview

B.  Summary of Oracle Solaris DDI/DKI Services

C.  Making a Device Driver 64-Bit Ready

D.  Console Frame Buffer Drivers

E.  pci.conf File

Index

Binding Client Drivers

This section discusses binding a driver to a device. It discusses compatible device names for devices with single interfaces and devices with multiple interfaces.

How USB Devices Appear to the System

A USB device can support multiple configurations. Only one configuration is active at any given time. The active configuration is called the current configuration.

A configuration can have more than one interface, possibly with intervening interface-associations that group two or more interfaces for a function. All interfaces of a configuration are active simultaneously. Different interfaces might be operated by different device drivers.

An interface can represent itself to the host system in different ways by using alternate settings. Only one alternate setting is active for any given interface.

Each alternate setting provides device access through endpoints. Each endpoint has a specific purpose. The host system communicates with the device by establishing a communication channel to an endpoint. This communication channel is called a pipe.

USB Devices and the Oracle Solaris Device Tree

If a USB device has one configuration, one interface, and device class zero, the device is represented as a single device node. If a USB device has multiple interfaces, the device is represented as a hierarchical device structure. In a hierarchical device structure, the device node for each interface is a child of the top-level device node. An example of a device with multiple interfaces is an audio device that presents simultaneously to the host computer both an audio control interface and an audio streaming interface. The audio control interface and the audio streaming interface each could be controlled by its own driver.

Compatible Device Names

The Oracle Solaris software builds an ordered list of compatible device names for USB binding based on identification information kept within each device. This information includes device class, subclass, vendor ID, product ID, revision, and protocol. See http://www.usb.org/home for a list of USB classes and subclasses.

This name hierarchy enables binding to a general driver if a more device-specific driver is not available. An example of a general driver is a class-specific driver. Device names that begin with usbif designate single interface devices. See Example 20-1 for examples. The USBA 2.0 framework defines all compatible names for a device. Use the prtconf command to display these device names, as shown in Example 20-2.

The following example shows an example of compatible device names for a USB mouse device. This mouse device represents a combined node entirely operated by a single driver. The USBA 2.0 framework gives this device node the names shown in the example, in the order shown.

Example 20-1 USB Mouse Compatible Device Names

1. 'usb430,100.102'      Vendor 430, product 100, revision 102
2. 'usb430,100'      Vendor 430, product 100
3. 'usbif430,class3.1.2' Vendor 430, class 3, subclass 1, protocol 2
4. 'usbif430,class3.1'   Vendor 430, class 3, subclass 1
5. 'usbif430,class3'     Vendor 430, class 3
6. 'usbif,class3.1.2'    Class 3, subclass 1, protocol 2
7. 'usbif,class3.1'      Class 3, subclass 1
8. 'usbif,class3'    Class 3

Note that the names in the above example progress from the most specific to the most general. Entry 1 binds only to a particular revision of a specific product from a particular vendor. Entries 3, 4, and 5 are for class 3 devices manufactured by vendor 430. Entries 6, 7, and 8 are for class 3 devices from any vendor. The binding process looks for a match on the name from the top name down. To bind, drivers must be added to the system with an alias that matches one of these names. To get a list of compatible device names to which to bind when you add your driver, check the compatible property of the device in the output from the prtconf -vp command.

The following example shows compatible property lists for a keyboard and a mouse. Use the prtconf -D command to display the bound driver.

Example 20-2 Compatible Device Names Shown by the Print Configuration Command

# prtconf -vD | grep compatible
            compatible: 'usb430,5.200' + 'usb430,5' + 'usbif430,class3.1.1'
+ 'usbif430,class3.1' + 'usbif430,class3' + 'usbif,class3.1.1' +
'usbif,class3.1' + 'usbif,class3'
            compatible: 'usb2222,2071.200' + 'usb2222,2071' +
'usbif2222,class3.1.2' + 'usbif2222,class3.1' + 'usbif2222,class3' +
'usbif,class3.1.2' + 'usbif,class3.1' + 'usbif,class3'

Use the most specific name you can to more accurately identify a driver for a device or group of devices. To bind drivers written for a specific revision of a specific product, use the most specific name match possible. For example, if you have a USB mouse driver written by vendor 430 for revision 102 of their product 100, use the following command to add that driver to the system:

add_drv -n -i '"usb430,100.102"' specific_mouse_driver

To add a driver written for any USB mouse (class 3, subclass 1, protocol 2) from vendor 430, use the following command:

add_drv -n -i '"usbif430,class3.1.2"' more_generic_mouse_driver

If you install both of these drivers and then connect a compatible device, the system binds the correct driver to the connected device. For example, if you install both of these drivers and then connect a vendor 430, model 100, revision 102 device, this device is bound to specific_mouse_driver. If you connect a vendor 430, model 98 device, this device is bound to more_generic_mouse_driver. If you connect a mouse from another vendor, this device also is bound to more_generic_mouse_driver. If multiple drivers are available for a specific device, the driver binding framework selects the driver with the first matching compatible name in the compatible names list.

Devices With Multiple Interfaces

Composite devices are devices that support multiple interfaces. Composite devices have a list of compatible names for each interface. This compatible names list ensures that the best available driver is bound to the interface. The most general multiple interface entry is usb,device.

For a USB audio composite device, the compatible names are as follows:

1. 'usb471,101.100'     Vendor 471, product 101, revision 100
2. 'usb471,101'         Vendor 471, product 101
3. 'usb,device'         Generic USB device

The name usb,device is a compatible name that represents any whole USB device. The usb_mid(7D) driver (USB multiple-interface driver) binds to the usb,device device node if no other driver has claimed the whole device. The usb_mid driver creates a child device node for each interface of the physical device. The usb_mid driver also generates a set of compatible names for each interface. Each of these generated compatible names begins with usbif. The system then uses these generated compatible names to find the best driver for each interface. In this way, different interfaces of one physical device can be bound to different drivers.

For example, the usb_mid driver binds to a multiple-interface audio device through the usb,device node name of that audio device. The usb_mid driver then creates interface-specific device nodes. Each of these interface-specific device nodes has its own compatible name list. For an audio control interface node, the compatible name list might look like the list shown in the following example.

Example 20-3 USB Audio Compatible Device Names

1. 'usbif471,101.100.config1.0' Vend 471, prod 101, rev 100, cnfg 1, iface 0
2. 'usbif471,101.config1.0'     Vend 471, product 101, config 1, interface 0
3. 'usbif471,class1.1.0'    Vend 471, class 1, subclass 1, protocol 0
4. 'usbif471,class1.1'      Vend 471, class 1, subclass 1
5. 'usbif471,class1'        Vend 471, class 1
6. 'usbif,class1.1.0'       Class 1, subclass 1, protocol 0
7. 'usbif,class1.1'         Class 1, subclass 1
8. 'usbif,class1'           Class 1

Use the following command to bind a vendor-specific, device-specific client driver named vendor_model_audio_usb to the vendor-specific, device-specific configuration 1, interface 0 interface compatible name shown in Example 20-3.

add_drv -n -i '"usbif471,101.config1.0"' vendor_model_audio_usb

Use the following command to bind a class driver named audio_class_usb_if_driver to the more general class 1, subclass 1 interface compatible name shown in Example 20-3:

add_drv -n -i '"usbif,class1.1"' audio_class_usb_if_driver

Use the prtconf -D command to show a list of devices and their drivers. In the following example, the prtconf -D command shows that the usb_mid driver manages the audio device. The usb_mid driver is splitting the audio device into interfaces. Each interface is indented under the audio device name. For each interface shown in the indented list, the prtconf -D command shows which driver manages the interface.

audio, instance #0 (driver name: usb_mid)
    sound-control, instance #2 (driver name: usb_ac)
    sound, instance #2 (driver name: usb_as)
    input, instance #8 (driver name: hid)

Devices With Interface-Association Descriptors

If the device includes an interface-association descriptor, the device tree can be parsed at the following three levels:

The usb_mid driver creates an ia (interface association) node for each ia. The compatible names of ia nodes generally begin with usbia. The name usb,ia is a compatible name that represents any ia as the tail of the compatible names. The usb_ia driver is bound to an ia node if no other driver has claimed this ia. The usb_ia driver creates a child node for each interface. An interface node as the child node of an ia node has the same properties with an interface node as the child of a device node.

Example 20-4 USB Video Interface Association Compatible Names

1. 'usbia46d,8c9.5.config1.0' vend 46d, prod 8c9, rev 5, cnfg 1, first_if_in_ia 0
2. 'usbia46d,8c9.config1.0'   vend 46d, prod 8c9, cnfg 1, first_if_in_ia 0
3. 'usbia46d,classe.3.0'      vend 46d, class e, subclass 3, protocol 0
4. 'usbia46d,classe.3'        vend 46d, class e, subclass 3
5. 'usbia46d,classe'          vend 46d, class e
6. 'usbia,classe.3.0'         class e, subclass 3, protocol 0
7. 'usbia,classe.3'           class e, subclass 3
8. 'usbia,classe'             class e
9. 'usb,ia'                   by default

Use the following command to bind a vendor-specific, device-specific client driver named vendor_model_video_usb to the vendor-specific, device-specific configuration 1, first_if_in_ia 0 compatible name shown in Example 20-4:

add_drv -n -i '"usbia46d,8c9.config1.0"' vendor_model_video_usb

Use the following command to bind a class driver named video_class_usb_ia_driver to the more general class e compatible names shown in Example 20-4:

add_drv -n -i '"usbia,classee"' video_class_usb_ia_driver

In the following example, the prtconf -D command shows a device tree of a webcam with ia of video and audio. The usb_mid driver manages the device and creates two ia respectively for video and audio. A video driver usbvc is bound to the video ia, and audio drivers are bound to the interface of the audio ia.

miscellaneous, instance #28 (driver name: usb_mid)
    video, instance #24 (driver name: usbvc)
    audio, instance #30 (driver name: usb_ia)
        sound-control, instance #38 (driver name: usb_ac)
        sound, instance #47 (driver name: usb_as)

Checking Device Driver Bindings

The file /etc/driver_aliases contains entries for the bindings that already exist on a system. Each line of the /etc/driver_aliases file shows a driver name, followed by a space, followed by a device name. Use this file to check existing device driver bindings.


Note - Do not edit the /etc/driver_aliases file manually. Use the add_drv(1M) command to establish a binding. Use the update_drv(1M) command to change a binding.