|
|
|
Location:
k32std.h
Link against: ekern.lib
DLogicalChannel
Supported from 5.0
The Kernel side logical channel.
This class defines the Kernel side interface to the logical device. The class consists of a number of virtual functions which must be overriden in a derived class.
A Kernel side logical channel is created by a factory object, an
instance of a DLogicalDevice derived class.
|
Defined in DLogicalChannel:
Cancel(), Close(), Complete(), CompleteAll(), Control(), DLogicalChannel(), Device(), DoCancel(), DoControl(), DoCreateL(), DoRequest(), IsPending(), Request(), SetBehaviour(), iDevice, iRequestStatus, iThread, iValidRequests, ~DLogicalChannel()
Inherited from CBase:
operator new()
Inherited from CObject:
AccessCount(),
Dec(),
FullName(),
Inc(),
Name(),
Open(),
Owner(),
SetName(),
SetNameL(),
SetOwner(),
UniqueID()
protected : DLogicalChannel(DLogicalDevice* aDevice);
Constructs the object with a pointer to the LDD factory object.
The specified LDD factory object is responsible for the construction of this logical channel.
The LDD factory object keeps a count of the number of logical channels constructed from it; this count is incremented by one. The LDD factory object cannot be freed while any logical channel constructed from it remains open.
Typically, a derived class constructor:
calls this constructor in its constructor initialisation list
includes a call to SetBehaviour() to enable
specific request numbers. This must be done before any asynchronous requests
can be made.
|
protected : ~DLogicalChannel();
Destructor.
The LDD factory object keeps a count of the number of logical channels constructed from it; the logical channel's destructor reduces this count by one. The LDD factory object cannot be freed while any logical channel constructed from it remains open.
Typically, there are number of requirements on a derived class.
If the device performs power handling, and this is implemented by the logical channel, then the derived class's destructor must ask the power handler to power down the device; the steps involved are:
to put the device into standby power mode
to remove the device's power handler from the system, i.e. de-register the power handler
to delete the power handler object.
The typical instruction sequence is:
...
iPowerHandler->PowerStandby();
...
Power::RemovePowerHandler(iPowerHandler);
...
delete iPowerHandler;
...
where iPowerHandler is of type
DPowerHandler*.
If the logical channel creates a physical channel, then it has ownership of this physical channel and is responsible for its destruction; typically, this done by the derived class's destructor.
It is also good practice for the derived class destructor to:
complete all outstanding requests by calling
CompleteAll(KErrAbort)
cancel any queued DFCs.
void Request(TInt aReqNo,TRequestStatus& aStatus,TAny* a1,TAny* a2);
Performs the initial handling of an asynchronous request.
The function is called by the Kernel as a result of a user side
call to RBusLogicalChannel::DoRequest().
The function calls this class's DoRequest() to
handle the request.
|
void Cancel(TUint aReqMask);
Performs the initial handling of an asynchronous request cancellation.
The function is called by the Kernel as result of a user side
call to RBusLogicalChannel::DoCancel().
Each bit in the TUint argument corresponds to the
request number specified in the original asynchronous request. For each
outstanding request specified in the argument, the function:
completes that request with KErrCancel
calls this class's DoCancel() to deal with the
detail of the cancellation operation.
|
TInt Control(TInt aFunction,TAny* a1,TAny* a2);
Performs the initial handling of a synchronous request.
The function is called by the Kernel as a result of a user side call to either:
RBusLogicalChannel::DoControl()
RBusLogicalChannel::DoSvControl()
This function runs in the context of the Kernel server, if the
user side called RBusLogicalChannel::DoSvControl().
The function calls this class's DoControl() to
handle the request.
|
|
protected : virtual void DoRequest(TInt aReqNo,TAny* a1,TAny* a2) = 0;
Handles an asynchronous request.
The function is called by this class's Request()
function as a result of a user side asynchronous Kernel Executive type request.
A Kernel Executive type request means that no allocation or de-allocation of
memory on the Kernel heap is possible.
Up to 4 asynchronous requests, each identified by a different
request number (0 - 3), can be outstanding at the same time. By default, no
requests are enabled. DLogicalChannel::SetBehaviour() must be
called to enable the appropriate requests.
Typically, the function is implemented as a series of switch statements.
Completion of the request at some later time, involving the
setting of the TRequestStatus object and the signalling of the
originator's thread, is handled by a call to the logical channel's
DLogicalChannel::Complete() function. As this updates the ready
queue and writes to the user side address space, it must not be called by the
Interrupt Service Routine directly (ISR); instead, the ISR should queue a
Delayed Function Call (DFC) which can safely call it.
|
Request() before
calling this function.protected : virtual void DoCancel(TInt aReqNo) = 0;
Handles the cancellation of an asynchronous request.
This function is called by this class's Cancel()
function.
|
Cancel() before this function is called. This means that
implementers need not worry about setting the request status or signalling to
the originating thread that the request is complete. Instead, the
implementation should just concern itself with doing whatever tidying up is
needed.protected : virtual void DoCreateL(TInt aUnit,CBase* aDriver,const TDesC* anInfo,const TVersion& aVer);
Performs secondary initialisation of the logical channel.
The function is called by the Kernel as part of the
construction and initialization of this logical channel object and is a result
of a user side call to RBusLogicalChannel::DoCreate().
The default implementation is empty.
If the device has power handling capability, and this is implemented in this logical channel, then its power handler should be created here, registered with the system's power model, and the device powered on.
The typical instruction sequence is:
...
iPowerHandler=new (ELeave) DDerivedPowerHandler(this);
...
User::LeaveIfError(Power::AddPowerHandler(iPowerHandler));
...
iPowerHandler->PowerOn();
...
where iPowerHandler is of type
DPowerHandler* and is, typically, a data member of the class
derived from DLogicalChannel.
This function should also check the requested version against the version with which this logical channel was built.
For those drivers which implement unit numbers but do not employ a PDD, then the specified unit number should be verified here.
|
RBusLogicalChannel::DoCreate()Power::AddPowerHandler()DPowerHandler::PowerOn()DPhysicalDevice::CreateL()DLogicalDevice::CreateL()protected : virtual TInt DoControl(TInt aFunction,TAny* a1,TAny* a2);
Handles a synchronous request.
The function is called by this class's Control()
function as a result of a user side synchronous Kernel Executive type request
or a synchronous Kernel Server type request. The function can only allocate or
de-allocate memory on the Kernel heap when running in the context of the Kernel
server
Implementers must use the function number to distinguish between the two situations.
Typically, DoControl() is implemented as a switch
statement based on the function number passed to it.
Device drivers can be queried about their capabilities; this is
often implemented by DoControl().
The default implementation returns
KErrNotSupported.
|
|
protected : virtual void Close();
Closes the logical channel.
This function is called by the Kernel in the context of the
Kernel Server as a result of closing the user side handle to this logical
channel, i.e. as a result of a user side call to Close() on the
RBusLogicalChannel.
The default implementation makes a base call to
CObject::Close() to reduce the reference count. An implementation
provided by a derived class should make a base call to this
Close() function after it has done its own specific
processing.
RBusLogicalChannel does not
re-implement the Close() function defined in the
RHandleBase class.protected : TBool IsPending(TInt aReqNo) const;
Determines whether the request associated with the specified request number is pending.
|
|
protected : DLogicalDevice* Device();
Gets a pointer to the LDD factory object that created this logical channel.
|
protected : void Complete(TInt aReqNo);
protected : void Complete(TInt aReqNo,TInt aReason);
Completes the outstanding request identified by the specified request number.
|
KMaxRequests, otherwise the Kernel panics KERN 2; the
request number must be valid, defined by a call to SetBehaviour(),
otherwise the Kernel panics KERN 3; there must be an outstanding request
corresponding to specified request number, otherwise the Kernel panics KERN
4.protected : void CompleteAll(TInt aReason);
Completes all outstanding requests.
|
protected : void SetBehaviour(TUint aValidRequests);
Defines which request numbers are valid.
The maximum possible request number is the value of
KMaxRequests-1.
Typically, this function is called by the constructor of the derived class. In any event, it must be called before any asynchronous requests are made.
|
RBusLogicalChannel::DoRequest() function that does not correspond
to a number defined by this function, causes a KERN-EXEC 18 panic to be
raised.private : TRequestStatus *iRequestStatus[KMaxRequests];
This is internal and is not intended for use.
private : DLogicalDevice *iDevice;
This is internal and is not intended for use.