[Contents] [index] [Help] [Retrace] [browse <] [Browse >]

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