USB Device Driver Stack for OS/2 Warp
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
Version | Date | Summary of Changes |
---|---|---|
1.0 | 02/22/02 | Initial version of document |
1.1 | 01/20/04 | Updated to include USB 2.0 support details |
Contents
- 1 About This Document
- 2 Introduction
- 3 Design Overview
- 4 Component Externals
- 4.1 APIs
- 4.2 Host Controller driver IDC calls
- 4.3 USBD driver IDC calls
- 4.3.1 Cancel I/O request(s)
- 4.3.2 Set device configuration request
- 4.3.3 Set interface request
- 4.3.4 Register HCD driver
- 4.3.5 Un-register HCD driver
- 4.3.6 Register Device Class driver
- 4.3.7 Process IRQ
- 4.3.8 Clear Stalled Endpoint request
- 4.3.9 Process I/O request
- 4.3.10 Initialize registered USB host controllers
- 4.3.11 Notify about power management state changes
- 4.3.12 Reset port
- 4.3.13 Initial enumeration complete
- 4.4 Class/client driver IDC calls
About This Document
Purpose
This document briefly describes OS/2 USB stack implementation and gives guidelines for host controller driver and class/client driver implementation together with stack driver communication API specification.
Intended Audience
This programmers reference document could be used by host controller and client/Class driver developer and contains design requirements used for OS/2 base USB stack implementation.
Introduction
OS/2 USB driver stack consists of 3 layers 1) host controller driver layer; 2) USBD root layer; 3) class/client layer. Driver stack internally uses communication interface based on Inter Driver Communication (IDC) calls. Interface between the system and class/client drivers depends on particular driver and its application area.USBD driver acts as a root of USB driver stack and both other layer drivers must register themselves within USBD. Root layer driver manages all USB device attach/detach processes and serves USB Hub devices internally. Host controller driver layer interacts with USB host hardware to execute requests received from USDB driver/layer and sends request complete messages (process IRQ requests) to USBD / Class/Client drivers.
Design Overview
- accepts registration/de-registration requests from all installed HCD layer drivers
- accepts registration requests from all installed device class/client drivers
- reset/initialize all host controllers via call to registered host controller drivers. This call starts enumeration process for particular host starting with device descriptor retrieval for controller root hub and then continuing root hub port processing as for regular hub device. Reset/Initialize call is executed as the latest at USBD driver INITIALIZATION COMPLETE strategy call or before if Complete Initialization IDC call is received from any class/client driver (see description below)
- calls all registered class/client drivers when new non-HUB device is attached or when detached
- passes I/O requests initiated by class/client drivers to appropriate HCD driver and processes request cancellation
- manages Hub control pipes to process device attachment/detachment (including I/O request canceling for detached devices)
- process set device configuration/set interface/clear stalled endpoint (reset endpoint) requests received from Class/Client drivers
- processes APM events - received from host controller drivers or APM.SYS driverprocess reset port request from Class/Client drivers (this request will initiate device enumeration process for selected device again)
- notify all registered Class/Client drivers about completed initial device enumeration.
Host Controller driver
Basic OS/2 USB Host Controller Driver processes only BASEDEVINIT (1Bh) and INITIALIZATION COMPLETE (1Fh) strategy calls. Processing of I/O requests and IRQ events (within USB stack requests completed by host/driver are called IRQ events) are handled by means of IDC calls to and from the USB Driver (or class client driver for IRQ processing calls). Host controller driver has to implement I/O request processing for all devices connected to corresponding host controller including root hub (in most cases implemented in host driver code).
BASEDEVINIT Strategy Command
- Processes CONFIG.SYS parameters. All stack drivers must process /V (verbose) parameter and display during initialization driver version/hardware information if initialization succeeds or error message(s) describing reason of failure. If /V parameter is not specified driver must initialize/fail to initialize quietly, without displaying any messages.
- Locates host controller device(s)
- Registers I/O resources within OS/2 Resource Manager
- Tries to register all host controllers within USBD driver: a) get USBD driver IDC address via DevHelp_AttachDD call with driver name "USBD$ "; b) issue registration call if possible.
INITIALIZATION COMPLETE Strategy Command
OS/2 USB host controller reissues registration call if registration failed because USBD driver was not yet loaded at initialization time.
Request complete (IRQ) notification
Host controller driver notifies I/O request originator by calling IDC routine, address of this routine is stored in request block. Threads that process request and call notification routine must be separated, this is valid also for requests that could be executed immediately - like retrieving port status from I/O space or memory mapped registers.
IDC Processing
- Accept an I/O request. HCD driver must implement software Root Hub support for host controller hardware
- Cancel I/O requests for specific USB device
- Reset Host controller
- process power management suspend call (optional)
- parameter checking
- bandwidth calculations
- request execution and error / success condition processing
- client notification about completed request.
- Process IRQ
- Register/Unregister HCD driver
- Notify USBD driver on wake-up events
Root hub implementation
- retrieving root hub device descriptor
- setting hub device address
- retrieving hub device configuration structures
- setting hub configuration
- retrieving hub descriptor
- retrieving hub/hub port status information
- clearing hub/hub port features
- setting hub/hub port features
- retrieving hub "status changed" pipe data.
Class/Client Driver
Class/client drivers serves specific USB device class or device giving access to hardware from client applications or operating system services (like file system, multimedia data streaming). Depending on device class, drivers are implemented as base device drivers or device driver and must process at least BASEDEVINIT (1Bh) or DEVINIT (00h) strategy calls. Support of INITIALIZATION COMPLETE (1Fh) strategy call is recommended to avoid problems with driver configuration string order in CONFIG.SYS file. OS/2 USB stack assumes that if a separate client driver(s) must be used for particular class driver then client driver never communicates directly with USBD driver and all requests must be passed to class driver that forwards requests to USBD driver. Class/Client driver must register within USBD driver. USBD calls class driver later to inform it about device/system status change. OS/2 USB stack use device configuration value to perform device reservation on the level of device. 0 configuration value means that device is not used / claimed for service. Class/Client driver must set configuration value to desired configuration (non-zero number) value to reserve device. Sharing of devices with the same configuration value between several drivers will work only in case if installed set of drivers are designed to work simultaneously or have special reservation mechanisms.
BASEDEVINIT/DEVINIT Strategy Command
- Processes CONFIG.SYS parameters. All stack drivers must process /V (verbose) parameter and display during initialization driver version/hardware information if initialization succeeds or error message(s) describing reason of failure. If /V parameter is not specified driver must initialize/fail to initialize quietly, without displaying any messages.
- Tries to register all host controllers within USBD driver: a) get USBD driver IDC address via DevHelp_AttachDD call with driver name "USBD$ "; b) issue registration call if possible (could not be done for BASE device drivers as registration call must be Ring0 call, but could be done later after initialization completes and driver starts normal request processing).
INITIALIZATION COMPLETE Strategy Command
OS/2 USB Class/Client driver reissues registration call if registration failed (or was not executed) at initialization time during initialization complete call.
IDC Processing
- Accept/reject device for service (during this call device configuration value must be set to non-zero value in corresponding DeviceInfo structure)
- Process detach device requests (this request must be passed to client driver if it works on the top of class driver)
- process power management suspend/resume notifications (optional)
- complete initialization call
- Process IRQ notification calls
- Process idle notification calls (to switch from BIOS support mode to native OS/2)
- class driver registration call
- I/O requests required for device initialization/functioning
- configuration/interface setting calls
- request cancel call
- clear stalled endpoint call
- complete initialization call (optional, may be response to adapter driver 'complete initialization' iorb request)
Filter drivers
Component Externals
Both the host controller driver (HCD) and USBD driver use IDC calls to perform I/O on the USB devices. These call descriptions can be used to develop new HCD layer drivers and new Device Class drivers.
APIs
Drivers in USB driver stack communicate with each other via IDC routine calls using common parameter format:
void IDCRoutine( RPH_GENIOCTL FAR *pRP_GENIOCTL );
where pRP_GENIOCTL is a pointer to a standard OS/2 IOCTL request packet. All structure field usage are as for standard IOCTL request packet. pRP_GENIOCTL->Cmd must be set to 10h (generic IOCtl call). The USBUHCD and USBD drivers ignore the pRP_GENIOCTL->sfn field value. The pRP_GENIOCTL->Category field is used to indicate which USB device driver is to process the request. Valid values include:
Definition | Value | Description |
---|---|---|
USB_IDC_CATEGORY_HOST | 0x90 | IDC to be processed by HCD driver |
USB_IDC_CATEGORY_USBD | 0x91 | IDC to be processed by USBD driver |
USB_IDC_CATEGORY_CLASS | 0x92 | IDC to be processed by Device Class driver |
USB_IDC_CATEGORY_CLIENT | 0x93 | IDC to be processed by Client driver |
The pRP_GENIOCTL->Function field is used to indicate what type of functionality is to be performed. Value values include:
Definition | Value | Description |
---|---|---|
USB_IDC_FUNCTION_ACCIO | 0x41 | Add I/O request to schedule |
USB_IDC_FUNCTION_CANCEL | 0x42 | Cancel I/O request for specified device |
USB_IDC_FUNCTION_REGISTER | 0x43 | Register driver with USBD |
USB_IDC_FUNCTION_PRCIRQ | 0x44 | Process IRQ request |
USB_IDC_FUNCTION_CHKSERV | 0x45 | Accept/reject device for service |
USB_IDC_FUNCTION_DETDEV | 0x46 | Detach device |
USB_IDC_FUNCTION_RSTHOST | 0x47 | Reset host controller |
USB_IDC_FUNCTION_SETCONF | 0x48 | Set device configuration |
USB_IDC_FUNCTION_SETINTF | 0x49 | Set device interface |
USB_IDC_FUNCTION_CLRSTALL | 0x4a | Clear stalled endpoint |
USB_IDC_FUNCTION_CMPL_INI | 0x4c | Initialize all registered USB host controller drivers |
USB_IDC_FUNCTION_APM | 0x4d | Power management state changes |
USB_IDC_FUNCTION_UNREGISTER | 0x4f | Un-register driver |
USB_IDC_FUNCTION_RESET_PORT | 0x51 | Initiate port reset for selected hub port |
USB_IDC_FUNCTION_IDLE | 0x52 | USBD driver has completed all hub configuration activities started at initialization time |
The following table show which device drivers can originate and which driver process specified IDC function types.
HCD Driver | USBD Driver | Device Class Driver | Client Driver | |
---|---|---|---|---|
I/O Request | Process | Originate/Process | Process/Originate | Originate/Process |
Cancel | Process | Originate/Process | Originate | n/a |
Register | Originate | Process | Originate/Process | Originate |
Process IRQ | Originate | Process | Process | Process |
Accept/Reject device | n/a | Originate | Process/Originate | Process |
Detach Device | n/a | Originate | Process/Originate | Process |
Reset Host Controller | Process | Originate | n/a | n/a |
Set Device Configuration | n/a | Process | Originate | n/a |
Set interface | n/a | Process | Originate | n/a |
Clear stalled | n/a | Process/Originate | Originate/Process | Originate |
Complete initialization | n/a | Process | Originate | n/a |
Power management | Originate/Process | Process/Originate | Process | n/a |
Un-register | Originate | Process | n/a | n/a |
Reset port | n/a | Process | Originate | n/a |
Idle | n/a | Originate | Process | n/a |
Upon successful completion, request packets in the USB driver stack set the STATUS_DONE bit as a return code in the pRP_GENIOCTL->Status field. On error conditions, the STATUS_DONE and STERR bits are set along with the appropriate error code value in the lower 7 bits in the pRP_GENIOCTL->Status field. Valid error status values in the USB stack include the following:
Definition | Value | Description |
---|---|---|
USB_IDC_WRONGCAT | 0x10 | wrong IDC call category |
USB_IDC_WRONGFUNC | 0x11 | wrong IDC call function |
USB_IDC_WFCATCOMB | 0x12 | wrong IDC call category/function combination |
USB_IDC_PARMERR | 0x13 | parameter error |
USB_IDC_ALLOCERR | 0x14 | failed to allocate internal data structures |
USB_IDC_NOBANDWIDTH | 0x15 | not enough bandwidth to execute request |
USB_IDC_EXCEEDSMAX | 0x16 | number of registered drivers exceeds maximum allowed |
USB_IDC_CANCELED | 0x17 | I/O request canceled |
USB_IDC_ADDRINV | 0x18 | device or endpoint not exists |
USB_IDC_SERVREJCTD | 0x19 | device can't be served by driver |
USB_IDC_IOFAILED | 0x20 | I/O request failed |
The individual IDC routines set specific return codes describing the failed action (see below).
Host Controller driver IDC calls
The following calls must be processed by the Host Controller Driver (calls are issued by USBD driver).
Accept I/O request
This call is used to place a I/O request in USB Host Controller Schedule. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x90 // Processed by HCD pRP_GENIOCTL->Function = 0x41 // IO Request pRP_GENIOCTL->ParmPacket = &USBRb
The USBRb data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID (assigned by USBD driver during registration) |
UCHAR | deviceAddress | USB device address. Valid range - [1,127], 0 are used for not configured devices. In most cases address 1 is used for root hub. |
UCHAR | endPointId | device endpoint ID, valid range - [0,15] |
UCHAR | status | device status on request complete (during IRQ processing)
|
WORD | flags | Low order byte sets transfer type and several flags:
High order byte gives packet/queuing/request completion details:
|
PUCHAR | buffer1 | Virtual address of data buffer. Address is converted to physical address by HCD. |
USHORT | buffer1Length | Buffer length in bytes. Value 0x7ff means zero length packet. |
PUCHAR | buffer2 | Virtual address of second data buffer. Address is converted to physical address by HCD. This buffer is used only for SETUP requests to receive optional setup data and isochronous transfers with individual frame lengths. |
USHORT | buffer2Length | Buffer length in bytes. Value 0x7ff means zero length packet. |
USHORT | serviceTime | Required service frequency in ms for nonisochronous requests. Valid range - [0,255]. For isochronous request contains frame index request add to. Frame index can be relative or absolute (if "absolute frame index" flag is on flags field). This field is set to absolute index value when request is accepted or IRQ processed. |
USHORT | maxPacketSize | maximum packet size to be used for specified endpoint, set to 0 to use maximum allowed for this device endpoint |
PUSBIDC | usbIDC | Address of IRQ processing routine to be called for this request |
USHORT | usbDS | data segment value for IRQ processing routine |
UCHAR | category | category value used in IRQ call |
ULONG | requestData1 | data to be stored within request |
ULONG | requestData2 | data to be stored within request |
ULONG | requestData3 | data to be stored within request |
UCHAR | maxErrorCount | maximum retry count, valid range - [0,3]; 0 means no retry limit |
_USBRb FAR * | nextRb | pointer to next request block, not used, must be set to NULL |
UCHAR | altInterface | alternate interface index. The value of this field is used by USBD to locate endpoint descriptor if "alternate interface specified" flags is on in flags field. Otherwise 0 interface index value is used. |
UCHAR | isoFlags | Field is used only for isochronous requests (when isochronous request flag is on in "flags" field) to specify requested service:
|
USHORT | isoFrameLength | Field is used only for isochronous 'open' requests and specifies number of data bytes to be transferred during single host frame |
USHORT | isoBuffers | Field is used only for isochronous 'open' requests and specifies number of buffers used for data transfer |
UCHAR | Mult | Number of transactions per micro frame (USB 2.0) |
UCHAR | HubAddr | Hub address for current device (USB 2.0) |
UCHAR | PortNumb | Hub port number for current device (USB 2.0) |
- If this flag is set, then request block contain Mult, HubAddr, PortNumb fields with valid values set and also isochronous request extension fields (values from these fields are used only if proper flag is set). USB2.0 flag is always on for host / USBD communication and extended request structure is used. Class/client drivers can issue requests using short structure form.
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request accepted |
0x8113 | request parameter error |
0x8114 | failed to allocate internal data structures |
0x8115 | not enough bandwidth to execute request |
0x8118 | device or endpoint not exists |
Isochronous requests are processed in different manner than all other requests - isochronous requests require special initialization/de initialization actions before data transfer starts and after transfer is finished. HCD layer driver calls IRQ routine only once per buffer even if data are split between several frames. Isochronous request details are specified in 'isoFlags' field. Typical calling sequence is the following:
1) isochronous open request (isoFlags=00000001b) allocates data structures to serve request. HCD driver saves isoBuffers and isoFrameLength in these structures. Data block is identified by device address, target endpoint address and transfer direction. Open request will fail if: there are already opened isochronous request for the same device, endpoint addresses and transfer direction (return code 0x8118); not enough memory to allocate request data block (return code 0x8114); not enough USB bandwidth to complete request (return code 0x8115); requested frame size (number of bytes to be transferred during single host frame) exceeds maximal packet size for target endpoint (return code 0x8113). Open call also saves caller identification data (IDC routine address, DS value, caller's category) and requestData1, requestData2, requestData3. Identification data is used in all IRQ calls, but requestData only for canceled request notification.
2) accept isochronous data buffer (isoFlags=00000000b) accepts buffer address and length from buffer1, buffer1Length fields and starts data transfer. In case if individual frame lengths are used then buffer2 and buffer2Length fields are used to pass this information. If constant frame length is used then both these fields must be set to 0. For detailed description of fixed/individual frame size transfers see note below. Buffer will be refused if: no isochronous request is opened for specified device,endpoint and transfer direction (no previous open call) (return code 0x8118); number of buffers exceeds number specified at open time (return code 0x8113). Values specified in requestData1, requestData2, requestData3 fields are used in 'buffer processed' notification call.
3) isochronous close request (isoFlags=00000010b) releases data structures allocated for request. This request must be the last call in isochronous data transfer for specified device, endpoint and transfer direction. This request fails if there were no open call for the same target. Cancel isochronous buffer processing call (isoFlags=00000100b) stops isochronous data processing, clears all the buffer information and returns in buffer1, buffer1Length fields last processed data buffer address and processed data length. Cancel request fails with return code 0x8118 if no isochronous request is opened for specified device,endpoint and transfer direction. Retrieve request status information call (isoFlags=00000100b) returns in buffer1, buffer1Length fields last processed data buffer address and processed data length. Request fails with return code 0x8118 if no isochronous request is opened for specified device,endpoint and transfer direction. The initial implementation supported only fixed frame size isochronous transfers. But it proved that for some clients (like USBAudio) this approach is not flexible enough and causes dropped samples due to fact that internal sampling frequency of device is not the exact multiple of USB internal 1000 Hz frame clock frequency. To allow clients to use explicit synchronization the API was extended to be able to specify the length of every frame individually. This information is passed in previously unused Buffer2 and Buffer2Length fields.
Variable | Fixed frame size | Individual frame size |
---|---|---|
Buffer1 | pointer to data | pointer to data |
Buffer1Length | number of bytes in data buffer | number of bytes in data buffer |
Buffer2 | NULL | pointer to ISO_FRAME_INFO array |
Buffer2Length | 0 | number of bytes in ISO_FRAME_INFO array |
isoFrameLength | fixed frame size | not used |
There is possibility that device will not be able to send/receive as much information as caller requested. To allow host controller to report back the number of actually transferred bytes the Buffer2 and Buffer2Length fields are used in notification messages.
Variable | Fixed frame size | Individual frame size |
---|---|---|
Buffer1 | pointer to data | pointer to data |
Buffer1Length | number of bytes in data buffer | number of bytes in data buffer |
Buffer2 | NULL | pointer to updated ISO_FRAME_INFO array |
Buffer2Length | Number of actually transferred bytes | number of bytes in ISO_FRAME_INFO array |
If number of actually received (only for READ) bytes is less than asked for then buffer is compacted to avoid gaps. The missing bytes at the tail of buffer are set to 0. | If number of actually received (only for READ) bytes is less than asked for then buffer is left in scattered state. Each ISO_FRAME_INFO entry specifies how many bytes in tail of frame are not received and thus have unknown values. |
To pass information about individual frame lengths the array of ISO_FRAME_INFO structures is used. There must be as many structures as number of frames to transfer. Structure contains only one member Length which specifies the number of bytes to transfer between host and device. In notification message the original values are replaced with number of actually transferred bytes.
Cancel I/O request(s)
This call is used to cancel all queued I/O requests for the specified USB device and endpoint. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x90 // Processed by HCD pRP_GENIOCTL->Function = 0x42 // Cancel request pRP_GENIOCTL->ParmPacket = &USBCancel
The USBCancel data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Function | |
UCHAR | controllerId | controller ID |
UCHAR | deviceAddress | USB device address. Valid range - [1,127], 0 are used for not configured devices |
UCHAR | endPointId | endpoint ID. Valid range - [0,15], 0xff cancels requests for all the device endpoints |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request(s) canceled |
Reset host controller
This call is used to reset host controller and move it into 'running' state:
pRP_GENIOCTL->Category = 0x90 // Processed by HCD pRP_GENIOCTL->Function = 0x42 // Cancel request pRP_GENIOCTL->ParmPacket = &USBDetach
The USBDetach data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID to be reset |
UCHAR | deviceAddress | Not used |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, host reset |
0x8118 | device or endpoint not exists |
Notify about power management state changes
This call is used to notify host controller drivers about changes in APM power states. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x90 // Processed by HOST pRP_GENIOCTL->Function = 0x4d // Power management notification pRP_GENIOCTL->ParmPacket = &ulAPMState // Power state
ulAPMState is DWORD value which can contain these values:
Code value | Description |
---|---|
USB_APM_SUSPEND (1L) | Host will go to suspended state |
USB_APM_RESUME (2L) | Host will resume from suspended state |
Return code is not analyzed by originator driver (USBD driver), host driver that processes this request can set it to any proper value.
USBD driver IDC calls
The following calls are processed by the USBD driver (calls may be issued by HCD and/or class driver depending on call type).
Cancel I/O request(s)
This call is used to cancel all queued I/O requests for the specified USB device and endpoint. USBD driver verifies host/device/endpoint and sends request to proper host controller driver. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x42 // Cancel request pRP_GENIOCTL->ParmPacket = &USBCancel
The USBCancel data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID |
UCHAR | deviceAddress | USB device address. Valid range - [1,127], 0 are used for not configured devices |
UCHAR | endPointId | endpoint ID. Valid range - [0,15], 0xff cancels requests for all the device endpoints |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request(s) canceled |
0x8118 | device or endpoint not exists |
Set device configuration request
This call is used by class/client drivers to set device configuration. USBD driver stores configuration value in device data structures that are passed to class/client drivers during attach request processing, configuration value could be used as flag to show that device will be used by class/client driver. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x48 // Set configuration pRP_GENIOCTL->ParmPacket = &USBSetConf
The USBSetConf data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID |
UCHAR | deviceAddress | USB device address. Valid range - [1,127] |
USHORT | classDriverDS | data segment value for IRQ processing routine |
UCHAR | configurationValue | desired configuration value |
ULONG | irqSwitchValue | value used in class driver IRQ processor worker switch |
UCHAR | category | category value used in IRQ call |
SetupPacket FAR * | setConfiguration | far pointer to setup packet buffer used in clearing operation |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request(s) canceled |
0x8118 | device or endpoint not exists |
Set interface request
This call is used by class/client drivers to select device Interface. USBD driver stores configuration value in device data structures that are passed to class/client drivers during attach request processing. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x49 // Set configuration pRP_GENIOCTL->ParmPacket = &USBSetConf
The USBSetConf data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID |
UCHAR | deviceAddress | USB device address. Valid range - [1,127] |
USHORT | classDriverDS | data segment value for IRQ processing routine |
UCHAR | configurationValue | desired configuration value |
ULONG | irqSwitchValue | value used in class driver IRQ processor worker switch |
UCHAR | category | category value used in IRQ call |
SetupPacket FAR* | setConfiguration | far pointer to setup packet buffer used in clearing operation |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request(s) canceled |
0x8118 | device or endpoint not exists |
Register HCD driver
This call is used to register a Host Controller Driver with the USBD driver. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x90 // Processed by USBD (!) pRP_GENIOCTL->Function = 0x43 // Register HCD driver pRP_GENIOCTL->ParmPacket = &USBHCD
The USBHCD data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
PUSBIDC | usbIDC | Address of HDC IDC routine |
PUCHAR | hcdID | Pointer to store assigned by USBD controller Ids, hcdID points to area to store all hcdCount IDs |
UCHAR | hcdCount | Number of served Host Controllers |
HDRIVER | hDriver | RM driver handle |
HADAPTER | hAdapter | RM adapter handle |
Last 2 items (hDriver and hAdapter) are repeated hcdCount times. Registration call is processed by USBD even if request category is set to host controller driver to distinguish between host and Client/Class registration requests. This is the only exception in request category processing.
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return, HCD registered |
0x8116 | number of registered drivers exceeds maximum allowed |
Un-register HCD driver
This call is used to un-register a HCD from the USBD driver. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // USBD pRP_GENIOCTL->Function = 0x4f // Register Device Class pRP_GENIOCTL->ParmPacket = &USBHCD
The USBHCD data structure is defined in src\dev\usb\include\usbidc.h , see details in 'Register HCD Driver' request description.
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return, Device Class Driver registered |
0x8118 | Host driver not found |
Register Device Class driver
This call is used to register a Device Class Driver with the USBD driver. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // USBD pRP_GENIOCTL->Function = 0x43 // Register Device Class pRP_GENIOCTL->ParmPacket = &USBDClass
The USBDClass data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
PUSBIDC | usbIDC | Address of Device Class driver IDC routine |
USHORT | usbDS | Class driver data segment value |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return, Device Class Driver registered |
0x8116 | number of registered drivers exceeds maximum allowed |
Process IRQ
Request type | Not restored fields | Updated fields |
---|---|---|
non-isochronous |
|
|
isochronous |
|
|
Status flags | Description |
---|---|
0x40 | STALLED |
0x20 | BUFFERR |
0x10 | BABBLE |
0x08 | NAK |
0x04 | CRC |
0x02 | BITSTUFF |
Code value | Description |
---|---|
0x0100 | normal return code, I/O request completed successfully |
0x8017 | Request has been canceled |
0x8020 | I/O request failed, see details in status field |
Clear Stalled Endpoint request
This call is used to pass a I/O request to the HCD driver. All the device class drivers call the USBD driver to add their requests to appropriate HCD schedule. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x4a // Clear Stalled Request pRP_GENIOCTL->ParmPacket = &USBClearStalled
The USBClearStalled data structure is defined in src\dev\usb\include\usbidc.h as:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID |
UCHAR | deviceAddress | USB device address. Valid range - [1,127] |
UCHAR | endPointId | device endpoint ID, valid range - [0,15] |
PUSBIDCEntry | clientIDCAddr | Address of IRQ processing routine to be called for this request |
USHORT | clientDS | data segment value for IRQ processing routine |
ULONG | irqSwitchValue | switch used by IRQ processing routine |
UCHAR | category | category value used in IRQ call |
SetupPacket FAR * | clearStalled | far pointer to setup packet buffer used in clearing operation |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request passed to accepted |
0x8115 | not enough bandwidth to execute request |
0x8118 | device or endpoint not exists |
Process I/O request
USBD driver accepts i/o requests in the same way as host drivers:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x41 // accept i/o Request pRP_GENIOCTL->ParmPacket = &USBRb
The USBRb data structure is defined in src\dev\usb\include\usbidc.h , see details in host controller decryption section. USBD checks for controller/device/endpoint presence and set device dependent flags in request block: 1) device speed flags (low/high speed device); 2) 0 default service time is replaced with actual value from device descriptor; 3) 0 maxPacket size is replaced with actual value .
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request accepted |
0x8113 | request parameter error |
0x8114 | failed to allocate internal data structures |
0x8115 | not enough bandwidth to execute request |
0x8118 | device or endpoint not exists |
Initialize registered USB host controllers
This call is used to start (move to running state) all registered USB host controller(s). This call could be used to start hosts earlier than all driver chain passes initialization complete phase, like during system boot when it is time to switch from BIOS support to native OS/2 driver support. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x4c // Complete initialization Request pRP_GENIOCTL->ParmPacket = &pRP_GENIOCTL // not used, must be non-NULL
// address to pass parameter check
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, host initialization process started |
Notify about power management state changes
This call is used to notify USBD about changes in APM power states - host wake up. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x4d // Power management notification pRP_GENIOCTL->ParmPacket = &ulAPMState // Power state
ulAPMState is DWORD value which can contain these values:
Code value | Description |
---|---|
USB_APM_RESUME (2L) | Host will resume from suspended state |
Return code is not analyzed by host controller driver, USBD can set it to any proper value.
Reset port
This call is used to request USBD driver to reset hub port for specified device, port reset will initiate device re-enumeration. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x91 // Processed by USBD pRP_GENIOCTL->Function = 0x51 // reset port pRP_GENIOCTL->ParmPacket = &USBRb // controller/device IDs
The USBRb data structure is defined in src\dev\usb\include\usbidc.h., USBD driver uses controllerId and deviceAddress fields to locate corresponding hub ID and port number to be reset.
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, port reset issued |
0x8118 | device or endpoint not exists (?) |
Initial enumeration complete
Class/client driver IDC calls
The following calls are processed by USB Class/Client drivers (calls may be issued by USBD or by HCD drivers depending on call type).
Initial enumeration complete
USBD driver processes all hub devices/attached devices during initial device enumeration. Class/Client drivers are notified by sending IDLE message sent out by USBD when initial enumeration completes. This notification could be used to switch from system boot time environment to normal processing environment and is sent out only once during boot/operation session. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x92 // Processed by CLASS/Client pRP_GENIOCTL->Function = 0x52 // idle pRP_GENIOCTL->ParmPacket = (PVOID)1 // not used
Return code is not analyzed by USBD driver, Class/Client driver can set it to any proper value.
Process IRQ
This call is used to process an IRQ (request complete processing) at the Class/Client level. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x92 // Processed by Class/Client pRP_GENIOCTL->Function = 0x44 // Process IRQ pRP_GENIOCTL->ParmPacket = &USBRb
The USBRb data structure is defined in src\dev\usb\include\usbidc.h., see details in USBD Process IRQ description.
Accept/reject device
This call is used to inform Class/Client drivers about new device that has completed enumeration process. Client/Class driver must analyze device description information and accept device for service or refuse service. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x92 // Processed by Class/Client pRP_GENIOCTL->Function = 0x45 // Process IRQ pRP_GENIOCTL->ParmPacket = &USBCDServe
The USBCDServe data structure is defined in src\dev\usb\include\usbidc.h. And contains the following fields:
Data Type | Variable | Function |
---|---|---|
DeviceInfo FAR * | pDeviceInfo | Far pointer to device information structure |
USBDClass FAR * | pFilter | Set on exit to Far pointer to filter driver IDC routine if current class/client driver is filter driver |
The DeviceInfo data structure is defined in src\dev\usb\include\usbidc.h. and contains the following fields:
Data Type | Variable | Function |
---|---|---|
UCHAR | ctrlID | controller ID |
UCHAR | deviceAddress | USB device address |
UCHAR | bConfigurationValue | USB device configuration value |
UCHAR | bInterfaceNumber | 0 based index in interface array for this item |
UCHAR | lowSpeedDevice | 0 for full speed device, non zero - low speed device |
UCHAR | portNum | port number to which device is attached |
USHORT | parentHubIndex | index in hub table to parent hub, -1 for root hub device |
HDEVICE | rmDevHandle | Resource Manager device handle |
SetupPacket | clearStalled | setup packet for USBD internal use |
DeviceDescriptor | descriptor | device descriptor |
UCHAR | configurationData[] | device configuration data |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, device accepted for service |
0x8019 | Rejected - driver will not serve current device |
Detach device
This call is used to process an IRQ (request complete processing) at the Class/Client level. Parameters for this request are defined as:
pRP_GENIOCTL->Category = 0x92 // Processed by Class/Client pRP_GENIOCTL->Function = 0x46 // Process IRQ pRP_GENIOCTL->ParmPacket = &USBDetach
The USBDetach data structure is defined in src\dev\usb\include\usbidc.h. and contains following fields:
Data Type | Variable | Function |
---|---|---|
UCHAR | controllerId | controller ID |
UCHAR | deviceAddress | USB device address. Valid range - [1,127] |
Upon completion one of the following return codes is set in the pRP_GENIOCTL->Status field:
Code value | Description |
---|---|
0x0100 | normal return code, I/O request completed successfully |
Notify about power management state changes
Code value | Description |
---|---|
USB_APM_SUSPEND (1L) | Host will go to suspended state |
USB_APM_RESUME (2L) | Host will resume from suspended state |