DosUSB driver documentation
DOS support for USB is currently very limited. There are
few drivers available, e.g. for mass storage devices.
DOS can work with a USB keyboard and a USB mouse only
if the BIOS
features legacy support by doing a 8042 controller emulation for
these devices. With legacy support enabled, the BIOS will then also
support to boot from and to access a USB floppy drive or hard disk.
For Linux there are UHCI, OHCI and EHCI drivers available
lot of device drivers which are based on these USB controller
drivers. Using DOSUSB.COM it is now possible for DOS application
programs to communicate with all sorts of USB devices and to implement
USB device drivers for DOS.
DOSUSB.COM is a USB host controller driver for DOS. It
is a TSR
program which implements a universal host controller driver (HCD) and a
universal serial bus driver (USBD). It can also be used with WIN 3.11.
DOSUSB.COM provides a software layer so application programs
USB device drivers can be written supporting specific USB devices.
It builds frame lists for the USB host controllers, sets
transfer descriptors and queue heads and schedules the transactions
requested by the USB device drivers.
Extract the zip file you have downloaded into a directory
hard disk e.g. c:\dosusb. This directory will then contain the
dosusb.htm This file, the documentation for DOSUSB.COM
licence.txt Licence information about DOSUSB.COM
usbview.exe Application which displays the descriptors of
mouse.exe USB mouse demo application
restart.exe Enumerates all devices connected
address.exe Displays all devices and their addresses
prnusb.sys Device driver for printers using DosUSB
lpt1usb.sys Device driver for printers replacing the LPT1: device
hplaser.exe Prints the file dosusb.txt on a HP laserprinter
usbdisk.sys Device driver for mass storage devices
The subdirectory SAMPLES will contain the source-code for the following samples:
code for usbview.exe in Powerbasic
mouse.bas Source code for mouse.exe in Powerbasic
keyboard.bas Source code for reading a USB keyboard in Powerbasic
hplaser.bas Source for an application to print the file dosusb.txt
to an HP Laserjet printer
lq590.bas Source for a sample to print to an Epson LQ-590 printer
setalt.bas Source code to set alternate interface for a device
enum.c Turbo C program to retrieve a device descriptor
enum.bas Powerbasic sample to retrieve a device descriptor
enum.asm Assembler sample to retrieve a device descriptor
address.bas Source code for address.exe in Powerbasic
hplaser.pas Pascal sample to print dosusb.txt to an HP Laserjet printer
hplaserv.bas VBDOS sample to print dosusb.txt to an HP Laserjet printer
hplaserv.mak VBDOS project file for hplaserv.bas
hplaserq.bas Quickbasic sample to print dosusb.txt to an HP Laserjet printer
reset.bas Powerbasic source for a reset command
reset.pas Pascal source for reset command
restart.bas Powerbasic source for restart.exe
restart.pas Pascal source for restart command
icheck.bas Powerbasic source for an installation check
cable.bas Sample to send data via a PC connect USB cable
reader.bas Sample to read sector zero of a memory card
stick.bas Sample to read sector zero of a USB flash drive.
stick.pas Sample in Pascal to read sector of a USB flash drive
floppy.bas Sample to read sector zero of a floppy drive
camera.bas Read isochronous traffic from a camera
scanner.bas Sample which reads the identity of an Epson 1670 scanner
serial.bas Sample terminal program using a USB/serial adapter
prnusb.asm Source code for the printer device driver
To start DosUSB enter DOSUSB.COM at the DOS prompt. DosUSB
will then enumerate all the connected devices and install itself
as a resident program.
On laptops, the number of ports per controller may exceed
the number of
USB sockets installed. DosUSB will then show more ports than can be used
DosUSB itself requires about 23k of computer memory. However,
also requests additional memory for each controller installed
in the computer.
DosUSB will work on a computer featuring UHCI or OHCI
It will try to determine whether OHCI or UHCI controllers are installed and
If the PC has an Intel or VIA mainboard it will have UHCI
These mainboards are used in most computers. If the PC has an EHCI controller
for USB 2.0, DosUSB will still be able to run, since the EHCI controller
works together with UHCI or OHCI controllers which DosUSB can use.
Since UHCI and OHCI just support up to 12Mbit/s, this
is the upper limit
for ports supported by DosUSB. However, a 2.0 port with 480Mbit/s should also
work at 12Mbit/s.
3. USB Request Block
To request the execution of a transaction the device driver
to use a USB Request Block (URB) of the following structure:
transaction_type byte ;control (2Dh), in (69h), out (E1h) as hex code
chain_end_flag byte ;reserved
error_code byte ;returned by dosuhci
status byte ;returned by dosuhci
transaction_flags word ;reserved
buffer_off word ;for in/out
buffer_seg word ;for in/out
buffer_length word ;for in/out
actual_length word ;for in/out, (maximum length / bytes returned)
setup_buffer_off word ;for control
setup_buffer_seg word ;for control
start_frame word ;reserved
nr_of_packets word ;isochronous if set to one
int_interval byte ;reserved
error_count byte ;number of retries
timeout word ;reserved
next_urb_off word ;reserved
next_urb_seg word ;reserved
urbstruc ends ;32 byte long
This URB structure is similar to the Linux URB.
Using this URB it is possible to schedule control, input
transactions. For control transactions, DosUSB can do the following
in and out transactions required to retrieve the requested data.
3.1 Elements of the URB structure
select the type of transaction scheduled, this can be
control, in or out transaction. For a control transaction enter
2D hex, for an in transaction enter 69 hex and for an out
transaction enter E1 hex.
You can also send commands to DosUHCI, if you enter FF
hex as the
transaction code. The commands available are explained below.
this element is currently not used
enter the USB device address here of the device the scheduled
transaction shall be send to.
The device driver can either request the device descriptor
all addresses from one to invalid to find the device in question.
Or you can use usbview to find the device manually.
each device has several endpoints. The device driver has
select the right endpoint address for the control, in and out
transactions. There are different endpoints for bulk, interrupt,
control or isochronous transactions.
in this element DosUSB will return an error code, if it
encounters a problem with the scheduled transaction. The
following codes are currently defined:
1 - invalid device address, 2 - internal error,
3 - invalid transaction_type, 4 - invalid buffer length
this is the status byte returned by the USB controller
executing the scheduled transaction. If a control transaction has
been scheduled, this element has the status byte of the last
transaction in the queue.
See details about this byte in the Intel UHCI design guide. In short:
Bit 0: Reserved, Bit 1: Bitstuff error, Bit 2: CRC/Timeout, Bit 3: NAK,
Bit 4: Babble detected, Bit 5: Data Buffer error, Bit 6: Stalled,
Bit 7: Active
So e.g. 88 hex means a NAK received, since the active bit is set the data
packet can be retried, 44 hex means a CRC/Timeout error which caused a stall.
The device may need a reset.
The OHCI controller returns different completion codes than the UHCI
controller. To simplify driver development, the DOSUSB driver translates the
OHCI completion codes to UHCI status codes. However, in the dosusb.log file
the OHCI codes are specified.
OHCI completion code 1 is translated to 44h, 2 to 42h, 3 to 44h, 4 to 40h,
5,6 and 7 to 44h, 8 to 50h, 9 to 00h, 12 to 20h, 13 to A0h and 14 to 88h.
this element is currently not used
buffer_off / buffer_seg
enter a pointer to a buffer here, where either the data
send by an out transaction or the data to be returned by an in or
control transaction shall be placed
specify either the length of the out buffer or the expected
length of the data to be returned by an in or control transaction
If you set buffer_length greater than actual_length
(maximum length) DosUSB will schedule the number of in
transactions required to retrieve the amount of data specified in
buffer_length. DosUSB accepts a buffer_length up to 1024 bytes.
In the current version I recommend to specify up to the actual_length.
to schedule a transaction, enter the maximum length supported
the addressed endpoint here. After the transaction is completed
this element will have the number of bytes returned.
This number is given as returned by the UHCI controller,
means zero bytes, 0 means one byte, 1 means two bytes and so on.
The maximum length, however, needs to be entered as 8 for 8
bytes, which will be returned as the number 7.
For an OHCI controller, the number is the real length in bytes.
setup_buffer_off / setup_buffer_seg
for control transactions, enter a pointer to the request
This can e.g. be a device descriptor request
if this element has a value greater zero, DosUSB will
transaction for isochronous traffic.
Isochronous support is not yet implemented for OHCI!
this instructs the UHCI controller to retry unsuccessful
Valid values are: 0 - default (3 retries), 1 - 1 retry, 2 - 2 retries,
3 - 3 retries. For OHCI this is set to three and cannot be modified.
DosUSB will not have the host controller retry if a NAK is received.
These transactions are terminated with 88h in the status element and have
to be retried by the application.
All other elements are currently unused. They are provided
device driver that is written for the current version of DosUSB
will run without changes with future versions too.
3.2. Scheduling control transactions
In the case of a control transaction DosUSB will return
input in the buffer pointed to buffer_seg and buffer_off, if buffer_seg
and buffer_off are not zero and buffer_length is greater than zero.
For a control transaction such as a device descriptor
DosUSB will return the device descriptor in buffer and
acknowledge the receipt to the device with a zero out
transaction. In this case the actual_length field has to be equal
to the maximum packet length and buffer_length has to specify the
requested length of the descriptor which shall be returned.
If buffer_length is set to zero, DosUSB will do an in
transaction but no out transaction. So for a set configuration
transaction you have to set buffer_length to zero since this
transaction does not return data from the device and therefore
requires no out transaction.
If you set buffer_seg and buffer_off to zero, DosUSB will
do an control transaction. The driver calling DosUSB can then
request the in and out transactions required following the control
3.3. Calling DosUSB to execute the URB
To have DosUSB execute the transaction defined by the
have to place a pointer to the URB in the DS:DX registers and
call interrupt 65h.
The DS register has to contain the segment part of the pointer
and the DX register the offset part of it.
With the /I commandline parameter you can specify a different
interrupt to be used by DosUSB. For example /I64 will ask
DosUSB to use interrupt 64h. Use the range 60h-67h.
Using the URB you can only schedule a transaction to a
device specified by the device address. So you can send and
receive data from a mass storage device or send data to a
printer. If you have a camera, which sends a constant stream of
data or a mouse, DosUSB will not be able to retrieve that data
while it is executing a transaction to e.g. a printer.
4. Commands to DosUSB
If you enter FFh as the transaction type, you can specify
ax register the following commands:
ax=1: If dev_add is zero, DosUSB will reset all devices
them again. It will not enumerate new devices and thus all devices
keep their address. If dev_add is greater than zero, DosUSB will
just reset and enumerate the device with that address. It will not
output anything to screen in that case. Instead, if the enumeration
was successful DosUSB will return a 0 or 30h, if it failed, it will
return a 1 or 31h in the transaction_type field of the urb.
ax=2: enables debug output
ax=3: disables debug output
ax=4: displays the URB received from a device driver. You also have to
specify a valid device address in the URB here.
ax=5: set data toggle to zero, e.g. after a clear_feature(endpoint_halt)
command. You also have to specify the device address and endpoint
in the URB here.
ax=6: allows to check if DosUSB is installed. Will return "G" or 47h in
the transaction type field of the URB. See the icheck.bas sample.
Check if the interrupt is initialized first before using this.
ax=7: allows to check whether a UHCI or OHCI controller is installed.
Will return in the transaction type field of the URB a "U" or 55h
if UHCI and an "O" or 4Fh if OHCI has been determined by DosUSB.
ax=8: DosUSB will check all ports for devices connected and reset and
enumerate all devices it finds. If there are any additional devices
or devices have been removed, all devices may receive a new address.
The device on port zero of the first controller will get address number
one and so forth. If this device has not changed, it will keep its
address. However, if there has been no device on that port before, all
devices will get a new address.
ax=9: allows to determine the type of USB controller installed. Will return
the PCI vendor ID in the field next_urb_off of the URB and the PCI
device ID in the field next_urb_seg.
5. Commandline options
DosUSB currently supports the following command line options:
/D write debug output to dosusb.log file
/I change interrupt to call DosUSB URB
/X exclude controller
The /X option allows to exclude a USB controller, which
will not be used by
DosUSB. E.g. /XEC00 will exclude the controller at I/O address EC00 hex.
If you want a USB mouse or keyboard to be controlled by the BIOS while using
DosUSB to communicate with another device at a different controller, you
can use this command to exclude the controller where the mouse and keyboard
6. Debug mode
DosUSB offers a trace of the transactions performed via
or OHCI interface. This allows to monitor whether the scheduled
transactions where successful.
If DosUSB is called with the /D command line, the debug
is written into the dosusb.log file while DosUSB is running.
Using the transaction descriptor FF hex and the command
can turn on the trace any time and using the command 03 you can
turn it off again. In this case, the debug output is written to
After each transaction the trace stops and asks for a keypress.
If you enter "c" here, the screen will be cleared.
For each UHCI transaction the trace contains the following lines:
a) the bytes which make up the transaction descriptor
as it is
returned by the UHCI interface. There are two differences of this
transaction descriptor to the one written to the UHCI interface:
the status byte has been updated by the controller and DosUHCI
puts the value 500h into the actual length field to check if it
has been updated by the controller. Following the transaction
descriptor the transaction type is given (IN, OUT or CTRL), the
bits set (LS=low speed, SPD=short packet detect, IOS=isochronous
traffic , IOC=interupt on complete) and the error limit
specified, usually three errors.
Above the transaction descriptor there are numbers which
allow to locate the bytes in the descriptor or AL for actual
length, ST for status, PI for PID and AD for device address.
b) Then the result of the transaction(s) is displayed.
Following this there are specified: the device address, the
endpoint, the data toggle bit and the maximum packet length.
If buffer_length is greater than actual_length (maximum
there will be buffer_length divided by actual_length number of
transactions. These will be displayed beneath each other here.
c) The final line shows the bytes in hexadecimal of the
or returned by this transaction.
For control transactions, the request is also displayed
beginning of the transaction.
For OHCI transactions the trace is set up differently.
For control transactions, the request is also displayed
beginning of the transaction.
An OHCI transaction is set up by an endpoint descriptor
(ED:) and an
transaction descriptor (TD:). The trace will list both after the transaction.
It will also show the TC field of the endpoint descriptor,
the value in
the toggle field of the transaction descriptor and the completion code in
numeric and text form followed by the number of bytes transfered.
7. Planned features for the next release
- support for isochronous transfers in OHCI.
8. USB reference material
Writing USB device drivers requires a good understanding
USB specifications. Here are some documents to get started:
"USB in a nutshell"
A good introduction to the USB specifications. Available from:
"USB Made Simple"
Another fine introduction by MQP Electronics.
Some notes about the USB specifications can be found here:
"Universal Host Controller Interface (UHCI) Design
Guide" by Intel.
This is the interface DosUSB is based on for its UHCI part.
"OpenHCI Open Host Controller Interface Specification
for USB" by Compay, Microsoft,
National Semiconductor. This is the specification for the OHCI part of DosUSB.
"USB 2.0 specifications"
Once you've read "USB in a nutshell" you have to consult this reference.
"USB complete" by Jan Axelson
Probably the most important book on USB. The author's web site is:
"USB Tracker" by Ellisys
This is a good USB scope and currently one with a relatively low
price. If you download their demonstration software, you get
excellent examples of USB communications with different devices.
To write a device driver for a floppy drive or mass storage
device you will usually only need the class specifications from
www.usb.org. However, many devices have vendor specific commands
which often are not made available. Some of these specifications
can be gathered from the Linux USB driver implementations.
9. USB analysers
If you develop a device driver using DosUSB, a USB protocol
analyser will be of great value.
The best choice is a hardware monitor such as the USB
Besides this device, there are software USB analysers
USB Monitor at www.hddsoftware.com,
USBinfo at http://lpt.usbfireinfo.com
or SourceUSB at http://www.sourcequest.com.
There is also a free software USB sniffer at
These tools are cheaper than the USB Tracker but only
to monitor the traffic between Windows and a USB device. However,
you can see how windows communicates with the device.
Finally there are devices which allow you to use a logic
to monitor USB traffic: www.futureplus.com.
The package contains samples of programs which use the
driver. These are not complete device drivers, they shall only
show the functionality of the DosUSB driver.
USBVIEW is a Powerbasic program which will display all
descriptors of a device.
ADDRESS is a utility in Powerbasic which displays all
and their device addresses.
MOUSE is a demo program which reads the input from a USB mouse.
LQ590.bas is a sample which prints a short text on an
HPLASER.bas will print the file DOSUSB.TXT on a HP Laserprinter.
It uses PCL commands to set up the printer for text output.
Most low cost USB printers are GDI or Windows printers
which will not
print ASCII codes sent to them. They expect data which controls their
print head. This protocol is vendor specific and usually not available.
If a printer accepts ASCII code via its parallel interface, it usually
can also do this via its USB interface. GDI printers can only be used with
Win 3.11 since there are no GDI drivers for DOS available.
SETALT.bas is a sample to set an alternate interface of a device.
ENUM.c is a Turbo C sample to retrieve a device descriptor.
ENUM.bas is a Powerbasic sample to retrieve a device descriptor.
ENUM.asm retrieves a device descriptor using assembler.
HPLASER.pas is a sample in Pascal to print dosusb.txt
to an HP Laserjet
Michel LECLERC translated HPLASER.bas to this Pascal sample.
HPLASERV.bas is a Visual Basic for DOS sample to print
dosusb.txt to an
HP Laserjet printer. Converted from hplaser.bas for Powerbasic.
RESET.bas resets and enumerates all connected devices.
This will not check
for additionally connected devices and not remove the addresses
for disconnected devices. So the addresses for all devices will not change.
RESTART.bas resets and enumerates all connected devices.
This will assign
addresses to additionally connected devices and remove the addresses
for disconnected devices. The addresses for other devices may change.
ICHECK.bas checks whether the DosUSB driver is installed and running.
KEYBOARD.bas reads the keys typed on a USB keyboard. The
USB HID to PS/2
scan code translation table can be found at the microsoft site in the document:
CABLE.bas is a sample which sends data via a PC connect
USB cable from one
USB port to a second USB port.
READER.bas reads sector zero of a memory card in a USB card reader.
STICK.BAS is very similar to READER.bas and reads sector
zero of a
USB memory stick.
STICK.PAS, RESTART.PAS and RESET.PAS are samples converted
Pascal by Joe da Silva
FLOPPY.bas will read the boot sector of a floppy in a USB floppy drive.
CAMERA.bas reads isochronous data from a Trust 120 Spacecam
saves it in the file image.yuv. Will run with UHCI only.
SCANNER.bas is a sample which reads the identity of an
1670 scanner. This does not use the ESC/I commands.
PRNUSB.sys is a printer device driver which uses DosUSB
to print to USB
printers. Tested with a HP 2420d Laserprinter and will also run with a
HP 880C, a HP 5940 and a HP 460C inkjet printer. It will also work with
parallel to USB adapters. Check the endpoints and use the setalt utility to
set the interface before printing here.
It is loaded with a "device=" statement in the
config.sys file. Load
DosUSB then, do not use the /D command line option here!
The default device address is one, the default device endpoint is two. Use
the command line options e.g. /D2 /E1 to select device address two and
endpoint number one. Use USBView to determine the right settings for your
Cannot be used with low cost GDI printers, since these do not accept ASCII
code for printing. However, since drivers for GDI printers are available for WIN 3.11,
if you use DosUSB and PRNUSB.SYS with WIN 3.11, you can also use these GDI printers with PRNUSB.SYS.There are no drivers for these printers in DOS, however.
Use "type dosusb.txt > prnusb" to print this file from the DOS prompt. Or
open "prnusb" as a file in your application program.
PRNUSB.asm is the source code for this driver.
LPT1USB.SYS is a variant of PRNUSB.SYS which installs
as a LPT1: device. So
you can print from the DOS Editor or other application programs directly.
USBDISK.SYS is a device driver for flash drives and other
mass storage devices
such as USB hard disks and PCMCIA cards in USB card readers.
It is currently provided as a beta version.
Since DosUSB does not support EHCI which allows for higher
the transfer is a bit slower than the one achived with Windows.
It is loaded with a "device=" statement in the
config.sys file such as:
device=c:\dosusb\usbdisk.sys provided the file usbdisk.sys in the c:\dosusb
directory on your hard disk.
If you have more than one USB device connected to the
PC and the flash drive
is not the first device to get address number one, you can use the /D command
line option. This way you can specify the address of the flash drive. DosUSB
will always give the same address to each device connected to the PC as long
as no device is removed or added. So if you found out, which address the
flash drive gets from DosUSB you can specify that with the /D option. Without
the /D option USBDISK.SYS assumes address one.
USBDISK.SYS reads the device descriptor to determine the endpoints so these do
not need to be set by a command line option.
Then boot the PC to have DOS load usbdisk.sys as specified in config.sys.
When DOS boots and loads the USBDISK.SYS driver, the driver
will display the drive
letter DOS has assigned to the mass storage device.
Plug in your flash drive now. Always use the same slot,
to avoid to get a
different address than before.
Start dosusb (without the /D option for log-file creation)
Now you can do a "dir" command on the flash
drive and copy files from the drive
to the hard disk and from the disk to the drive. You can also delete files etc.
Even if there are no files in the directory, DOS does a lot of reads which
will cause a long delay at the end of the "dir" command to determine the free space
on the device. Using "dir" with the "/B" option will be much quicker.
If you want to boot the PC from a floppy disk or CD, DOS
will often not assign a drive
letter which is correct when usbdisk.sys is loaded using the config.sys file. In this case
you should not put usbdisk.sys into the config.sys file but use the devload.com utility to
load usbdisk.sys later after loading DOSUSB.COM.
USBDISK.SYS does not support changing the mass storage device yet. If you connect a different flash disk you have to reboot your PC to reload USBDISK.SYS or your data will be corrupted.
If the mass storage device is not formatted it is not supported by USBDISK.SYS. It will not return that the device is unformatted.
USBDISK.SYS will just access the first partition of a USB hard disk.
If your flash disk has a write protect switch, this will not be queried by USBDISK.SYS. So DOS can copy to the flash disk even when the write protect switch is set.
Windows opens a small window showing how much data has
been copied. DOS does
not do that. So with large files it seems that nothing is happening - but
DOS does copy!
Better remove usbdisk from the config.sys file before
booting Windows - some Windows
versions may try to access the device which USBDISK.SYS provides when running SCANDISK.
So there are several issues left to improve for the next release. However, it took quite a lot of time to develop USBDISK.SYS and it can be used to transfer files successfully now.
17th February 2007 Georg Potthast