--- a/kernel/eka/include/drivers/dma_v2.h Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dma_v2.h Tue May 04 09:44:26 2010 +0100
@@ -18,6 +18,10 @@
// generic header file <drivers/dma.h>.
//
+/** @file
+ @publishedPartner
+*/
+
#ifndef __DMA_H__
#error "dma_v2.h must'n be included directly - use <drivers/dma.h> instead"
#endif // #ifndef __DMA_H__
@@ -67,14 +71,14 @@
Some peripherals may require a post-increment address mode.
@see DDmaRequest::Fragment
- @publishedPartner
- @released
+
+ Note: This enum is only required for backwards compatibility with the old
+ DMA framework, it can be removed once this is no longer needed.
+
+ @deprecated
*/
enum TDmaRequestFlags
{
- // Note: This enum is only required for backwards compatibility with the
- // old DMA framework, it can be removed once this is no longer needed.
-
/** Source is address of memory buffer */
KDmaMemSrc = 0x01,
/** Destination is address of memory buffer */
@@ -96,7 +100,6 @@
are needed because hardware descriptors can not easily be extended to store
additional information.
- @publishedPartner
@released
*/
struct SDmaDesHdr
@@ -104,18 +107,23 @@
SDmaDesHdr* iNext;
};
+
/** Pointer to signature of the new extended callback function.
- TUint - bitmask of one or more TDmaCallbackType values
- TDmaResult - just that
- TAny* - was provided by client in DDmaRequest constructor
+ TUint - bitmask of one or more TDmaCallbackType values
+ TDmaResult - just that
+ TAny* - was provided by client in DDmaRequest constructor
SDmaDesHdr* - points to header (and thus descriptor) which caused a
- 'descriptor completed' or 'descriptor paused' event.
+ 'descriptor completed' or 'descriptor paused' event
+
+ @released
*/
typedef void (*TDmaCallback)(TUint, TDmaResult, TAny*, SDmaDesHdr*);
+
class TDmaChannel;
+
/** A DMA request is a list of fragments small enough to be transferred in one go
by the DMAC.
@@ -132,10 +140,7 @@
Mutexes are used internally to protect data structures accessed both by the
client thread and the DFC thread. Therefore no fast mutex can be held when
calling a request function.
-
- @publishedPartner
- @released
- */
+*/
class DDmaRequest : public DBase
{
friend class TDmaChannel;
@@ -143,14 +148,17 @@
public:
/** The outcome of the transfer
+ @see TDmaResult
+
@deprecated
- @see TDmaResult
*/
enum TResult {EBadResult=0, EOk, EError};
+
/** The signature of the completion/failure callback function
+ @see TDmaCallback
+
@deprecated
- @see TDmaCallback
*/
typedef void (*TCallback)(TResult, TAny*);
@@ -183,15 +191,19 @@
@param aMaxTransferSize Maximum fragment size. If not specified,
defaults to the maximum size supported by the DMA controller for the
type of transfer that is later scheduled.
+
+ @released
*/
- IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb, TAny* aCbArg=NULL,
- TUint aMaxTransferSize=0);
+ IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb,
+ TAny* aCbArg=NULL, TUint aMaxTransferSize=0);
/** Destructor.
Assume the request is not being transferred or pending.
- */
+
+ @released
+ */
IMPORT_C ~DDmaRequest();
@@ -212,6 +224,15 @@
previously. The previous configuration if any is lost whether or not
the function succeeds.
+ The client must ensure that any memory buffers involved in the transfer
+ have been suitably prepared for DMA. For memory allocated on the kernel
+ side or in a shared chunk this amounts to ensuring cache consistency
+ before Queue() is called. However for memory that was allocated on the
+ user side the client must also ensure that the memory is protected from
+ both data paging and RAM defragmentation before Fragment() is called
+ @see Kern::MapAndPinMemory(). Note however, that this function is only
+ available if the flexible memory model (FMM) is in use.
+
@param aSrc Source memory buffer linear address or peripheral magic
cookie.
@param aDest Destination memory buffer linear address or peripheral
@@ -237,6 +258,38 @@
/** New version of the DMA request fragment function, to be used with the
TDmaTransferArgs structure.
+
+ Split request into a list of fragments small enough to be fed to the
+ DMAC.
+
+ The size of each fragment is smaller than or equal to the maximum
+ transfer size supported by the DMAC. If the source and/or destination
+ is memory, each fragment points to memory which is physically
+ contiguous.
+
+ The request can be uninitialised or may have been fragmented
+ previously. Any previous configuration is lost whether or not the
+ function succeeds.
+
+ The client must ensure that any memory buffers involved in the transfer
+ have been suitably prepared for DMA. For memory allocated on the kernel
+ side or in a shared chunk this amounts to ensuring cache consistency
+ before Queue() is called. However for memory that was allocated on the
+ user side the client must also ensure that the memory is protected from
+ both data paging and RAM defragmentation before Fragment() is called
+ @see Kern::MapAndPinMemory(). Note however, that this function is only
+ available if the flexible memory model (FMM) is in use.
+
+ @param aTransferArgs Describes the transfer to be performed.
+
+ @return KErrNone if success. KErrArgument if certain arguments are
+ invalid. May also fail if running out of descriptors.
+
+ @pre The request is not being transferred or pending.
+ @pre The various parameters must be valid. The PIL or PSL will fault
+ the kernel if not.
+
+ @released
*/
IMPORT_C TInt Fragment(const TDmaTransferArgs& aTransferArgs);
@@ -250,11 +303,13 @@
after the transfer if necessary.
@return KErrNone if success, KErrGeneral otherwise.
- */
+
+ @released
+ */
IMPORT_C TInt Queue();
- /** Append new descriptor(s) to existing list.
+ /** Append new descriptor(s) to existing list.
Clients needing to build a custom descriptor list should call this
function to allocate the list and access the resulting list through
@@ -270,11 +325,13 @@
@param aCount Number of descriptors to append.
@return KErrNone or standard error code.
- */
+
+ @released
+ */
IMPORT_C TInt ExpandDesList(TInt aCount=1);
- /** Append new descriptor(s) to existing list. This function variant
+ /** Append new descriptor(s) to existing list. This function variant
operates on the source port descriptor chain.
Works like ExpandDesList except that it uses the iSrcFirstHdr and
@@ -288,11 +345,13 @@
@param aCount Number of descriptors to append.
@return KErrNone or standard error code.
- */
+
+ @prototype
+ */
IMPORT_C TInt ExpandSrcDesList(TInt aCount=1);
- /** Append new descriptor(s) to existing list. This function variant
+ /** Append new descriptor(s) to existing list. This function variant
operates on the destination port descriptor chain.
Works like ExpandDesList except that it uses the iDstFirstHdr and
@@ -306,14 +365,18 @@
@param aCount Number of descriptors to append.
@return KErrNone or standard error code.
- */
+
+ @prototype
+ */
IMPORT_C TInt ExpandDstDesList(TInt aCount=1);
/** Free resources associated with this request.
Assume the request is not being transferred or pending.
- */
+
+ @released
+ */
IMPORT_C void FreeDesList();
@@ -324,7 +387,9 @@
This function can only be used if SDmacCaps::iAsymHwDescriptors is
true, otherwise it will do nothing.
- */
+
+ @prototype
+ */
IMPORT_C void FreeSrcDesList();
@@ -335,7 +400,9 @@
This function can only be used if SDmacCaps::iAsymHwDescriptors is
true, otherwise it will do nothing.
- */
+
+ @prototype
+ */
IMPORT_C void FreeDstDesList();
@@ -367,6 +434,8 @@
@see Queue()
@see TotalNumSrcElementsTransferred()
+
+ @prototype
*/
IMPORT_C void EnableSrcElementCounting(TBool aResetElementCount=ETrue);
@@ -399,6 +468,8 @@
@see Queue()
@see TotalNumDstElementsTransferred()
+
+ @prototype
*/
IMPORT_C void EnableDstElementCounting(TBool aResetElementCount=ETrue);
@@ -427,6 +498,8 @@
@see Queue()
@see TotalNumSrcElementsTransferred()
+
+ @prototype
*/
IMPORT_C void DisableSrcElementCounting();
@@ -455,6 +528,8 @@
@see Queue()
@see TotalNumDstElementsTransferred()
+
+ @prototype
*/
IMPORT_C void DisableDstElementCounting();
@@ -475,6 +550,8 @@
@return The number of elements that have been transferred by this
transfer request at the source port.
+
+ @prototype
*/
IMPORT_C TUint32 TotalNumSrcElementsTransferred();
@@ -495,6 +572,8 @@
@return The number of elements that have been transferred by this
transfer request at the destination port.
+
+ @prototype
*/
IMPORT_C TUint32 TotalNumDstElementsTransferred();
@@ -512,9 +591,12 @@
@return The number of fragments (descriptors / pseudo descriptors) that
this transfer request has been split into.
- */
+
+ @released
+ */
IMPORT_C TInt FragmentCount();
+
/** Returns the number of source port fragments that this transfer request
has been split into.
@@ -527,7 +609,9 @@
@return The number of source port fragments (descriptors) that this
transfer request has been split into.
- */
+
+ @prototype
+ */
IMPORT_C TInt SrcFragmentCount();
@@ -543,17 +627,24 @@
@return The number of destination port fragments (descriptors) that
this transfer request has been split into.
- */
+
+ @prototype
+ */
IMPORT_C TInt DstFragmentCount();
private:
inline void OnDeque();
- TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs);
+ TInt CheckTransferConfig(const TDmaTransferConfig& aTarget, TUint aCount) const;
+ TInt CheckMemFlags(const TDmaTransferConfig& aTarget, TUint aCount) const;
+ TInt AdjustFragmentSize(TUint& aFragSize, TUint aElementSize, TUint aFrameSize);
+ TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs) const;
+ TUint GetMaxTransferlength(const TDmaTransferArgs& aTransferArgs, TUint aCount) const;
TInt Frag(TDmaTransferArgs& aTransferArgs);
TInt FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
TInt FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
TInt FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
TInt FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
+ TInt FragBalancedAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
TInt ExpandDesList(TInt aCount, TInt& aDesCount, SDmaDesHdr*& aFirstHdr,
SDmaDesHdr*& aLastHdr);
void FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr);
@@ -561,7 +652,7 @@
public:
// WARNING: The following attributes are accessed both in client and DFC
- // context and so accesses must be protected with the channel lock.
+ // thread context, so accesses must be protected with the channel lock.
TDmaChannel& iChannel; /**< The channel this request is bound to */
TCallback iCb; /**< Called on completion/failure (can be NULL) */
TAny* iCbArg; /**< Callback argument */
@@ -608,18 +699,15 @@
Mutexes are used internally to protect data structures accessed both by the
client thread and the DFC one. Therefore no fast mutex can be held when
calling a channel function.
-
- @publishedPartner
- @released
- */
+*/
class TDmaChannel
{
friend class DDmaRequest;
friend class TDmac;
friend class DmaChannelMgr;
+
public:
-
- /** Information passed by client when opening a channel */
+ /** Information passed by client when opening a channel. */
struct SCreateInfo
{
/** Default constructor. Initializes all fields with meaningful default
@@ -628,20 +716,23 @@
Must be inline (for now) because exporting it would break existing
custom DMA libs as their clients would need the export which would
be missing from the custom .def files.
+
+ @released
*/
SCreateInfo() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {};
- /** Identifier used by PSL to select channel to open */
- TUint32 iCookie;
- /** Number of descriptors this channel can use.
+ /** Identifier used by PSL to select channel to open.
- This number is not used in the upgraded version of the DMA
- framework and is kept there only for source compatibility. If the
- client is certain that it will only ever use that version, then the
- value passed here doesn't matter - the framework will ignore it.
+ @released
+ */
+ TUint32 iCookie;
+ /** Number of descriptors this channel can maximally use.
- @deprecated
- */
+ This value will not be used in the fully implemented new version of
+ the DMA framework. Until then it is still required.
+
+ @released
+ */
TInt iDesCount;
/** DFC queue used to service DMA interrupts.
@@ -649,15 +740,22 @@
priority to avoid a situation where a transfer completes while
being cancelled and another transfer is started before the DFC
thread gets a chance to run. This would lead to a stray DFC.
+
+ @released
*/
TDfcQue* iDfcQ;
- /** DFC priority */
+ /** DFC priority.
+
+ @released
+ */
TUint8 iDfcPriority;
/** Used by PSL to configure a channel priority (if possible).
The default is KDmaPriorityNone (the don't care value).
- @see TDmaPriority
+ @see TDmaPriority
+
+ @prototype
*/
TUint iPriority;
/** Request a dynamic DMA channel.
@@ -668,12 +766,14 @@
that case.
The default value is EFalse.
+
+ @prototype
*/
TBool iDynChannel;
};
public:
- /** Opens the DMA channel.
+ /** Opens the DMA channel.
Channel selection is done by the hardware-specific layer using a cookie
passed in via aInfo.
@@ -689,7 +789,9 @@
otherwise.
@return KErrNone or standard error code.
- */
+
+ @released
+ */
IMPORT_C static TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel);
@@ -701,6 +803,8 @@
released, and the pointer/reference to it mustn't therefore be accessed
any longer after the function has returned. The channel pointer should
be set to NULL by the client.
+
+ @released
*/
IMPORT_C void Close();
@@ -733,9 +837,12 @@
support channel linking, KErrArgument if this channel was already
linked to a different channel, KErrGeneral if a general error occurred
preventing a successful outcome.
- */
+
+ @prototype
+ */
IMPORT_C TInt LinkToChannel(TDmaChannel* aChannel);
+
/** Pauses an active transfer on this channel.
A paused channel transfer can be resumed by calling Resume() or it can
@@ -751,7 +858,9 @@
KErrCompletion if a transfer was already paused, KErrNotSupported if
the DMAC doesn't support channel transfer pausing/resuming, KErrGeneral
if a general error occurred preventing a successful outcome.
- */
+
+ @released
+ */
IMPORT_C TInt Pause();
@@ -767,17 +876,22 @@
Function can only be used if the DMAC supports this functionality.
@see SDmacCaps::iChannelPauseAndResume
+ @see SDmacCaps::iLinkedListPausedInterrupt
@return KErrNone if a paused transfer has been resumed successfully,
KErrCompletion if there was no paused transfer, KErrNotSupported if the
DMAC doesn't support channel transfer pausing/resuming, KErrGeneral if
a general error occurred preventing a successful outcome.
- */
+
+ @released
+ */
IMPORT_C TInt Resume();
/** Cancels the current request and all the pending ones.
- */
+
+ @released
+ */
IMPORT_C void CancelAll();
@@ -795,6 +909,8 @@
@return 0 if transfer length is not limited, the maximum transfer
length in bytes otherwise.
+
+ @released
*/
IMPORT_C TUint MaxTransferLength(TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo);
@@ -819,7 +935,9 @@
@return A value representing the alignment mask (e.g. 3 if buffer must
be 4-byte aligned)
- */
+
+ @released
+ */
IMPORT_C TUint AddressAlignMask(TUint aTargetFlags, TUint aElementSize,
TUint32 aPslInfo);
@@ -829,7 +947,9 @@
@return A reference to a structure containing the capabilities and
features of the DMA controller associated with this channel.
- */
+
+ @released
+ */
IMPORT_C const SDmacCaps& DmacCaps();
@@ -876,7 +996,9 @@
@see TDmaPILFlags::KDmaRequestCallbackFromIsr
@return KErrGeneral if there was an error, KErrNone otherwise.
- */
+
+ @released
+ */
IMPORT_C TInt IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid,
TUint32 aDstAddr=KPhysAddrInvalid,
TUint aTransferCount=0,
@@ -891,18 +1013,20 @@
NB: This API should not be used any longer.
After calling TDmaChannel::Open() successfully the channel is
- guaranteed to be open. Therefore there seems no good reason for this
- API to exist.
+ guaranteed to be open, hence there seems no good reason for this API to
+ exist.
@deprecated
- */
+ */
inline TBool IsOpened() const;
/** Tests whether the channel's request queue is currently empty.
@return ETrue if request queue is currently empty, EFalse otherwise.
- */
+
+ @released
+ */
inline TBool IsQueueEmpty() const;
@@ -910,7 +1034,9 @@
it is used for debug tracing by the PIL.
@return PSL-specific value which uniquely identifies this channel.
- */
+
+ @released
+ */
inline TUint32 PslId() const;
@@ -918,7 +1044,9 @@
transferred.
@param aFragmentCount The number of consecutive fragments to fail
- */
+
+ @released
+ */
IMPORT_C TInt FailNext(TInt aFragmentCount);
@@ -926,53 +1054,65 @@
more interrupts.
@param aInterruptCount The number of consecutive interrupts to miss
- */
+
+ @released
+ */
IMPORT_C TInt MissNextInterrupts(TInt aInterruptCount);
/** Function allowing platform-specific layer to extend channel API with
new channel-specific operations.
- @param aCmd Command identifier. Negative values are reserved for use by
- Nokia.
+ @param aCmd Command identifier.
@param aArg PSL-specific argument
@return KErrNotSupported if aCmd is not supported. PSL-specific value
otherwise.
- */
+
+ @released
+ */
IMPORT_C TInt Extension(TInt aCmd, TAny* aArg);
/** This is a function that allows the Platform Specific Layer (PSL) to
extend the DMA API with new channel-independent operations.
- @param aCmd Command identifier. Negative values are reserved for
- Symbian use.
+ @param aCmd Command identifier.
@param aArg PSL-specific.
@return KErrNotSupported if aCmd is not supported; a PSL specific value
otherwise.
+
+ @released
*/
IMPORT_C TInt StaticExtension(TInt aCmd, TAny* aArg);
- /** @deprecated
- @see DmacCaps()
- */
+ /** @see DmacCaps()
+
+ @deprecated
+ */
inline const TDmac* Controller() const;
- /** @deprecated
- @see MaxTransferLength()
- */
+ /** @see MaxTransferLength()
+
+ @deprecated
+ */
inline TInt MaxTransferSize(TUint aFlags, TUint32 aPslInfo);
- /** @deprecated
- @see AddressAlignMask()
- */
+ /** @see AddressAlignMask()
+
+ @deprecated
+ */
inline TUint MemAlignMask(TUint aFlags, TUint32 aPslInfo);
protected:
// Interface with state machines
+
+ /** Constructor.
+
+ @released
+ */
TDmaChannel();
/** Called by the PIL when adding a new request to the channel's queue.
@@ -980,11 +1120,15 @@
and begin transfer of aReq if possible.
@param aReq The request which has been added to the queue
+
+ @released
*/
virtual void DoQueue(const DDmaRequest& aReq);
/** Called by the PIL in response to a CancelAll call. It should update
the channel state appropriately.
+
+ @released
*/
virtual void DoCancelAll() = 0;
@@ -999,6 +1143,8 @@
@param aHdr The header for a descriptor, which must be unlinked
from its next descriptor (if there is one)
+
+ @released
*/
virtual void DoUnlink(SDmaDesHdr& aHdr);
@@ -1012,6 +1158,8 @@
@param aCurReq The current request.
@param aCompletedHdr Must be set by the implementation to the header
of the last transfer to complete.
+
+ @released
*/
virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
@@ -1032,6 +1180,8 @@
@param aDstCompletedHdr Must be set by the implementation to
the header of the last destination descriptor to complete.
+
+ @prototype
*/
virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
SDmaDesHdr*& aDstCompletedHdr);
@@ -1080,20 +1230,21 @@
NFastMutex iLock; // for data accessed in both client & DFC context
SDmaDesHdr* iCurHdr; // fragment being transferred or NULL
SDmaDesHdr** iNullPtr; // Pointer to NULL pointer following last fragment
- TDfc iDfc; // transfer completion/failure DFC
- TInt iMaxDesCount; // maximum number of allocable descriptors
- TInt iAvailDesCount; // available number of descriptors
+ TDfc iDfc; // transfer completion/failure DFC
+ TInt iMaxDesCount; // maximum number of allocable descriptors
+ TInt iAvailDesCount; // available number of descriptors
volatile TUint32 iIsrDfc; // Interface between ISR and DFC:
enum {KErrorFlagMask = 0x80000000}; // bit 31 - error flag
enum {KCancelFlagMask = 0x40000000}; // bit 30 - cancel flag
enum {KDfcCountMask = 0x3FFFFFFF}; // bits 0-29 - number of queued DFCs
- SDblQue iReqQ; // being/about to be transferred request queue
- TInt iReqCount; // number of requests attached to this channel
- TInt iQueuedRequests; // number of requests currently queued on this channel
+ SDblQue iReqQ; // being/about to be transferred request queue
+ TInt iReqCount; // number of requests attached to this channel
+ TInt iQueuedRequests; // number of requests currently queued on this channel
+
private:
TDmaCancelInfo* iCancelInfo; // ...
- TBool iRedoRequest; // client ISR callback wants a redo of request
- TBool iIsrCbRequest; // request on queue using ISR callback
+ TBool iRedoRequest; // client ISR callback wants a redo of request
+ TBool iIsrCbRequest; // request on queue using ISR callback
__DMA_DECLARE_INVARIANT
};
@@ -1103,54 +1254,24 @@
// INTERFACE WITH TEST HARNESS
//////////////////////////////////////////////////////////////////////////////
-/** Set of information used by test harness.
+/** Provides access to test information structure stored in the PSL.
- @publishedPartner
- @released
+ Must be implemented by the PSL (v1).
+
+ @deprecated
*/
-struct TDmaTestInfo
- {
- /** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/
- TUint iMaxTransferSize;
- /** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
- TUint iMemAlignMask;
- /** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/
- TUint32 iMemMemPslInfo;
- /** Number of test single-buffer channels */
- TInt iMaxSbChannels;
- /** Pointer to array containing single-buffer test channel ids */
- TUint32* iSbChannels;
- /** Number of test double-buffer channels */
- TInt iMaxDbChannels;
- /** Pointer to array containing double-buffer test channel ids */
- TUint32* iDbChannels;
- /** Number of test scatter-gather channels */
- TInt iMaxSgChannels;
- /** Pointer to array containing scatter-gather test channel ids */
- TUint32* iSgChannels;
- };
+IMPORT_C const TDmaTestInfo& DmaTestInfo();
/** Provides access to test information structure stored in the PSL.
- Must be implemented by the PSL.
+ Must be implemented by the PSL (v2).
- @publishedPartner
- @released
-*/
-IMPORT_C const TDmaTestInfo& DmaTestInfo();
-
-/** Provides access to test information structure stored in the PSL.
-
- Must be implemented by the PSL.
-
- @publishedPartner
@released
*/
IMPORT_C const TDmaV2TestInfo& DmaTestInfoV2();
-
//////////////////////////////////////////////////////////////////////////////