USB 2.0 Extended Control Driver for OS/2 (ArcaOS, eComStation)

This product is available free of charge and may be used at your own risk. Have fun. Click here for the ISC license.

Description - This classless device driver enables you to directly control usb devices. It provides an application program interface that conforms to the standard DosRead and DosWrite functions and as such may be easily used from rexx procedures using the charin and charout functions. It has been designed to ease the development and test of simple usb devices that do not belong to any usb device class and which exercise standard/vendor control transfers and data (bulk/interrupt) transfers. There is a 1 to 1 relationship between an instance of this device driver and a particular usb device. Moreover the additional hybrid control interface supports isochronous transfers with 1 specific endpoint through DosDevIOCtl functions that are however not available to rexx procedures.

Installation - Move the USBECD23.ZIP file into a directory of your choice and unzip it. Copy the USBECD.SYS file to your C:\OS2\BOOT directory. Add the device driver to the CONFIG.SYS file with the DEVICE=C:\OS2\BOOT\USBECD.SYS statement and restart your system. Attach the usb device that you want to control and it will be accepted by the device driver for inquiry via the DosRead function. Run the USBREAD.CMD file and it will obtain and display the device descriptor of the attached usb device and the device driver parameters required to control it with the DosWrite function. Update the device driver statement in the CONFIG.SYS accordingly and restart your system. Run the USBWRITE.CMD file and here is where the fun starts.

Obtain this product here free of charge. Click here for source/samples. Click here for my home page.

Device Driver Parameters

DEVICE=USBECD.SYS /D:0000:0000:0000 /N:$$$$$$$$ /S /V

You may use several instances of this device driver for various usb devices. All instances need to have a unique device driver name specified. CAUTION: Make sure that the device driver name is unique. It must be different to all other file, directory and driver names throughout your system. The default device driver name becomes $ when no name has been specified and this may only be used for the last of these instances. All parameters need to be in upper case.

/D:0000:0000:0000 - Device, specifies the usb device. The 1st part is idVendor, the Vendor Identification. The 2nd part is idProduct, the Product Identification. The 3rd part is bcdDevice, the Device Release Number. Must be specified with valid hexadecimal numbers. The driver accepts the characters 0 thru 9 and A thru F. Moreover the wildcard character # may be used. An invalid character truncates the hexadecimal number. Leading zeroes may be omitted.

/N:$$$$$$$$ - Name, specifies the device driver name. Must be unique and valid. It must be different to all other file, directory and driver names throughout your system. The driver accepts the characters allowed by the HPFS file system for file and directory names but not the space and the dot. An invalid character truncates the device driver name.

/S - Silence Mode, switch audible signal off. The default is audible signal switched on which results into a sharp beep on attach/detach of the usb device.

/V - Verbose Mode, display information. Displays driver information during OS/2 initialization. The default is no driver information displayed.

USBREAD.CMD

usbread sName

Attach the usb device that you want to inspect and it will be accepted by all instances of the device driver for inquiry via the DosRead function. Run the usbread.cmd file to obtain the device descriptor of the last attached usb device and to display it together with the device driver parameters required to control that usb device with the DosWrite function.

sName - Name of the device driver to be used. This is an optional argument and the name will default to $ when no name has been specified.

USBWRITE.CMD

usbwrite sName

Attach the usb device that you want to control and it will be accepted by the associated device driver instance for control by the DosWrite function. You may associate a particular device driver instance to the usb device that you want to control by means of the proper device driver parameters. Run the usbwrite.cmd file to obtain and display the device descriptor, configuration descriptors and associated interface and endpoint descriptors.

sName - Name of the device driver to be used. This is an optional argument and the name will default to $ when no name has been specified.

Control/Data Transfers

Control/Data transfers are supported through the Direct Control Interface and the Application Program Interface.

