--- a/kernel/eka/include/drivers/dma_hai.h Tue May 11 17:28:22 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,896 +0,0 @@
-// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// include/drivers/dma_hai.h
-// DMA Framework - Symbian Hardware Abstraction Interface (SHAI).
-//
-//
-
-#ifndef __DMA_HAI_H__
-#define __DMA_HAI_H__
-
-
-#include <kernel/kern_priv.h>
-
-
-//////////////////////////////////////////////////////////////////////////////
-
-
-/** Interface used by PIL to open and close DMA channels.
-
- Must be implemented by the PSL.
-
- @publishedPartner
- @released
-*/
-class DmaChannelMgr
- {
-public:
- /** Opens a channel using a client-provided identifier.
-
- This function must be implemented by the PSL.
-
- @param aOpenId PSL-specific magic cookie passed by client. This could
- identify the channel exactly (by being just the channel number), or at
- least sufficiently (for example for use with a certain peripheral), or
- it may indicate some properties which the channel must possess. It may
- be set to zero always if all channels are equivalent.
-
- @param aDynChannel ETrue if the Open call is for a dynamic channel. A
- dynamic channel is not exclusively reserved for just one client, and
- further Open calls for more dynamic channels should succeed as long as
- certain resources (but not including the number of available physical
- channels) are not exceeded. Different transfer requests on this dynamic
- channel may be serviced using different actual channels.
-
- @param aPriority The desired channel priority as requested by the
- client. This may be an actual hardware priority or a
- platform-independent value. Not being able to satisfy the requested
- value is not a reason for the PSL to return NULL. This parameter may be
- ignored if aDynChannel is passed as ETrue. An overriding per-transfer
- priority may be requested by a client later via
- TDmaTransferArgs::iChannelPriority.
- @see SDmacCaps::iChannelPriorities
- @see TDmaPriority
-
- @return Pointer to channel if available, NULL otherwise. It should not
- be NULL if the Open call was for a dynamic channel unless a processing
- error occurred.
-
- @pre The PIL calls this function with a global fast mutex held to avoid
- race conditions.
-
- @post If a non-NULL pointer is returned, the object pointed to has its
- iController, iDmacCaps, iPslId, iDynChannel and iPriority members set
- to valid states.
-
- iController should point to the controller handling the
- channel.
-
- iDmacCaps should point to a SDmacCaps structure containing values
- relating to this particular channel.
-
- iPslId should contain a value uniquely identifying the channel - the
- PIL assigns this value later during request fragmentation to
- TDmaTransferArgs::iChannelCookie. It can be given any convenient value
- by the PSL (channel index, I/O port address, etc.).
-
- iDynChannel should be set to ETrue by the PSL if a dynamic channel was
- requested and has been opened.
-
- If applicable, iPriority should contain the actual hardware priority
- that has been configured or reserved. Otherwise it may be left at its
- default value TDmaPriority::KDmaPriorityNone.
- */
- static TDmaChannel* Open(TUint32 aOpenId, TBool aDynChannel, TUint aPriority);
-
- /** Performs platform-specific operations when a channel is closed.
-
- If aChannel was opened as a dynamic channel then this call is a sign
- that there is a client which does not intend to queue any further
- transfer requests via this channel.
-
- This function must be implemented by the PSL but the implementation can
- be a no-op.
-
- @param aChannel The channel to close
-
- @pre The PIL calls this function with a global fast mutex held to avoid
- race conditions.
- */
- static void Close(TDmaChannel* aChannel);
-
- /** Function allowing PSL to extend DMA API with new channel-independent
- operations.
-
- This function must be implemented by the PSL.
-
- @param aCmd Command identifier. Negative values are reserved for FW
- internal use.
-
- @param aArg PSL-specific
-
- @return KErrNotSupported if aCmd is not supported. PSL-specific value
- otherwise.
- */
- static TInt StaticExtension(TInt aCmd, TAny* aArg);
-
- /** Acquires the channel manager lock. Called by the PIL before opening and
- closing a channel.
- */
- static void Wait();
-
- /** Releases the channel manager lock. Called by the PIL after opening and
- closing a channel.
- */
- static void Signal();
-
-private:
- /** Declared, defined, and called by PSL's DECLARE_STANDARD_EXTENSION(). */
- friend TInt InitExtension();
-
- /** Must be called in the DMA DLL entry point. */
- static TInt Initialise();
-
- static NFastMutex Lock;
- };
-
-
-//////////////////////////////////////////////////////////////////////////////
-
-
-/** Abstract base class representing a DMA controller.
-
- The class has two purposes.
-
- First, it is a container for channels, descriptors and descriptor headers.
-
- Second, it exposes a set of virtual functions implemented by the PSL
- (platform-specific layer).
-
- These functions are the main interfaces between the PIL
- (platform-independent layer) and PSL.
-
- @publishedPartner
- @released
-*/
-class TDmac
- {
- friend class DmaChannelMgr;
-
-protected:
- /** Data required for creating a new instance */
- struct SCreateInfo
- {
- /** True if DMAC uses hardware descriptors (i.e. supports
- scatter/gather mode).
- */
- TBool iCapsHwDes;
- /** Initial maximum number of descriptors and headers (shared by all
- channels) to be allocated by the PIL. If at run time more
- descriptors are needed then they will be dynamically allocated and
- added to the available pool.
-
- The PSL may consider a number of factors when providing this
- initial value, such as the number of channels on this controller,
- the maximum transfer size per descriptor and also likely usage
- scenarios for the platform or device (number of drivers using DMA,
- their traffic patterns, simultaneity of operations, etc.).
- */
- TInt iDesCount;
- /** Size of individual descriptors. Use sizeof(TDmaTransferArgs) for
- single-buffer and double-buffer (i.e. non-s/g) controllers.
- */
- TInt iDesSize;
- /** Bitmask used when creating the memory chunk storing the descriptor
- pool. Used only for hardware descriptors.
-
- The access part must be EMapAttrSupRw. If the chunk is cached
- and/or buffered, the PSL must flush the data cache and/or drain the
- write buffer in InitHwDes() and related functions.
-
- The physical start address of the chunk will always be MMU page
- size aligned.
-
- @see TMappingAttributes
- */
- TUint iDesChunkAttribs;
- };
-
- /** Base class constructor. */
- TDmac(const SCreateInfo& aInfo);
-
- /** Base class 2nd-phase constructor. */
- TInt Create(const SCreateInfo& aInfo);
-
-public:
- /** Base class virtual destructor. */
- virtual ~TDmac();
-
- /** Allocates a number of headers (and hence also descriptors) from the
- header/descriptor pools. Called by the PIL but may also be used by the
- PSL.
- */
- TInt ReserveSetOfDes(TInt aCount);
-
- /** Returns previously allocated headers (and hence also descriptors) to
- the header/descriptor pools. Called by the PIL but may also be used by
- the PSL.
- */
- void ReleaseSetOfDes(TInt aCount);
-
- /** Called by the PIL during request fragmentation to fill a descriptor or
- pseudo descriptor with transfer arguments.
- */
- TInt InitDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
-
- /** Called by the PIL in TDmaChannel::IsrRedoRequest() if any of the
- latter's arguments is non-zero.
- */
- TInt UpdateDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
- TUint aTransferCount, TUint32 aPslRequestInfo);
-
- /** Returns a reference to the associated pseudo descriptor for a given
- descriptor header. For use by PIL and PSL.
- */
- inline TDmaTransferArgs& HdrToDes(const SDmaDesHdr& aHdr) const;
-
- /** Returns a reference to the associated hardware descriptor for a given
- descriptor header. For use by PIL and PSL.
- */
- inline TAny* HdrToHwDes(const SDmaDesHdr& aHdr) const;
-
- /** Returns the physical address of the hardware descriptor
- pointed to by aDes. For use by PIL and PSL.
- */
- inline TUint32 HwDesLinToPhys(TAny* aDes) const;
-
- /** Called by the PIL to acquire the controller lock which protects the
- header and descriptor pools.
- */
- inline void Wait();
-
- /** Called by the PIL to release the controller lock which protects the
- header and descriptor pools.
- */
- inline void Signal();
-
-public:
- /** Called by PIL when one fragment (single-buffer and double-buffer DMACs)
- or list of fragments (scatter/gather DMAC) is to be transferred.
-
- Called when initiating a new transfer and also, for double-buffer
- DMACs, for configuring the next fragment to transfer while the current
- one is ongoing.
-
- The function must be implemented by the PSL if
- SCreateInfo::iCaps::iAsymHwDescriptors is reported as false.
-
- @note This function may be called in thread or ISR context by the PIL
-
- @param aChannel The channel to use.
- @param aHdr Header associated with fragment to transfer.
- */
- virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
-
- /** Called by PIL when two lists of fragments (scatter/gather DMAC with
- asymmetrical linked-list capability) are to be transferred.
-
- Called when initiating a new transfer.
-
- The function must be implemented by the PSL if
- SDmaCaps::iAsymHwDescriptors is reported as true.
-
- @note This function may be called in thread or ISR context by the PIL
-
- @param aChannel The channel to use.
- @param aSrcHdr Header associated with descriptor to transfer on the
- source side.
- @param aDstHdr Header associated with descriptor to transfer on the
- destination side.
- */
- virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aSrcHdr,
- const SDmaDesHdr& aDstHdr);
-
- /** Called by PIL to stop a transfer on a given channel.
-
- The stopping must occur synchronously as the PIL assumes the channel
- is halted after calling this function. A channel stopped via this
- function is not intended to be resumed. Function must always be
- implemented by the PSL.
-
- @param aChannel The channel to stop
- @post The channel will be idle
- @post No interrupt will occur from this channel until a new
- request is queued.
- */
- virtual void StopTransfer(const TDmaChannel& aChannel) = 0;
-
- /** Called by PIL to pause (suspend) a transfer on a given channel.
-
- A paused channel transfer must be able to be resumed by calling
- ResumeTransfer().
-
- The function must be implemented by the PSL if
- SDmacCaps::iChannelPauseAndResume is reported as true.
-
- @return KErrNone if the transfer has been paused successfully,
- KErrCompletion if the transfer was already paused, KErrGeneral
- if a general error occurred preventing a successful outcome.
-
- @post No interrupt will occur from this channel until it is
- resumed.
- */
- virtual TInt PauseTransfer(const TDmaChannel& aChannel);
-
- /** Called by PIL to resume a paused (suspended) transfer on a given
- channel.
-
- Resume() can be called when the transfer is paused as a result of a
- previous call to PauseTransfer() or because the DMAC has encountered a
- Pause bit in a H/W descriptor.
-
- The function must be implemented by the PSL if
- SDmacCaps::iChannelPauseAndResume is reported as true.
-
- @return KErrNone if the transfer has been resumed successfully,
- KErrCompletion if there was no paused transfer, KErrGeneral
- if a general error occurred preventing a successful outcome.
- */
- virtual TInt ResumeTransfer(const TDmaChannel& aChannel);
-
- /** Called by PIL to check whether a DMA channel is idle.
-
- 'Idle' here means that the channel is ultimately stopped, for example
- because the transfer has finished, or an error was encountered, or it
- was manually stopped, but not because it was manually suspended (aka
- 'paused'), or it is waiting for a request line assertion to start the
- transfer.
-
- @param aChannel The channel to test
-
- @return ETrue if channel idle, EFalse if transferring.
- */
- virtual TBool IsIdle(const TDmaChannel& aChannel) = 0;
-
- /** Called by PIL to retrieve from the PSL the maximum transfer length
- based on the parameters passed.
-
- @param aChannel Channel to be used for the transfer
- @param aSrcFlags Bitmask characterising transfer source
- @see TDmaTransferArgs::iSrcConfig::iFlags
- @param aDstFlags Bitmask characterising transfer destination
- @see TDmaTransferArgs::iDstConfig::iFlags
- @param aPslInfo Cookie passed by client and used by the PSL
- @see TDmaTransferArgs::iPslRequestInfo
-
- @return 0 if transfer length is not limited, the maximum transfer
- length in bytes otherwise.
- */
- virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
- TUint aDstFlags, TUint32 aPslInfo) = 0;
-
- /** Called by PIL to retrieve from the PSL the memory alignment mask based
- on the parameters passed. Some DMA controllers impose alignment
- constraints on the base address of memory buffers. This mask is AND'ed
- against memory addresses computed during fragmentation.
-
- The PIL will call this function separately for source and destination.
-
- An assumption is that the PSL doesn't need to know if a call to this
- function is for the source or the destination side, i.e. both ports
- are, as far as the alignment is concerned, equivalent. All that matters
- are the values of the relevant configuration parameters.
-
- Another assumption is that the alignment requirement for a port on a
- DMAC with potentially different values for source and destination does
- not depend on the configuration of the respective other port.
-
- @param aChannel Channel used for the transfer
- @param aTargetFlags Bitmask characterising transfer source or
- destination
- @see TDmaTransferArgs::iSrcConfig::iFlags
- @see TDmaTransferArgs::iDstConfig::iFlags
- @param aElementSize Element size used for the transfer. May be zero if
- not known or 'don't care'.
- @param aPslInfo Cookie passed by client and used by the PSL
- @see TDmaTransferArgs::iPslRequestInfo
-
- @return A value representing the alignment mask (e.g. 3 if buffer must
- be 4-byte aligned)
- */
- virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aTargetFlags,
- TUint aElementSize, TUint32 aPslInfo) = 0;
-
- /** Called by PIL during fragmentation to initialise a hardware descriptor.
-
- The PSL must assume the descriptor is the last in the chain and so set
- the interrupt bit and set the next descriptor field to an end of chain
- marker.
-
- The function must be implemented by the PSL if and only if the DMAC
- supports hardware descriptors and SDmaCaps::iAsymHwDescriptors is
- reported as false.
-
- @param aHdr Header associated with the hardware descriptor to
- initialise
- @param aTransferArgs The transfer parameters for this descriptor
-
- @return KErrNone if the descriptor was successfully initialized,
- KErrArgument if any of the transfer arguments were detected to be
- invalid, KErrGeneral if a general error occurred preventing a
- successful outcome.
- */
- virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
-
- /** Called by PIL during fragmentation to initialise a hardware descriptor
- on the source side of an asymmetric linked list.
-
- The function must be implemented by the PSL if
- SDmaCaps::iAsymHwDescriptors is reported as true.
-
- @param aHdr Header associated with the hardware descriptor to
- initialise
- @param aTransferArgs The transfer parameters for this descriptor. Only
- the elements relating to the source side should be relevant to the
- implementation.
-
- @return KErrNone if the descriptor was successfully initialized,
- KErrArgument if any of the transfer arguments were detected to be
- invalid, KErrGeneral if a general error occurred preventing a
- successful outcome.
- */
- virtual TInt InitSrcHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
-
- /** Called by PIL during fragmentation to initialise a hardware descriptor
- on the destination side of an asymmetric linked list.
-
- The function must be implemented by the PSL if
- SDmaCaps::iAsymHwDescriptors is reported as true.
-
- @param aHdr Header associated with the hardware descriptor to
- initialise
- @param aTransferArgs The transfer parameters for this descriptor. Only
- the elements relating to the destination side should be relevant to the
- implementation.
-
- @return KErrNone if the descriptor was successfully initialized,
- KErrArgument if any of the transfer arguments were detected to be
- invalid, KErrGeneral if a general error occurred preventing a
- successful outcome.
- */
- virtual TInt InitDstHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
-
- /** Called by the PIL in ISR context to change specific fields in a
- hardware descriptor.
-
- The function must be implemented by the PSL if and only if the DMAC
- supports hardware descriptors and SDmaCaps::iAsymHwDescriptors is
- reported as false.
-
- @param aHdr Header associated with the hardware descriptor to be
- updated
- @param aSrcAddr @see TDmaTransferArgs::iSrcConfig::iAddr
- @param aDstAddr @see TDmaTransferArgs::iDstConfig::iAddr
- @param aTransferCount @see TDmaTransferArgs::iTransferCount
- @param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo
-
- Since Epoc::LinearToPhysical() cannot be called in ISR context the
- addresses passed into this function are always physical ones, i.e.
- TDmaTransferFlags::KDmaPhysAddr is implied.
-
- @return KErrNone if the descriptor was successfully modified,
- KErrArgument if any of the transfer arguments were detected to be
- invalid, KErrGeneral if a general error occurred preventing a
- successful outcome.
- */
- virtual TInt UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
- TUint aTransferCount, TUint32 aPslRequestInfo);
-
- /** Called by the PIL in ISR context to change specific fields in a
- hardware descriptor.
-
- The function must be implemented by the PSL if
- SDmaCaps::iAsymHwDescriptors is reported as true.
-
- @param aHdr Header associated with the hardware descriptor to be
- updated
- @param aSrcAddr @see TDmaTransferArgs::iSrcConfig::iAddr
- @param aTransferCount @see TDmaTransferArgs::iTransferCount
- @param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo
-
- Since Epoc::LinearToPhysical() cannot be called in ISR context the
- address passed into this function is always a physical ones, i.e.
- TDmaTransferFlags::KDmaPhysAddr is implied.
-
- @return KErrNone if the descriptor was successfully modified,
- KErrArgument if any of the transfer arguments were detected to be
- invalid, KErrGeneral if a general error occurred preventing a
- successful outcome.
- */
- virtual TInt UpdateSrcHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr,
- TUint aTransferCount, TUint32 aPslRequestInfo);
-
- /** Called by the PIL in ISR context to change specific fields in a
- hardware descriptor.
-
- The function must be implemented by the PSL if
- SDmaCaps::iAsymHwDescriptors is reported as true.
-
- @param aHdr Header associated with the hardware descriptor to be
- updated
- @param aDstAddr @see TDmaTransferArgs::iDstConfig::iAddr
- @param aTransferCount @see TDmaTransferArgs::iTransferCount
- @param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo
-
- Since Epoc::LinearToPhysical() cannot be called in ISR context the
- address passed into this function is always a physical ones, i.e.
- TDmaTransferFlags::KDmaPhysAddr is implied.
-
- @return KErrNone if the descriptor was successfully modified,
- KErrArgument if any of the transfer arguments were detected to be
- invalid, KErrGeneral if a general error occurred preventing a
- successful outcome.
- */
- virtual TInt UpdateDstHwDes(const SDmaDesHdr& aHdr, TUint32 aDstAddr,
- TUint aTransferCount, TUint32 aPslRequestInfo);
-
- /** Called by PIL, when fragmenting a request, to append a new hardware
- descriptor to an existing descriptor chain. May also be called by
- clients who wish to create their own descriptor chains.
-
- Must clear the interrupt bit of the descriptor associated with aHdr.
-
- The function must be implemented by the PSL if and only if the DMAC
- supports hardware descriptors.
-
- @param aHdr Header associated with last fragment in chain
- @param aNextHdr Header associated with fragment to append
- */
- virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
-
- /** Called by PIL when queuing a new request while the channel is running.
-
- Must append the first hardware descriptor of the new request to the
- last descriptor in the existing chain.
-
- The function must be implemented by the PSL if and only if the DMAC
- supports hardware descriptors.
-
- @param aChannel The channel where the transfer takes place
- @param aLastHdr Header associated with last hardware descriptor in
- chain
- @param aNewHdr Header associated with first hardware descriptor in new
- request
- */
- virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
- const SDmaDesHdr& aNewHdr);
-
- /** Called by PIL when queuing a new request while the channel is running.
-
- Must append the first hardware descriptor of the new request to the
- last descriptor in the existing chain.
-
- The function must be implemented by the PSL if
- SDmaCaps::iAsymHwDescriptors is reported as true.
-
- @param aChannel The channel where the transfer takes place
- @param aSrcLastHdr Header associated with the last descriptor in the
- source side chain
- @param aSrcNewHdr Header associated with the first source side
- descriptor of the new request
- @param aDstLastHdr Header associated with the last descriptor in the
- destination side chain
- @param aDstNewHdr Header associated with the first destination side
- descriptor of the new request
- */
- virtual void AppendHwDes(const TDmaChannel& aChannel,
- const SDmaDesHdr& aSrcLastHdr, const SDmaDesHdr& aSrcNewHdr,
- const SDmaDesHdr& aDstLastHdr, const SDmaDesHdr& aDstNewHdr);
-
- /** Called by PIL when completing or cancelling a request to cause the PSL
- to unlink the last item in the h/w descriptor chain from a subsequent
- chain that it was possibly linked to.
-
- The function must be implemented by the PSL if and only if the DMAC
- supports hardware descriptors.
-
- @param aChannel The channel where the request (and thus the descriptor)
- was queued
- @param aHdr Header associated with last h/w descriptor in
- completed / cancelled chain
- */
- virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
-
- /** Called by PIL when freeing descriptors back to the shared pool in
- FreeDesList(). The PSL inside ClearHwDes() can clear the contents of
- the h/w descriptor.
-
- This may be necessary if the PSL implementation uses the h/w descriptor
- as another header which in turn points to the actual DMA h/w descriptor
- (aka LLI).
-
- The function may be implemented by the PSL if the DMAC supports
- hardware descriptors.
-
- @param aHdr Header associated with the h/w descriptor being freed.
- */
- virtual void ClearHwDes(const SDmaDesHdr& aHdr);
-
- /** Called by PIL to logically link two physical channels.
-
- The function must be implemented by the PSL if the DMAC supports
- logical channel linking.
-
- @see SDmacCaps::iChannelLinking
-
- @param a1stChannel The channel which is to be linked to another channel
- @param a2ndChannel The channel the first one is to be linked to
-
- @return KErrNone if the two channels have been linked successfully,
- KErrCompletion if a1stChannel was already linked to a2ndChannel,
- KErrArgument if a1stChannel was already linked to a different channel,
- KErrGeneral if a general error occurred preventing a successful
- outcome. The default PIL implementation returns KErrNotSupported.
- */
- virtual TInt LinkChannels(TDmaChannel& a1stChannel, TDmaChannel& a2ndChannel);
-
- /** Called by PIL to logically unlink a physical channel from its linked-to
- successor.
-
- The function must be implemented by the PSL if the DMAC supports
- logical channel linking.
-
- @see SDmacCaps::iChannelLinking
-
- @param aChannel The channel which is to be unlinked from its successor
-
- @return KErrNone if the channel has been unlinked successfully,
- KErrCompletion if the channel was not linked to another channel,
- KErrGeneral if a general error occurred preventing a successful
- outcome. The default PIL implementation returns KErrNotSupported.
- */
- virtual TInt UnlinkChannel(TDmaChannel& aChannel);
-
- /** Called by a test harness to force an error when the next fragment is
- transferred.
-
- Must be implemented by the PSL only if possible.
-
- @param aChannel The channel where the error is to occur.
-
- @return KErrNone if implemented. The default PIL implementation
- returns KErrNotSupported.
- */
- virtual TInt FailNext(const TDmaChannel& aChannel);
-
- /** Called by a test harness to force the DMA controller to miss one or
- more interrupts.
-
- The function must be implemented by the PSL only if possible.
-
- @param aChannel The channel where the error is to occur
- @param aInterruptCount The number of interrupt to miss.
-
- @return KErrNone if implemented. The default PIL implementation
- returns KErrNotSupported.
- */
- virtual TInt MissNextInterrupts(const TDmaChannel& aChannel, TInt aInterruptCount);
-
- /** Function allowing platform-specific layer to extend channel API with
- new channel-specific operations.
-
- @see TDmaChannel::ChannelExtension
-
- @param aChannel Channel to operate on
- @param aCmd Command identifier. Negative values are reserved for use by
- Nokia.
- @param aArg PSL-specific argument
-
- @return KErrNotSupported if aCmd is not supported. PSL-specific value
- otherwise.
- */
- virtual TInt Extension(TDmaChannel& aChannel, TInt aCmd, TAny* aArg);
-
- /** Called by the PIL to query the number of elements that have so far been
- transferred by the hardware descriptor associated with aHdr at the
- source port.
-
- If SDmacCaps::iAsymHwDescriptors is true then the PIL will call this
- function only for source-side descriptors, and the PSL should fault the
- kernel if this is not the case.
-
- The function must be implemented (i.e. overridden) by the PSL if and
- only if the DMAC supports hardware descriptors.
-
- @param aHdr Descriptor header associated with the hardware descriptor
- to be queried
-
- @return The number of elements that have been transferred by the
- hardware descriptor associated with aHdr at the source port
- */
- virtual TUint32 HwDesNumSrcElementsTransferred(const SDmaDesHdr& aHdr);
-
- /** Called by the PIL to query the number of elements that have so far been
- transferred by the hardware descriptor associated with aHdr at the
- destination port.
-
- If SDmacCaps::iAsymHwDescriptors is true then the PIL will call this
- function only for destination-side descriptors, and the PSL should
- panic if this is not the case.
-
- The function must be implemented (i.e. overridden) by the PSL if and
- only if the DMAC supports hardware descriptors.
-
- @param aHdr Descriptor header associated with the hardware descriptor
- to be queried
-
- @return The number of elements that have been transferred by the
- hardware descriptor associated with aHdr at the destination port
- */
- virtual TUint32 HwDesNumDstElementsTransferred(const SDmaDesHdr& aHdr);
-
-protected:
- /** Called by the PSL in interrupt context upon a channel interrupt event.
-
- @param aChannel The channel the ISR relates to
- @param aEventMask Bitmask of one or more TDmaCallbackType values
- @param aIsComplete Set to ETrue if no error was encountered
- */
- static void HandleIsr(TDmaChannel& aChannel, TUint aEventMask, TBool aIsComplete);
-
-private:
- /** Called in Create() */
- TInt AllocDesPool(TUint aAttribs);
-
- /** Called in ~TDmac() */
- void FreeDesPool();
-
-private:
- NFastMutex iLock; // protect descriptor reservation and allocation
- const TInt iMaxDesCount; // initial number of descriptors and headers
- TInt iAvailDesCount; // current available number of descriptors and headers
- SDmaDesHdr* iHdrPool; // descriptor header dynamic array
-#ifndef __WINS__
- DPlatChunkHw* iHwDesChunk; // chunk for hardware descriptor pool
-#endif
- TAny* iDesPool; // hardware or pseudo descriptor dynamic array
- const TInt iDesSize; // descriptor size in bytes
-
-public:
- const TBool iCapsHwDes; /*< True if DMAC uses h/w descriptors */
- SDmaDesHdr* iFreeHdr; /*< head of unallocated descriptors linked list */
-
-#ifdef _DEBUG
- /** Tests whether aHdr points into the descriptor header array. */
- TBool IsValidHdr(const SDmaDesHdr* aHdr);
-#endif
- __DMA_DECLARE_INVARIANT
- };
-
-
-//////////////////////////////////////////////////////////////////////////////
-
-
-/** Single-buffer DMA channel.
-
- Can be instantiated or further derived by the PSL.
-
- @publishedPartner
- @released
-*/
-class TDmaSbChannel : public TDmaChannel
- {
-private:
- virtual void DoQueue(const DDmaRequest& aReq);
- virtual void DoCancelAll();
- virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
-private:
- enum {EIdle = 0, ETransferring} iState;
- };
-
-
-/** Double-buffer DMA channel.
-
- Can be instantiated or further derived by the PSL.
-
- @publishedPartner
- @released
-*/
-class TDmaDbChannel : public TDmaChannel
- {
-private:
- virtual void DoQueue(const DDmaRequest& aReq);
- virtual void DoCancelAll();
- virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
-private:
- enum {EIdle = 0, ETransferring, ETransferringLast} iState;
- };
-
-
-/** Scatter-gather DMA channel.
-
- Can be instantiated or further derived by the PSL.
-
- @publishedPartner
- @released
-*/
-class TDmaSgChannel : public TDmaChannel
- {
-private:
- virtual void DoQueue(const DDmaRequest& aReq);
- virtual void DoCancelAll();
- virtual void DoUnlink(SDmaDesHdr& aHdr);
- virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
-private:
- enum {EIdle = 0, ETransferring} iState;
- };
-
-
-/** Scatter-gather DMA channel with asymmetric linked-lists.
-
- Can be instantiated or further derived by the PSL.
-
- @publishedPartner
- @released
-*/
-class TDmaAsymSgChannel : public TDmaChannel
- {
-private:
- virtual void DoQueue(const DDmaRequest& aReq);
- virtual void DoCancelAll();
- virtual void DoUnlink(SDmaDesHdr& aHdr);
- virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
- SDmaDesHdr*& aDstCompletedHdr);
-private:
- SDmaDesHdr* iSrcCurHdr; // source fragment being transferred or NULL
- SDmaDesHdr** iSrcNullPtr; // Pointer to NULL pointer following last source fragment
- SDmaDesHdr* iDstCurHdr; // destination fragment being transferred or NULL
- SDmaDesHdr** iDstNullPtr; // Pointer to NULL pointer following last destination fragment
- enum {EIdle = 0, ETransferring} iState;
- };
-
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Trace macros intended for use by the DMA PSL
-#define DMA_PRINTF(MSG) __KTRACE_OPT(KDMA, Kern::Printf((MSG)))
-#define DMA_PRINTF1(MSG, ARG1) __KTRACE_OPT(KDMA, Kern::Printf((MSG), (ARG1)))
-#define DMA_PRINTF2(MSG, ARG1, ARG2) __KTRACE_OPT(KDMA, Kern::Printf((MSG), (ARG1), (ARG2)))
-
-#define DMA_PSL_MESG "DMA PSL: "
-
-// General PSL tracing
-#define DMA_PSL_TRACE(MSG) DMA_PRINTF(DMA_PSL_MESG MSG)
-#define DMA_PSL_TRACE1(MSG, ARG1) DMA_PRINTF1(DMA_PSL_MESG MSG, (ARG1))
-#define DMA_PSL_TRACE2(MSG, ARG1, ARG2) DMA_PRINTF2(DMA_PSL_MESG MSG, (ARG1), (ARG2))
-
-
-#define DMA_PSL_CHAN_MESG DMA_PSL_MESG "ChanId %d: "
-#define DMA_PSL_CHAN_ARGS(CHAN) ((CHAN).PslId())
-
-// For channel specific tracing (where CHAN is a TDmaChannel)
-#define DMA_PSL_CHAN_TRACE_STATIC(CHAN, MSG) DMA_PRINTF1(DMA_PSL_CHAN_MESG MSG, DMA_PSL_CHAN_ARGS(CHAN))
-#define DMA_PSL_CHAN_TRACE_STATIC1(CHAN, MSG, ARG1) DMA_PRINTF2(DMA_PSL_CHAN_MESG MSG, DMA_PSL_CHAN_ARGS(CHAN), (ARG1))
-
-// For channel specific tracing, for use within methods of TDmaChannel derived
-// class
-#define DMA_PSL_CHAN_TRACE(MSG) DMA_PSL_CHAN_TRACE_STATIC(*this, MSG)
-#define DMA_PSL_CHAN_TRACE1(MSG, ARG1) DMA_PSL_CHAN_TRACE_STATIC1(*this, MSG, (ARG1))
-
-
-
-#include <drivers/dma_hai.inl>
-
-
-#endif // #ifndef __DMA_HAI_H__