Synchronous Requests

This document describes the use of synchronous requests by device drivers.

Synchronous requests

Synchronous requests are typically used to set or retrieve some information for the device driver. These requests almost never need to access the hardware itself, and usually complete relatively quickly. They return only after the completion of the request and the user side thread is blocked till completion. Synchronous requests are usuallly initiated by a call to RBusLogicalChannel::DoControl(). The request is most likely to be executed in the context of the client user-side thread.

A driver lists its available synchronous requests in an enumeration, for example:

// Synchronous control messages used with DoControl()
enum TControl 
    {
    EControlConfigure, // Configure the device (UART)
    EControlTransmitData, // Transmit data over the device (UART)    
    EControlReceiveData,    // Receive the data from the device 
    ENumRequests, // Number of synchronous control requests
    AllRequests = (1<<ENumRequests)-1
    };

Implementation

Drivers generally implement the DoControl() function in the LDD to handle the received synchronous messages. The implementation reads the request type and other passed arguments, and handles the request appropriately. For example, the following handles RExDriver::EControlConfigure requests:

TInt DExDriverLogicalChannel::DoControl(TInt aFunction, TAny* a1, TAny* /*a2*/)
    {
    switch (aFunction)
        {
        case RExDriver::EControlConfigure:
            memclr(&c, sizeof(c)));
            TPtr8 cfg((TUint8*)&c, 0, sizeof(c)));
            r = Kern::ThreadDesRead(iClient,a1,cfg,0,0);
            if (r==KErrNone)
                Pdd()->Configure(&c);
            break;
            ...
        default:
                r = KErrNotSupported;
        }
    return r;
    }