Control Transfers are supported by all usb devices through the default control pipe (the one with endpoint address 0). Most usb devices have to be configured before their data transfer interfaces can be used. Be aware that the usbecd.sys device driver does not issue a SetConfiguration request during attach of the associated usb device. It is up to the application to do this. The contents of the bmRequestType field distinguishes the parameter packet used by the data (bulk/interrupt) transfers from the setup packet used by the control transfers. The reserved value of 0xEC specifies that the packet is a parameter packet. Otherwise it is a setup packet.

Parameter Packet
fielddescription
bmRequestType0xEC - parameter
bmToggle0/8 - data toggle
wTimeOut[0]timeout interval
wTimeOut[1]timeout interval
bEndpointAddressendpoint address
bmAttributestransfer type
wLength[0]data length
wLength[1]data length
Setup Packet
fielddescription
bmRequestTypecharacteristics
bRequestspecific request
wValue[0]request dependent
wValue[1]request dependent
wIndex[0]request dependent
wIndex[1]request dependent
wLength[0]data length
wLength[1]data length

The bEndpointAddress field and the bmAttributes field of the parameter packet must be filled from the same fields of the corresponding endpoint descriptor. The bmToggle field supplies the initial data toggle to the device driver and receives the updated data toggle from the device driver. Since the usbecd.sys device driver does not keep track of the data toggle state between successive DosWrite requests to a particular endpoint, that data toggle must be carried forward by the application from the last DosWrite into the next DosWrite destined to that very same endpoint. The wTimeOut field defines the maximum wait time in milliseconds for the data transfer to complete. The special value 0xFFFF waits forever. The default timeout interval is 4096 milliseconds.

Direct Control Interface

The direct control interface uses OS/2 Procedures language 2/REXX functions. To control the usb device the following functions are described:

Acquire Driver

rc=stream(sName,'command','open');

Opens the device driver with read/write access for this process and denies read/write access to all other processes as required by the device driver. The device driver relies on standard file system access and sharing rules for contention control and does not use the notification of the open.

sName - Name of the usb device driver to be opened.

rc - Return Code. See the OS/2 Procedures Language 2/REXX Reference for the standard strings returned.

Obtain Device Descriptor

sBuffer=charin(sName,,26);

Builds the setup packet to obtain the device descriptor. Transmits the setup packet to the usb device. Receives the device descriptor from the usb device. The last attached usb device will be used rather than the associated usb device.

sName - Name of the usb device driver to be used.

sBuffer - Name of the buffer to receive the setup packet and the device descriptor.

Execute Control Transfer

rc=charout(sName,sBuffer);

Transmits the setup packet to the associated usb device. Transmits the number of data bytes specified in the wLength field of the setup packet to that usb device when the data transfer direction specified in the bmRequestType field of the setup packet is host-to-device. Receives the number of data bytes specified in the wLength field of the setup packet from that usb device when the data transfer direction specified in the bmRequestType field of the setup packet is device-to-host.

sName - Name of the usb device driver to be used.

sBuffer - Name of the buffer that contains the setup packet in its first 8 bytes. For host-to-device transfers the data bytes to be transmitted will be taken from the remainder of this buffer. For device-to-host transfers the data bytes to be received will be put into the remainder of this buffer.

rc - Return Code. See the OS/2 Procedures Language 2/REXX Reference for the standard strings returned.

Execute Data Transfer

rc=charout(sName,sBuffer);

Transmits the number of data bytes specified in the wLength field of the parameter packet to the associated usb device when the data transfer direction specified in the bEndpointAddress field of the parameter packet is host-to-device. Receives the number of data bytes specified in the wLength field of the parameter packet from that usb device when the data transfer direction specified in the bmEndpointAddress field of the parameter packet is device-to-host.

sName - Name of the usb device driver to be used.

sBuffer - Name of the buffer that contains the parameter packet in its first 8 bytes. For host-to-device transfers the data bytes to be transmitted will be taken from the remainder of this buffer. For device-to-host transfers the data bytes to be received will be put into the remainder of this buffer.

rc - Return Code. See the OS/2 Procedures Language 2/REXX Reference for the standard strings returned.

Release Driver

rc=stream(sName,'command','close');

Closes the device driver and allows read/write access to other processes. The device driver relies on standard file system access and sharing rules for contention control and does not use the notification of the close.

