diff -r b3a1d9898418 -r 95f71bcdcdb7 kernel/eka/include/drivers/dma_v2.h --- a/kernel/eka/include/drivers/dma_v2.h Fri May 14 17:13:29 2010 +0300 +++ b/kernel/eka/include/drivers/dma_v2.h Thu May 27 14:17:14 2010 +0300 @@ -18,6 +18,10 @@ // generic header file . // +/** @file + @publishedPartner +*/ + #ifndef __DMA_H__ #error "dma_v2.h must'n be included directly - use 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(); - //////////////////////////////////////////////////////////////////////////////