Table of Contents
When a USB device is attached to a port, either on the host controller or on a hub the USB system performs several actions:
Configures USB address of the device
Reads the device configuration
Checks power and bandwidth requirements do not exceed available resources.
Create necessary USB resources from devices reported configuration.
Searches for an appropriate driver to handle the device
Each USB device carries identification information so device drivers can determine the suitability. The USB committee define class, sub-class and protocol codes in the relevant standards. The device also carries a unique manufacturer and product code for additional identification.
The USB system searches for a device driver as follows:
Sends a message to all listening handlers for a driver for a specific vendor and product ID.
Searches the driver path (if set) for a driver for a specific vendor and product ID
Sends a message to all listening handlers for a device driver for a general class.
Searches the driver path (if set) for a device driver for a general class.
Device is marked as unclaimed and kept for future drivers to claim.
Once an appropriate device driver is located the search does not continue.
Only module based drivers can have a message handler and hence only this form of device driver may be sensibly loaded before the device is connected. This makes module drivers ideal for operation where devices are required to operate the system, are inserted and removed often or need to operate outside a multi tasking environment.
Application drivers have fewer constraints on their environment than modules but are more limited in their use. Application drivers can either be run by the USB system when a device is connected or can claim the device from the unclaimed pool when the driver is started by the user.
The driver should perform its required module initialization. And in addition needs to register a message handler (see the section Section 3) with the USB system. The module may be loaded at any time even before the USB system and may remain resident after the USB system has been removed. The module should listen for the relevant service calls for USB core starting (Service_USB 16 - USB system module started) and stopping (Service_USB 17 - USB system module stopped).
On receipt of the message, the device driver should check the relevant fields in the message data to ascertain if the device being offered can be handled by the driver. The driver should ignore the message if the type field is set to USBMSG_NEWDEV_CURRENTDRIVER to indicate the message is intended for currently attached drivers. The message is passed around first with the try field set to USBMSG_NEWDEV_TRY_VENDOR to see if there are any vendor specific drivers available, and then with the try field set to USBMSG_NEWDEV_TRY_CLASS to specify the message is intended for drivers for an specific class and subclass.
If the driver can service the device, it should claim the message to stop any further drivers being informed. The driver should do minimal device startup in the message handler to allow the USB system to continue.
The module should listen for the device unplug message to ascertain when the device has been removed, and free all resources associated with the device.
The module should free all USB resources on exit, the USB system will not perform any automatic garbage collection. Any outstanding requests must either be cleared or allowed to complete before the module exits to avoid system errors
When the USB system has identified that a driver must be started from a file-system. The USBDeviceDriver$Path path will be searched for a driver. The drivers must be stored in application directories (i.e. are preceded by an ! and contain a !Run file) which are named according to the following specification.
For a class driver, the directory name is !cc-sc-ppU
For a vendor/product driver, the directory name is in the form of !cc-sc-ppU.!vvvv-iiii
Code | Name | Base | Pad Length |
---|---|---|---|
cc | class code | hex | 2 |
sc | sub-class code | hex | 2 |
pp | Protocol code | hex | 2 |
vvvv | Vendor Code | hex | 4 |
iiii | Product Code | hex | 4 |
The default contents of the USBDeviceDriver$Path are the DevDriver directory inside the booted copy of !USB. The device driver can either add the directory containing itself to this path, or be installed within the !USB.DevDriver directory. Device drivers should not modify any other part of !USB without prior permission.
Arguments are passed on the command line containing the relevant information about the device.
Log file / temporary file the textual name of the host controller the device is on the device number in decimal
These are followed by a list of endpoints, each item being joined to the next by a '-' character, in the from of two decimals separated by a '/' character. The first entry in the item is the endpoint reference, the second being the endpoint number, containing info about the type (in,out,bulk,etc).
Further parameters are prefixed by switches
Format | Entry | Type |
---|---|---|
-s | Serial number | serial number of device |
-m | Vendor ID | vendor id (decimal) |
-p | product ID | product id (decimal) |
-devmsg | ptr to msg | pointer to the device message that launched the driver |
The devmsg field should be stored for later use if the driver wishes to release the device once finished with it, or can be used to extract the same data as passed in to the driver via the command line.
A device driver should return as soon as possible after being started, and therefore if the driver is not able to multi-task it should start itself within a task window to allow the rest of the system to continue.
The unclaimed devices pool keeps device that where not claimed by any device driver, and can be accessed using a USB message to find and manage entries in it.
The driver should create the relevant message, send it and inspect the results to see what is available. If the driver wants to use the device, it should first ensure it can claim it before attempting further communications. This will ensure nothing else on the system will interfere with the drivers use of the device.
Once the driver has finished with the device, it is at the discretion of the driver whether it wants to return the device to the unclaimed pool or not. If the driver does not wish to, it should ensure the device is removed from the USB system by issuing a drop message, otherwise it should send a release message to return the device to the pool.
Once a device has been physically removed, the system ensures that it will not be returned to the unclaimed pool.