sName - Name of the usb device driver to be closed.

rc - Return Code. See the OS/2 Procedures Language 2/REXX Reference for the standard strings returned.

Isochronous Transfers

Isochronous transfers are supported through the Hybrid Control Interface which uses DosDevIOCtl functions.

Parameter Buffer
fielddescription
hEventSemevent semaphore handle
bEndpointAddressendpoint address
bAlternateSettingalternative setting
wMaxPacketSizemaximum payload size
wIsoBufferLengthsize of one iso buffer
wIsoBufferCountnumber of iso buffers
wIsoFrameCountnumber of iso frames

The hEventSem field of the parameter buffer must be filled with the handle of an unnamed shared event semaphore obtained from a previous call to DosCreateEventSem. When an Isochronous Queue Request completes, this semaphore will be posted. The bEndpointAddress field of the parameter buffer must be filled from the same field of the corresponding endpoint descriptor. The bAlternateSetting field of the parameter buffer must be filled from the same field of the corresponding interface descriptor. The wMaxPacketSize field of the parameter buffer must be filled from the same field of the corresponding endpoint descriptor. The wIsoBufferLength and wIsoBufferCount fields of the parameter buffer must be set such that wIsoBufferLength*wIsoBufferCount bytes fit within the data buffer.

Set wIsoFrameLength to (wMaxPacketSize&2047)*(((wMaxPacketSize&6144)>>11)+1). Set wIsoFrameCount to (wIsoBufferLength-4)/(wIsoFrameLength+2) to transfer individual frames. The data area in each iso buffer starts with a frame data array and ends with a frame size array. Each array has wIsoFrameCount elements. Otherwise the data area in each iso buffer contains concatenated payload(s).

Data Buffer (frames)
data areacompletion result fields
data[],size[]buffer1length,buffer2Length
..
data[],size[]buffer1length,buffer2Length
Data Buffer (stream)
data areacompletion result fields
payload(s)buffer1length,buffer2Length
..
payload(s)buffer1length,buffer2Length

The data buffer must be aligned at a 65536 byte boundary. The number of contiguous iso buffers in this data buffer is wIsoBufferCount.

When an Isochronous Queue Request is issued and frames are being used then the frame size array in the iso buffer must always have been prepared by resetting each element to wIsoFrameLength.

When an Isochronous Queue Request completes and frames are being used then buffer1Length contains the offset to the frame size array and buffer2Length contains the size of the frame size array (wIsoFrameCount*2). The frame data array contains the individual frames and the frame size array contains the corresponding lengths.

When an Isochronous Queue Request completes and frames are not used, then buffer1Length contains the size of the data area (wIsoBufferLength-4) and buffer2Length contains the number of bytes transferred.

Hybrid Control Interface

The hybrid control interface uses DosDevIOCtl functions. To control the usb device the following functions are described:

Isochronous Open Request

ulrc=DosDevIOCtl(hDevice,0xEC,0x40,pParm,cbParm,pcbParm,pData,cbData,pcbData);

Locks the data buffer in memory. Allocates resources for isochronous transfer.

hDevice - The device handle obtained from a previous call to DosOpen.

pParm - Parameter Buffer Address. The parameter buffer contains the appropriate parameters to enable isochronous transfers.

cbParm - Parameter Buffer Length. Must be 14 when the optional field wIsoFrameCount in the Parameter Buffer has been specified. Otherwise it must be 12.

pcbParm - Address of the variable to receive the Parameter Buffer Length.

pData - Data Buffer Address. The data buffer contains the contiguous iso buffers. It must be aligned at a 65536 bytes boundary.

cbData - Data Buffer Length. Must be at least wIsoBufferLength*wIsoBufferCount.

pcbData - Address of the variable to receive the Data Buffer Length.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

Isochronous Queue Request

ulrc=DosDevIOCtl(hDevice,0xEC,0x42,0,0,0,0,0,0);

Schedules one iso buffer for transfer. Prepares for next transfer. Upon isochronous transfer complete, the EventSem will be posted.

