USB driver hints for Solaris

When putting together my Wacom tablet driver and others, I hit a few conceptual walls in understanding USB better. So I thought I would distill a few critical points here as I go. Sure, you could read the full USB 1.1 specification but that would most likely give you a headache ;-) So read the tips here to get you oriented.

Assumptions

I assume that you have had SOME exposure to solaris driver writing. If not, you should probably first go read Sun's "Writing Device Drivers" document. Search the online docs at oracle, or see if the link on my TIPS page is up to date.

For a slightly condensed version, you might try Sun's Driver writer orientation. (This is actually titled "Solaris OS on x86 Platforms - Device Driver Writer's Orientation", and the link is still valid as of Oct 2011)

You might also want to read my Solaris driver developer tips

Data Transfer Types

The key thing to keep in mind is that there are specific types of data transfer allowed with a USB device. Not all devices support all types of transfer. In fact, most devices will only
Control data
Stuff to tweak the device with, or get special info about it. All devices must support control messages
Bulk data
For when you want to move "large" chunks of data. You don't care too much when it gets there, as long as it gets there.
"isochronos" data
Basically, real-time and/or non-critical data. Think of it as streaming life video. You dont care too much if you drop a frame or two, you just want the data to keep coming
Interrupt data
"Interrupt-driven". EG: the user presses the "abort" key on the device.

Data Pipes

To use one of the above data transfer types, you first have to open a pipe. A "Pipe" is sort of like a TCP socket connection. You have to open up a connection before you can start sending data. You cannot just start poking at registers somewhere.

To open a pipe, you have to first know which endpoint on the device to use. (with the exception of a control pipe, which is special). When first starting to write a USB device driver, if you do not already know the endpoint idenfiers, you must query the device for which endpoints it has, check the type of each and use the appropriate one. Make sure that you check that the one you want is available. For example, a graphics tablet will probably not offer a "bulk transfer" endpoint at all.

Interfaces and 'Alt'ernate settings

Every USB device has at least one 'interface'. An interface is anything that has a unique USB ID, even though it has a single physical packaging. For example, a combined keyboard+mouse may be a single physical box, but there would be two 'interfaces'.

Any particular 'interface', may have multiple 'alternate' settings (Although most devices only have 1 setting). If you configure an interface to a non-default 'alternate' setting, you may have a completely new set of endpoints available to you. Unfortunately, it is not a simple thing to configure an alternate config under the current Solaris USB framework.


Tips for Solaris 8 USB

(as of June 2002)

The following tips are all specific to the "current" solaris USB framework. The Sun USB team has announced that there is a new USB framework coming down the pike. No official date for it has been set, so it seems safe to assume it will not be released for a few months.

Getting an endpoint

Currently with solaris 8, you have to use usb_parse_endpoint_descr() to get an "endpoint descriptor". Once you have that, you can pass the descriptor to usb_pipe_open() to open up a pipe to use. If you want a control pipe, you pass in a NULL endpoint descriptor.
Note: the upcoming new solaris USB API does not use usb_parse_endpoint_descr().

Reading data

You should read the comments in /usr/include/sys/usb/usbai.h, particularly the "Data Transfer Management" section. Some critical excerpts:

Writing data

The same comment from above is still true:
"ALL data transfer[s] are asynchronous"
You first call the appropriate send function, and then wait for a callback to trigger if you care about the result of the send.

Note: It appears that the "*bulk*" routines do byteswapping as appropriate. However, the other ones (eg: xxx_ctrl_xxx) do not.


Written by:Philip Brown
Visit the Solaris driver pages at bolthole.com. Or Search Bolthole.com