forked from KolibriOS/kolibrios
USB support
git-svn-id: svn://kolibrios.org@3520 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
183
kernel/trunk/docs/usbapi.txt
Normal file
183
kernel/trunk/docs/usbapi.txt
Normal file
@@ -0,0 +1,183 @@
|
||||
When the kernel detects a connected USB device, it configures the device in
|
||||
terms of USB protocol - SET_ADDRESS + SET_CONFIGURATION, the first
|
||||
configuration is always selected. The kernel also reads device descriptor to
|
||||
print some information, reads and parses configuration descriptor. For every
|
||||
interface the kernel looks for class code of this interface and loads the
|
||||
corresponding COFF driver. Currently the correspondence is hardcoded into
|
||||
the kernel code and looks as follows: 3 = usbhid.obj, 8 = usbstor.obj,
|
||||
9 is handled by the kernel itself, other = usbother.obj.
|
||||
|
||||
The driver must be standard driver in COFF format, exporting procedure
|
||||
named "START" and a variable named "version". Loader calls "START" procedure
|
||||
as stdcall with one parameter DRV_ENTRY = 1; if initialization is successful,
|
||||
the "START" procedure is also called by shutdown code with one parameter
|
||||
DRV_EXIT = -1.
|
||||
|
||||
The driver must register itself as a USB driver in "START" procedure.
|
||||
This is done by call to exported function RegUSBDriver and passing the returned
|
||||
value as result of "START" procedure.
|
||||
|
||||
void* __stdcall RegUSBDriver(
|
||||
const char* name,
|
||||
void* handler,
|
||||
const USBFUNC* usbfunc
|
||||
);
|
||||
|
||||
The parameter 'name' should match the name of driver, "usbhid" for usbhid.obj.
|
||||
The parameter 'handler' is optional; if it is non-NULL, it should point to
|
||||
the standard handler for IOCTL interface as in non-USB drivers.
|
||||
The parameter 'usbfunc' is a pointer to the following structure:
|
||||
|
||||
struc USBFUNC
|
||||
{
|
||||
.strucsize dd ? ; size of the structure, including this field
|
||||
.add_device dd ? ; pointer to AddDevice function in the driver
|
||||
; required
|
||||
.device_disconnect dd ? ; pointer to DeviceDisconnected function in the driver
|
||||
; optional, may be NULL
|
||||
; other functions may be added in the future
|
||||
}
|
||||
|
||||
The driver should implement the function
|
||||
|
||||
void* __stdcall AddDevice(
|
||||
void* pipe0,
|
||||
void* configdescr,
|
||||
void* interfacedescr
|
||||
);
|
||||
|
||||
The parameter 'controlpipe' is a handle of the control pipe for endpoint zero
|
||||
of the device. It can be used as the argument of USBControlTransferAsync.
|
||||
The parameter 'configdescr' points to USB configuration descriptor
|
||||
and all associated data, as returned by GET_DESCRIPTOR request.
|
||||
The total length of all associated data is contained in the configuration
|
||||
descriptor.
|
||||
The parameter 'interfacedescr' points to USB interface descriptor corresponding
|
||||
to the interface which is initializing. This is a pointer inside data
|
||||
associated with the configuration descriptor.
|
||||
Note that one device can implement many interfaces, so AddDevice may be
|
||||
called several times with the same 'configdescr' and different 'interfacedescr'.
|
||||
The returned value NULL means that the initialization has failed.
|
||||
Any other value means that configuration was successful; the kernel does not
|
||||
try to interpret the value. It can be, for example, pointer to the internal
|
||||
data allocated with Kmalloc, or index in some internal table. Remember that
|
||||
Kmalloc() is NOT stdcall, it destroys ebx.
|
||||
|
||||
The driver can implement the function
|
||||
|
||||
void __stdcall DeviceDisconnected(
|
||||
void* devicedata
|
||||
);
|
||||
|
||||
If this function is implemented, the kernel calls it when the device is
|
||||
disconnected, passing the returned value of AddDevice as 'devicedata'.
|
||||
|
||||
The driver can use the following functions exported by the kernel.
|
||||
|
||||
void* __stdcall USBOpenPipe(
|
||||
void* pipe0,
|
||||
int endpoint,
|
||||
int maxpacketsize,
|
||||
int type,
|
||||
int interval
|
||||
);
|
||||
|
||||
The parameter 'pipe0' is a handle of the pipe for endpoint zero for
|
||||
the device, as passed to AddDevice. It is used to identify the device.
|
||||
The parameter 'endpoint' is endpoint number as defined by USB. Lower
|
||||
4 bits form the number itself, bit 7 - highest bit of low byte -
|
||||
is 0/1 for OUT/IN endpoints, other bits should be zero.
|
||||
The parameter 'maxpacketsize' sets the maximum packet size for this pipe.
|
||||
The parameter 'type' selects the type of the endpoint as defined by USB:
|
||||
0 = control, 1 = isochronous (not supported yet), 2 = bulk, 3 = interrupt.
|
||||
The parameter 'interval' is ignored for control and bulk endpoints.
|
||||
For interrupt endpoints, it sets the polling interval in milliseconds.
|
||||
The function returns a handle to the pipe or NULL on failure.
|
||||
|
||||
void* __stdcall USBNormalTransferAsync(
|
||||
void* pipe,
|
||||
void* buffer,
|
||||
int size,
|
||||
void* callback,
|
||||
void* calldata,
|
||||
int flags
|
||||
);
|
||||
void* __stdcall USBControlTransferAsync(
|
||||
void* pipe,
|
||||
void* config,
|
||||
void* buffer,
|
||||
int size,
|
||||
void* callback,
|
||||
void* calldata,
|
||||
int flags
|
||||
);
|
||||
|
||||
The first function inserts a bulk or interrupt transfer to the transfer queue
|
||||
for given pipe. Type and direction of transfer are fixed for bulk and interrupt
|
||||
endpoints and are set in USBOpenPipe. The second function inserts a control
|
||||
transfer to the transfer queue for given pipe. Direction of a control transfer
|
||||
is concluded from 'config' packet, bit 7 of byte 0 is set for IN transfers
|
||||
and cleared for OUT transfers. These function return immediately; when data
|
||||
are transferred, the callback function will be called.
|
||||
|
||||
The parameter 'pipe' is a handle returned by USBOpenPipe.
|
||||
The parameter 'config' of USBControlTransferAsync points to 8-byte
|
||||
configuration packet as defined by USB.
|
||||
The parameter 'buffer' is a pointer to buffer. For IN transfers, it will be
|
||||
filled with the data. For OUT transfers, it should contain data to be
|
||||
transferred. It can be NULL for an empty transfer or if no additional data are
|
||||
required for a control transfer.
|
||||
The parameter 'size' is size of data to transfer. It can be 0 for an empty
|
||||
transfer or if no additional data are required for a control transfer.
|
||||
The parameter 'callback' is a pointer to a function which will be called
|
||||
when the transfer will be done.
|
||||
The parameter 'calldata' will be passed as is to the callback function.
|
||||
For example, it can be NULL, it can be a pointer to device data or it can be
|
||||
a pointer to data used to pass additional parameters between caller and
|
||||
callback. The transfer-specific data can also be associated with 'buffer',
|
||||
preceding (negative offsets from 'buffer') or following (offsets more than
|
||||
or equal to 'size') the buffer itself.
|
||||
The parameter 'flags' is the bitmask.
|
||||
The bit 0 is ignored for OUT transfers, for IN transfers it controls whether
|
||||
the device can transfer less data than 'size' bytes. If the bit is 0, a small
|
||||
transfer is an error; if the bit is 1, a small transfer is OK.
|
||||
All other bits are reserved and should be zero.
|
||||
The returned value is NULL if an error occured and non-NULL if the transfer
|
||||
was successfully queued. If an error will occur later, the callback function
|
||||
will be notified.
|
||||
|
||||
void __stdcall CallbackFunction(
|
||||
void* pipe,
|
||||
int status,
|
||||
void* buffer,
|
||||
int length,
|
||||
void* calldata
|
||||
);
|
||||
|
||||
The parameters 'pipe', 'buffer', 'calldata' are the same as for the
|
||||
corresponding USB*TransferAsync.
|
||||
The parameter 'length' is the number of bytes transferred. For
|
||||
control transfers, this includes 8 bytes from SETUP stage, so
|
||||
0 means that SETUP stage failed and 'size'+8 means full transfer.
|
||||
The parameter 'status' is nonzero if an error occured.
|
||||
USB_STATUS_OK = 0 ; no error
|
||||
USB_STATUS_CRC = 1 ; CRC error
|
||||
USB_STATUS_BITSTUFF = 2 ; bit stuffing violation
|
||||
USB_STATUS_TOGGLE = 3 ; data toggle mismatch
|
||||
USB_STATUS_STALL = 4 ; device returned STALL
|
||||
USB_STATUS_NORESPONSE = 5 ; device not responding
|
||||
USB_STATUS_PIDCHECK = 6 ; invalid PID check bits
|
||||
USB_STATUS_WRONGPID = 7 ; unexpected PID value
|
||||
USB_STATUS_OVERRUN = 8 ; too many data from endpoint
|
||||
USB_STATUS_UNDERRUN = 9 ; too few data from endpoint
|
||||
USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer
|
||||
; possible only for isochronous transfers
|
||||
USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
|
||||
; possible only for isochronous transfers
|
||||
USB_STATUS_DISCONNECTED = 16 ; device disconnected
|
||||
|
||||
If several transfers are queued for the same pipe, their callback functions
|
||||
are called in the same order as they were queued.
|
||||
When the device is disconnected, all callback functions are called
|
||||
with USB_STATUS_DISCONNECTED. The call to DeviceDisconnected() occurs after
|
||||
all callbacks.
|
Reference in New Issue
Block a user