When frames are being used then the frame size array in the iso buffer must always be prepared by resetting each element to wIsoFrameLength.

hDevice - The device handle obtained from a previous call to DosOpen.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

Isochronous Close Request

ulrc=DosDevIOCtl(hDevice,0xEC,0x41,0,0,0,0,0,0);

Releases resources for isochronous transfer. Unlocks the data buffer in memory.

hDevice - The device handle obtained from a previous call to DosOpen.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

Application Program Interface

The application program interface uses OS/2 Control Program functions. To control the usb device the following functions are described:

DosOpen

ulrc=DosOpen(pszName,phDevice,pulAction,0,0,1,18,0);

Opens the device driver with read/write access for this process and denies read/write access to all other processes as required by the device driver. The device driver relies on standard file system access and sharing rules for contention control and does not use the notification of the open.

pszName - Address of the asciiz name of the usb device driver to be opened.

phDevice - Address of the variable to receive the device handle.

pulAction - Address of the variable to receive the action taken.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

DosRead

ulrc=DosRead(hDevice,pBuffer,cbTransfer,pcbTransfer);

Builds the setup packet to obtain the device descriptor. Transmits the setup packet to the usb device. Receives the device descriptor from the usb device. The last attached usb device will be used rather than the associated device.

hDevice - The device handle obtained from a previous call to DosOpen.

pBuffer - Address of the buffer to receive the setup packet and the device descriptor.

cbTransfer - Number of bytes to transfer. The size of the setup packet is 8. The size of the device descriptor is 18. Thus the cbTransfer field must be at least 26.

pcbTransfer - Address of the variable to receive the number of bytes transferred. Beware of the fact that this becomes just a copy of the cbTransfer field. The number of data bytes actually received is put into the wLenght field of the setup packet rather than into this field.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

DosWrite

ulrc=DosWrite(hDevice,pBuffer,cbTransfer,pcbTransfer);

In case of control (standard/vendor) transfer: - Transmits the setup packet to the associated usb device. Transmits the number of data bytes specified in the wLength field of the setup packet to that usb device when the data transfer direction specified in the bmRequestType field of the setup packet is host-to-device. Receives the number of data bytes specified in the wLength field of the setup packet from that usb device when the data transfer direction specified in the bmRequestType field of the setup packet is device-to-host.

In case of data (bulk/interrupt) transfer: - Transmits the number of data bytes specified in the wLength field of the parameter packet to the associated usb device when the data transfer direction specified in the bEndpointAddress field of the parameter packet is host-to-device. Receives the number of data bytes specified in the wLength field of the parameter packet from that usb device when the data transfer direction specified in the bmEndpointAddress field of the parameter packet is device-to-host.

hDevice - The device handle obtained from a previous call to DosOpen.

pBuffer - Address of the buffer that contains the parameter/setup packet in its first 8 bytes. For host-to-device transfers the data bytes to be transmitted will be taken from the remainder of this buffer. For device-to-host transfers the data bytes to be received will be put into the remainder of this buffer.

cbTransfer - Number of bytes to transfer. The parameter/setup packet must always be present in the buffer, so the minimum number of bytes to transfer must be 8. For data transfer the actual number of bytes to be transferred is controlled by the wLength field of the parameter/setup packet. Thus the number of bytes to transfer must be at least 8 higher than the wLength field of the parameter/setup packet.

pcbTransfer - Address of the variable to receive the number of bytes transferred. Beware of the fact that this becomes just a copy of the cbTransfer field. The number of data bytes actually transferred is put into the wLenght field of the parameter/setup packet rather than into this field.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

DosClose

ulrc=DosClose(hDevice);

Closes the device driver and allows read/write access to other processes. The device driver relies on standard file system access and sharing rules for contention control and does not use the notification of the close.

hDevice - The device handle obtained from a previous call to DosOpen.

ulrc - Return Code. See the Control Program Guide and Reference for the standard values returned.

Conforms to XHTML 1.0 Conforms to CSS 2.1 © W.M.Brul 2004-2016, all rights reserved.