Once a device has been opened, you use it by passing the I/O request to
it. When the device processes the I/O request, it acts on the information
the I/O request contains and returns a reply message, i.e., the I/O
request, to the message port when it is finished. The I/O request is
passed to a device using one of three functions, DoIO(), SendIO() and
BeginIO(). They take only one argument: the I/O request you wish to pass
to the device.
* DoIO() is a synchronous function. It will not return until the
device has finished with the I/O request. DoIO() will wait, if
necessary, for the request to complete, and will remove (GetMsg())
any reply message from the message port.
* SendIO() is an asynchronous function. It can return immediately, but
the I/O operation it initiates may take a short or long time. SendIO
is normally used when your application has other work to do while the
I/O request is being acted upon, or if your application wishes to
allow the user to cancel the I/O. Using SendIO() requires that you
wait on or check for completion of the request, and remove the
completed request from the message port with GetMsg().
* BeginIO() is commonly used to control the QuickIO bit when sending an
I/O request to a device. When the QuickIO flag (IOF_QUICK) is set in
the I/O request, a device is allowed to take certain shortcuts in
performing and completing a request. If the request can complete
immediately, the device will not return a reply message and the
QuickIO flag will remain set. If the request cannot be completed
immediately, the QUICK_IO flag will be clear. DoIO() normally
requests QuickIO; SendIO() does not.
An I/O request typically has three fields set for every command sent to a
device. You set the command itself in the io_Command field, a pointer to
the data for the command in the io_Data field, and the length of the data
in the io_Length field.
SerialIO->IOSer.io_Length = sizeof(ReadBuffer);
SerialIO->IOSer.io_Data = ReadBuffer;
SerialIO->IOSer.io_Command = CMD_READ;
SendIO((struct IORequest *)SerialIO);
Commands consist of two parts (separated by an underscore, all in upper
case): a prefix and the command word. The prefix indicates whether the
command is an Exec or device specific command. All Exec standard commands
have "CMD" as the prefix. They are defined in the include file
<exec/io.h>.
Table 19-2: Standard Exec Device Commands
CMD_READ CMD_START CMD_UPDATE CMD_CLEAR
CMD_WRITE CMD_STOP CMD_FLUSH CMD_RESET
You should not assume that a device supports all standard Exec device
commands. Always check the documentation before attempting to use one of
them. Device-specific command prefixes vary with the device.
Table 19-3: System Device Command Prefixes
Device Prefix Example
------ ------ -------
Audio ADCMD ADCMD_ALLOCATE
Clipboard CBD CBD_POST
Console CD CD_ASKKEYMAP
Gameport GPD GPD_SETCTYPE
Input IND IND_SETMPORT
Keyboard KBD KBD_READMATRIX
Narrator no device specific commands -
Parallel PDCMD PDCMD_QUERY
Printer PRD PRD_PRTCOMMAND
SCSI HD HD_SCSICMD
Serial SDCMD SDCMD_BREAK
Timer TR TR_ADDREQUEST
Trackdisk TD and ETD TD_MOTOR/ETD_MOTOR
Each device maintains its own I/O request queue. When a device receives
an I/O request, it either processes the request immediately or puts it in
the queue because one is already being processed. After an I/O request is
completely processed, the device checks its queue and if it finds another
I/O request, begins to process that request.
Synchronous Vs. Asynchronous Requests I/O Request Completion
[Back to Amiga Developer Docs]