os/kernelhwsrv/kernel/eka/include/drivers/dma_v2.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/dma_v2.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1135 @@
     1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0""
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// include/drivers/dma_v2.h
    1.18 +// DMA Framework - Client API v2 definition.
    1.19 +//
    1.20 +// NB: DMA clients should never include this file directly, but only ever the
    1.21 +// generic header file <drivers/dma.h>.
    1.22 +//
    1.23 +
    1.24 +#ifndef __DMA_H__
    1.25 +#error "dma_v2.h must'n be included directly - use <drivers/dma.h> instead"
    1.26 +#endif	// #ifndef __DMA_H__
    1.27 +
    1.28 +#ifndef __DMA_V2_H__
    1.29 +#define __DMA_V2_H__
    1.30 +
    1.31 +
    1.32 +#include <kernel/kernel.h>
    1.33 +#include <drivers/dmadefs.h>
    1.34 +
    1.35 +
    1.36 +//////////////////////////////////////////////////////////////////////////////
    1.37 +// Debug Support - KDmaPanicCat is defined in each source file
    1.38 +
    1.39 +#define __DMA_ASSERTD(e) __ASSERT_DEBUG(e, Kern::Fault(KDmaPanicCat, __LINE__))
    1.40 +#define __DMA_ASSERTA(e) __ASSERT_ALWAYS(e, Kern::Fault(KDmaPanicCat, __LINE__))
    1.41 +#ifdef _DEBUG
    1.42 +#define __DMA_CANT_HAPPEN() Kern::Fault(KDmaPanicCat, __LINE__)
    1.43 +#define __DMA_DECLARE_INVARIANT public: void Invariant();
    1.44 +#define __DMA_INVARIANT() Invariant()
    1.45 +#else
    1.46 +#define __DMA_CANT_HAPPEN()
    1.47 +#define __DMA_DECLARE_INVARIANT
    1.48 +#define __DMA_INVARIANT()
    1.49 +#endif
    1.50 +
    1.51 +
    1.52 +//////////////////////////////////////////////////////////////////////////////
    1.53 +// INTERFACE EXPOSED TO DEVICE-DRIVERS
    1.54 +//////////////////////////////////////////////////////////////////////////////
    1.55 +
    1.56 +//////////////////////////////////////////////////////////////////////////////
    1.57 +
    1.58 +/** Bitmasks used for configuring a DMA request.
    1.59 +
    1.60 +	In general, specify KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest)
    1.61 +	if the source (resp. destination) is a memory buffer and clear
    1.62 +	KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest) if the source
    1.63 +	(resp. destination) is a peripheral.
    1.64 +
    1.65 +	If the location is given as a physical address (rather than a linear one)
    1.66 +	then also specify KDmaPhysAddrSrc and/or KDmaPhysAddrDest.
    1.67 +
    1.68 +	The EKA1 "Fill Mode" can be implemented by omitting KDmaIncSrc.
    1.69 +
    1.70 +	Some peripherals may require a post-increment address mode.
    1.71 +
    1.72 +	@see DDmaRequest::Fragment
    1.73 +	@publishedPartner
    1.74 +	@released
    1.75 +*/
    1.76 +enum TDmaRequestFlags
    1.77 +	{
    1.78 +	// Note: This enum is only required for backwards compatibility with the
    1.79 +	// old DMA framework, it can be removed once this is no longer needed.
    1.80 +
    1.81 +	/** Source is address of memory buffer */
    1.82 +	KDmaMemSrc       = 0x01,
    1.83 +	/** Destination is address of memory buffer */
    1.84 +	KDmaMemDest      = 0x02,
    1.85 +	/** Source address must be post-incremented during transfer */
    1.86 +	KDmaIncSrc       = 0x04,
    1.87 +	/** Destination address must be post-incremented during transfer */
    1.88 +	KDmaIncDest      = 0x08,
    1.89 +	/** Source address is a physical address (as opposed to a linear one) */
    1.90 +	KDmaPhysAddrSrc  = 0x10,
    1.91 +	/** Destination address is a physical address (as opposed to a linear one) */
    1.92 +	KDmaPhysAddrDest = 0x20,
    1.93 +	/** Request a different max transfer size (for instance for test purposes) */
    1.94 +	KDmaAltTransferLen = 0x40
    1.95 +	};
    1.96 +
    1.97 +
    1.98 +/** Each hardware or pseudo descriptor is associated with a header.  Headers
    1.99 +	are needed because hardware descriptors can not easily be extended to store
   1.100 +	additional information.
   1.101 +
   1.102 +	@publishedPartner
   1.103 +	@released
   1.104 +*/
   1.105 +struct SDmaDesHdr
   1.106 +	{
   1.107 +	SDmaDesHdr* iNext;
   1.108 +	};
   1.109 +
   1.110 +/** Pointer to signature of the new extended callback function.
   1.111 +
   1.112 +	TUint - bitmask of one or more TDmaCallbackType values
   1.113 +	TDmaResult - just that
   1.114 +	TAny* - was provided by client in DDmaRequest constructor
   1.115 +	SDmaDesHdr* - points to header (and thus descriptor) which caused a
   1.116 +	'descriptor completed' or 'descriptor paused' event.
   1.117 + */
   1.118 +typedef void (*TDmaCallback)(TUint, TDmaResult, TAny*, SDmaDesHdr*);
   1.119 +
   1.120 +class TDmaChannel;
   1.121 +
   1.122 +/** A DMA request is a list of fragments small enough to be transferred in one go
   1.123 +	by the DMAC.
   1.124 +
   1.125 +	In general, fragmentation is done in the framework by calling Fragment() but
   1.126 +	clients with special needs can allocate a blank descriptor list with
   1.127 +	ExpandDesList() and customise it to fit their needs.
   1.128 +
   1.129 +	Clients should not set attributes directly, but should use the various functions
   1.130 +	instead.
   1.131 +
   1.132 +	This class has not been designed to be called from several concurrent threads.
   1.133 +	Multithreaded clients must implement their own locking scheme (via DMutex).
   1.134 +
   1.135 +	Mutexes are used internally to protect data structures accessed both by the
   1.136 +	client thread and the DFC thread. Therefore no fast mutex can be held when
   1.137 +	calling a request function.
   1.138 +
   1.139 +	@publishedPartner
   1.140 +	@released
   1.141 + */
   1.142 +class DDmaRequest : public DBase
   1.143 +	{
   1.144 +	friend class TDmaChannel;
   1.145 +
   1.146 +public:
   1.147 +	/** The outcome of the transfer
   1.148 +
   1.149 +		@deprecated
   1.150 +		@see TDmaResult
   1.151 +	*/
   1.152 +	enum TResult {EBadResult=0, EOk, EError};
   1.153 +	/** The signature of the completion/failure callback function
   1.154 +
   1.155 +		@deprecated
   1.156 +		@see TDmaCallback
   1.157 +	*/
   1.158 +	typedef void (*TCallback)(TResult, TAny*);
   1.159 +
   1.160 +public:
   1.161 +    /** Constructor.
   1.162 +
   1.163 +		Create a new transfer request.
   1.164 +
   1.165 +		@param aChannel The channel this request is bound to.
   1.166 +		@param aCb Callback function called on transfer completion or failure
   1.167 +		(in channel DFC context).  Can be NULL.
   1.168 +		@param aCbArg   Argument passed to callback function.
   1.169 +		@param aMaxTransferSize Maximum fragment size.  If not specified, defaults to the maximum size
   1.170 +		supported by the DMA controller for the type of transfer that is later scheduled.
   1.171 +
   1.172 +		@deprecated
   1.173 +    */
   1.174 +	IMPORT_C DDmaRequest(TDmaChannel& aChannel, TCallback aCb=NULL, TAny* aCbArg=NULL,
   1.175 +						 TInt aMaxTransferSize=0);
   1.176 +
   1.177 +
   1.178 +	/** Constructor.
   1.179 +
   1.180 +		Create a new transfer request.
   1.181 +
   1.182 +		@param aChannel The channel this request is bound to.
   1.183 +		@param aDmaCb Callback function called on transfer completion or
   1.184 +		failure (in channel DFC or ISR context). Can be NULL.
   1.185 +		@param aCbArg Argument passed to callback function.
   1.186 +		@param aMaxTransferSize Maximum fragment size. If not specified,
   1.187 +		defaults to the maximum size supported by the DMA controller for the
   1.188 +		type of transfer that is later scheduled.
   1.189 +	*/
   1.190 +	IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb, TAny* aCbArg=NULL,
   1.191 +						 TUint aMaxTransferSize=0);
   1.192 +
   1.193 +
   1.194 +	/** Destructor.
   1.195 +
   1.196 +		Assume the request is not being transferred or pending.
   1.197 +    */
   1.198 +	IMPORT_C ~DDmaRequest();
   1.199 +
   1.200 +
   1.201 +	/** Split request into a list of fragments small enough to be fed to the
   1.202 +		DMAC.
   1.203 +
   1.204 +		The size of each fragment is smaller than or equal to the maximum
   1.205 +		transfer size supported by the DMAC. If the source and/or destination
   1.206 +		is memory, each fragment points to memory which is physically
   1.207 +		contiguous.
   1.208 +
   1.209 +		The kind of transfer to perform is specified via a set of flags used by
   1.210 +		a PIL and a magic cookie passed to the PSL. If the source
   1.211 +		(resp. destination) is a peripheral, aSrc (resp. aDest) is treated as a
   1.212 +		magic cookie by the PIL and passed straight to the PSL.
   1.213 +
   1.214 +		The request can be uninitialised or may have been fragmented
   1.215 +		previously. The previous configuration if any is lost whether or not
   1.216 +		the function succeeds.
   1.217 +
   1.218 +		@param aSrc Source memory buffer linear address or peripheral magic
   1.219 +		cookie.
   1.220 +		@param aDest Destination memory buffer linear address or peripheral
   1.221 +		magic cookie.
   1.222 +		@param aCount Number of bytes to transfer.
   1.223 +		@param aFlags Bitmask characterising the transfer.
   1.224 +		@param aPslInfo Hardware-specific information passed to PSL.
   1.225 +
   1.226 +		@return KErrNone if success. KErrArgument if aFlags and/or aPslInfo are
   1.227 +		invalid when finding the maximum transfer size. May also fail if
   1.228 +		running out of descriptors.
   1.229 +
   1.230 +		@pre The request is not being transferred or pending.
   1.231 +		@pre The various parameters must be valid. The PIL or PSL will fault the
   1.232 +		kernel if not.
   1.233 +
   1.234 +		@see TDmaRequestFlags
   1.235 +
   1.236 +		@deprecated
   1.237 +    */
   1.238 +	IMPORT_C TInt Fragment(TUint32 aSrc, TUint32 aDest, TInt aCount, TUint aFlags, TUint32 aPslInfo);
   1.239 +
   1.240 +
   1.241 +	/** New version of the DMA request fragment function, to be used with the
   1.242 +		TDmaTransferArgs structure.
   1.243 +	*/
   1.244 +	IMPORT_C TInt Fragment(const TDmaTransferArgs& aTransferArgs);
   1.245 +
   1.246 +
   1.247 +	/** Transfer asynchronously this request.
   1.248 +
   1.249 +		If this request's channel is idle, the request is transferred
   1.250 +		immediately. Otherwise, it is queued and transferred later.
   1.251 +
   1.252 +		The client is responsible for ensuring cache consistency before and/or
   1.253 +		after the transfer if necessary.
   1.254 +
   1.255 +		@return KErrNone if success, KErrGeneral otherwise.
   1.256 +    */
   1.257 +	IMPORT_C TInt Queue();
   1.258 +
   1.259 +
   1.260 +    /** Append new descriptor(s) to existing list.
   1.261 +
   1.262 +		Clients needing to build a custom descriptor list should call this
   1.263 +		function to allocate the list and access the resulting list through
   1.264 +		iFirstHdr and iLastHdr.
   1.265 +
   1.266 +		Clients should not change the value of iFirstHdr, iLastHdr and the
   1.267 +		iNext field of the descriptor headers to ensure descriptors can be
   1.268 +		deallocated. Clients are free to change hardware descriptors, including
   1.269 +		chaining, in whatever way suit them.
   1.270 +
   1.271 +		Assume the request is not being transferred or pending.
   1.272 +
   1.273 +		@param aCount Number of descriptors to append.
   1.274 +
   1.275 +		@return KErrNone or standard error code.
   1.276 +    */
   1.277 +	IMPORT_C TInt ExpandDesList(TInt aCount=1);
   1.278 +
   1.279 +
   1.280 +    /** Append new descriptor(s) to existing list. This function variant
   1.281 +		operates on the source port descriptor chain.
   1.282 +
   1.283 +		Works like ExpandDesList except that it uses the iSrcFirstHdr and
   1.284 +		iSrcLastHdr fields.
   1.285 +
   1.286 +		@see ExpandDesList
   1.287 +
   1.288 +		This function can only be used if SDmacCaps::iAsymHwDescriptors is
   1.289 +		true, otherwise it will just return KErrGeneral.
   1.290 +
   1.291 +		@param aCount Number of descriptors to append.
   1.292 +
   1.293 +		@return KErrNone or standard error code.
   1.294 +    */
   1.295 +	IMPORT_C TInt ExpandSrcDesList(TInt aCount=1);
   1.296 +
   1.297 +
   1.298 +    /** Append new descriptor(s) to existing list. This function variant
   1.299 +		operates on the destination port descriptor chain.
   1.300 +
   1.301 +		Works like ExpandDesList except that it uses the iDstFirstHdr and
   1.302 +		iDstLastHdr fields.
   1.303 +
   1.304 +		@see ExpandDesList
   1.305 +
   1.306 +		This function can only be used if SDmacCaps::iAsymHwDescriptors is
   1.307 +		true, otherwise it will just return KErrGeneral.
   1.308 +
   1.309 +		@param aCount Number of descriptors to append.
   1.310 +
   1.311 +		@return KErrNone or standard error code.
   1.312 +    */
   1.313 +	IMPORT_C TInt ExpandDstDesList(TInt aCount=1);
   1.314 +
   1.315 +
   1.316 +	/** Free resources associated with this request.
   1.317 +
   1.318 +		Assume the request is not being transferred or pending.
   1.319 +    */
   1.320 +	IMPORT_C void FreeDesList();
   1.321 +
   1.322 +
   1.323 +	/** Free resources associated with this request. This function variant
   1.324 +		operates on the source port descriptor chain.
   1.325 +
   1.326 +		@see FreeDesList
   1.327 +
   1.328 +		This function can only be used if SDmacCaps::iAsymHwDescriptors is
   1.329 +		true, otherwise it will do nothing.
   1.330 +    */
   1.331 +	IMPORT_C void FreeSrcDesList();
   1.332 +
   1.333 +
   1.334 +	/** Free resources associated with this request. This function variant
   1.335 +		operates on the destination port descriptor chain.
   1.336 +
   1.337 +		@see FreeDesList
   1.338 +
   1.339 +		This function can only be used if SDmacCaps::iAsymHwDescriptors is
   1.340 +		true, otherwise it will do nothing.
   1.341 +    */
   1.342 +	IMPORT_C void FreeDstDesList();
   1.343 +
   1.344 +
   1.345 +	/** Enables the functionality for counting the transferred source
   1.346 +		elements.
   1.347 +
   1.348 +		This function can be called at any time, but the enabled/disabled
   1.349 +		status is checked by the framework only at two points in time.
   1.350 +
   1.351 +		The first one is after a request has been queued, and if it is enabled
   1.352 +		then the counting will commence as soon as the transfer starts.
   1.353 +
   1.354 +		The second point is when Resume() is called for a paused transfer, and
   1.355 +		in this case the following applies. If counting was enabled when the
   1.356 +		transfer was paused and it is now disabled then the counting is stopped
   1.357 +		at that point and the count value frozen. If counting was disabled when
   1.358 +		the transfer was paused and it is now enabled then the counting will
   1.359 +		commence when the transfer resumes. (The starting value will depend on
   1.360 +		the argument of the enable function.) Otherwise nothing will change,
   1.361 +		i.e. counting will either continue normally (enabled/enabled) or
   1.362 +		neither stop nor continue (disabled/disabled).
   1.363 +
   1.364 +		Once a status has been set, it remains valid for the entire duration of
   1.365 +		the transfer (and beyond, if it is not changed again).
   1.366 +
   1.367 +		@param aResetElementCount If ETrue (the default) then the count
   1.368 +		variable will be reset to zero, otherwise it will retain its current
   1.369 +		value.
   1.370 +
   1.371 +		@see Queue()
   1.372 +		@see TotalNumSrcElementsTransferred()
   1.373 +	*/
   1.374 +	IMPORT_C void EnableSrcElementCounting(TBool aResetElementCount=ETrue);
   1.375 +
   1.376 +
   1.377 +	/** Enables the functionality for counting the transferred destination
   1.378 +		elements.
   1.379 +
   1.380 +		This function can be called at any time, but the enabled/disabled
   1.381 +		status is checked by the framework only at two points in time.
   1.382 +
   1.383 +		The first one is after a request has been queued, and if it is enabled
   1.384 +		then the counting will commence as soon as the transfer starts.
   1.385 +
   1.386 +		The second point is when Resume() is called for a paused transfer, and
   1.387 +		in this case the following applies. If counting was enabled when the
   1.388 +		transfer was paused and it is now disabled then the counting is stopped
   1.389 +		at that point and the count value frozen. If counting was disabled when
   1.390 +		the transfer was paused and it is now enabled then the counting will
   1.391 +		commence when the transfer resumes. (The starting value will depend on
   1.392 +		the argument of the enable function.) Otherwise nothing will change,
   1.393 +		i.e. counting will either continue normally (enabled/enabled) or
   1.394 +		neither stop nor continue (disabled/disabled).
   1.395 +
   1.396 +		Once a status has been set, it remains valid for the entire duration of
   1.397 +		the transfer (and beyond, if it is not changed again).
   1.398 +
   1.399 +		@param aResetElementCount If ETrue (the default) then the count
   1.400 +		variable will be reset to zero, otherwise it will retain its current
   1.401 +		value.
   1.402 +
   1.403 +		@see Queue()
   1.404 +		@see TotalNumDstElementsTransferred()
   1.405 +	*/
   1.406 +	IMPORT_C void EnableDstElementCounting(TBool aResetElementCount=ETrue);
   1.407 +
   1.408 +
   1.409 +	/** Disables the functionality for counting the transferred source
   1.410 +		elements.
   1.411 +
   1.412 +		This function can be called at any time, but the enabled/disabled
   1.413 +		status is checked by the framework only at two points in time.
   1.414 +
   1.415 +		The first one is after a request has been queued, and if it is enabled
   1.416 +		then the counting will commence as soon as the transfer starts.
   1.417 +
   1.418 +		The second point is when Resume() is called for a paused transfer, and
   1.419 +		in this case the following applies. If counting was enabled when the
   1.420 +		transfer was paused and it is now disabled then the counting is stopped
   1.421 +		at that point and the count value frozen. If counting was disabled when
   1.422 +		the transfer was paused and it is now enabled then the counting will
   1.423 +		commence when the transfer resumes. (The starting value will depend on
   1.424 +		the argument of the enable function.) Otherwise nothing will change,
   1.425 +		i.e. counting will either continue normally (enabled/enabled) or
   1.426 +		neither stop nor continue (disabled/disabled).
   1.427 +
   1.428 +		Once a status has been set, it remains valid for the entire duration of
   1.429 +		the transfer (and beyond, if it is not changed again).
   1.430 +
   1.431 +		@see Queue()
   1.432 +		@see TotalNumSrcElementsTransferred()
   1.433 +	*/
   1.434 +	IMPORT_C void DisableSrcElementCounting();
   1.435 +
   1.436 +
   1.437 +	/** Disables the functionality for counting the transferred destination
   1.438 +		elements.
   1.439 +
   1.440 +		This function can be called at any time, but the enabled/disabled
   1.441 +		status is checked by the framework only at two points in time.
   1.442 +
   1.443 +		The first one is after a request has been queued, and if it is enabled
   1.444 +		then the counting will commence as soon as the transfer starts.
   1.445 +
   1.446 +		The second point is when Resume() is called for a paused transfer, and
   1.447 +		in this case the following applies. If counting was enabled when the
   1.448 +		transfer was paused and it is now disabled then the counting is stopped
   1.449 +		at that point and the count value frozen. If counting was disabled when
   1.450 +		the transfer was paused and it is now enabled then the counting will
   1.451 +		commence when the transfer resumes. (The starting value will depend on
   1.452 +		the argument of the enable function.) Otherwise nothing will change,
   1.453 +		i.e. counting will either continue normally (enabled/enabled) or
   1.454 +		neither stop nor continue (disabled/disabled).
   1.455 +
   1.456 +		Once a status has been set, it remains valid for the entire duration of
   1.457 +		the transfer (and beyond, if it is not changed again).
   1.458 +
   1.459 +		@see Queue()
   1.460 +		@see TotalNumDstElementsTransferred()
   1.461 +	*/
   1.462 +	IMPORT_C void DisableDstElementCounting();
   1.463 +
   1.464 +
   1.465 +	/** Returns the number of elements that have been transferred by this
   1.466 +		transfer request at the source port.
   1.467 +
   1.468 +		To use this method, the counting functionality has to be explicitly
   1.469 +		enabled, either before the transfer request is queued or while it is
   1.470 +		paused.
   1.471 +
   1.472 +		@see EnableSrcElementCounting()
   1.473 +		@see DisableSrcElementCounting()
   1.474 +
   1.475 +		This function should only be called after the transfer has finished
   1.476 +		(completed with or without error, or because it was cancelled) or while
   1.477 +		it is paused. Otherwise it may just return 0.
   1.478 +
   1.479 +		@return The number of elements that have been transferred by this
   1.480 +		transfer request at the source port.
   1.481 +	*/
   1.482 +	IMPORT_C TUint32 TotalNumSrcElementsTransferred();
   1.483 +
   1.484 +
   1.485 +	/** Returns the number of elements that have been transferred by this
   1.486 +		transfer request at the destination port.
   1.487 +
   1.488 +		To use this method, the counting functionality has to be explicitly
   1.489 +		enabled, either before the transfer request is queued or while it is
   1.490 +		paused.
   1.491 +
   1.492 +		@see EnableDstElementCounting()
   1.493 +		@see DisableDstElementCounting()
   1.494 +
   1.495 +		This function should only be called after the transfer has finished
   1.496 +		(completed with or without error, or because it was cancelled) or while
   1.497 +		it is paused. Otherwise it may just return 0.
   1.498 +
   1.499 +		@return The number of elements that have been transferred by this
   1.500 +		transfer request at the destination port.
   1.501 +	*/
   1.502 +	IMPORT_C TUint32 TotalNumDstElementsTransferred();
   1.503 +
   1.504 +
   1.505 +	/** Returns the number of fragments that this transfer request has been
   1.506 +		split into.
   1.507 +
   1.508 +		This number will only be different from 0 once Fragment() has been
   1.509 +		called or after descriptors have been manually allocated by the client
   1.510 +		using ExpandDesList().
   1.511 +
   1.512 +		If SDmacCaps::iAsymHwDescriptors is true then this function will always
   1.513 +		return 0, and SrcFragmentCount() / DstFragmentCount() should be used
   1.514 +		instead.
   1.515 +
   1.516 +		@return The number of fragments (descriptors / pseudo descriptors) that
   1.517 +		this transfer request has been split into.
   1.518 +	 */
   1.519 +	IMPORT_C TInt FragmentCount();
   1.520 +
   1.521 +	/** Returns the number of source port fragments that this transfer request
   1.522 +		has been split into.
   1.523 +
   1.524 +		This number will only be different from 0 once Fragment() has been
   1.525 +		called or after descriptors have been manually allocated by the client
   1.526 +		using ExpandSrcDesList().
   1.527 +
   1.528 +		This function can only be used if SDmacCaps::iAsymHwDescriptors is
   1.529 +		true, otherwise it will always return 0.
   1.530 +
   1.531 +		@return The number of source port fragments (descriptors) that this
   1.532 +		transfer request has been split into.
   1.533 +	 */
   1.534 +	IMPORT_C TInt SrcFragmentCount();
   1.535 +
   1.536 +
   1.537 +	/** Returns the number of destination port fragments that this transfer
   1.538 +		request has been split into.
   1.539 +
   1.540 +		This number will only be different from 0 once Fragment() has been
   1.541 +		called or after descriptors have been manually allocated by the client
   1.542 +		using ExpandDstDesList().
   1.543 +
   1.544 +		This function can only be used if SDmacCaps::iAsymHwDescriptors is
   1.545 +		true, otherwise it will always return 0.
   1.546 +
   1.547 +		@return The number of destination port fragments (descriptors) that
   1.548 +		this transfer request has been split into.
   1.549 +	 */
   1.550 +	IMPORT_C TInt DstFragmentCount();
   1.551 +
   1.552 +private:
   1.553 +	inline void OnDeque();
   1.554 +	TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs);
   1.555 +	TInt Frag(TDmaTransferArgs& aTransferArgs);
   1.556 +	TInt FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
   1.557 +	TInt FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
   1.558 +	TInt FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
   1.559 +	TInt FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
   1.560 +	TInt ExpandDesList(TInt aCount, TInt& aDesCount, SDmaDesHdr*& aFirstHdr,
   1.561 +					   SDmaDesHdr*& aLastHdr);
   1.562 +	void FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr);
   1.563 +	TInt FragmentCount(const SDmaDesHdr* aHdr);
   1.564 +
   1.565 +public:
   1.566 +	// WARNING: The following attributes are accessed both in client and DFC
   1.567 +	// context and so accesses must be protected with the channel lock.
   1.568 +	TDmaChannel& iChannel;		/**< The channel this request is bound to */
   1.569 +	TCallback iCb;			 /**< Called on completion/failure (can be NULL) */
   1.570 +	TAny* iCbArg;			 /**< Callback argument */
   1.571 +	TDmaCallback iDmaCb;		// the new-style callback function
   1.572 +	TAny* iDmaCbArg;			// the new-style callback arg
   1.573 +	TBool iIsrCb;				// client wants callback in ISR context
   1.574 +	TInt iDesCount;			   /**< The number of fragments in list */
   1.575 +	SDmaDesHdr* iFirstHdr;	   /**< The first fragment in the list (or NULL) */
   1.576 +	SDmaDesHdr* iLastHdr;	   /**< The last fragment in the list (or NULL) */
   1.577 +	TInt iSrcDesCount;		   /**< The number of fragments in list */
   1.578 +	SDmaDesHdr* iSrcFirstHdr;  /**< The first fragment in the list (or NULL) */
   1.579 +	SDmaDesHdr* iSrcLastHdr;   /**< The last fragment in the list (or NULL) */
   1.580 +	TInt iDstDesCount;		   /**< The number of fragments in list */
   1.581 +	SDmaDesHdr* iDstFirstHdr;  /**< The first fragment in the list (or NULL) */
   1.582 +	SDmaDesHdr* iDstLastHdr;   /**< The last fragment in the list (or NULL) */
   1.583 +	SDblQueLink iLink;			/**< The link on channel queue of pending requests */
   1.584 +	TBool iQueued;				/**< Indicates whether request is pending or being transferred */
   1.585 +	TUint iMaxTransferSize;		/**< Defaults to DMA controller max. transfer size */
   1.586 +
   1.587 +	TUint32 iTotalNumSrcElementsTransferred;
   1.588 +	TUint32 iTotalNumDstElementsTransferred;
   1.589 +
   1.590 +	__DMA_DECLARE_INVARIANT
   1.591 +	};
   1.592 +
   1.593 +
   1.594 +//////////////////////////////////////////////////////////////////////////////
   1.595 +
   1.596 +class TDmac;
   1.597 +class DmaChannelMgr;
   1.598 +class TDmaCancelInfo;
   1.599 +
   1.600 +/** DMA channel base class.
   1.601 +
   1.602 +	Standard derived classes are provided for this channel (see
   1.603 +	TDmaSbChannel, TDmaDbChannel, TDmaSgChannel, and TDmaAsymSgChannel).
   1.604 +	The base-port implementor will only need to write their own derived
   1.605 +	class if one of the standard classes is unsuitable.
   1.606 +
   1.607 +	This class has not been designed to be called from several concurrent
   1.608 +	client threads. Multithreaded clients must implement their own locking
   1.609 +	scheme (via DMutex).
   1.610 +
   1.611 +	Mutexes are used internally to protect data structures accessed both by the
   1.612 +	client thread and the DFC one. Therefore no fast mutex can be held when
   1.613 +	calling a channel function.
   1.614 +
   1.615 +	@publishedPartner
   1.616 +	@released
   1.617 + */
   1.618 +class TDmaChannel
   1.619 +	{
   1.620 +	friend class DDmaRequest;
   1.621 +	friend class TDmac;
   1.622 +	friend class DmaChannelMgr;
   1.623 +public:
   1.624 +
   1.625 +	/** Information passed by client when opening a channel */
   1.626 +	struct SCreateInfo
   1.627 +		{
   1.628 +		/** Default constructor. Initializes all fields with meaningful default
   1.629 +			values.
   1.630 +
   1.631 +			Must be inline (for now) because exporting it would break existing
   1.632 +			custom DMA libs as their clients would need the export which would
   1.633 +			be missing from the custom .def files.
   1.634 +		*/
   1.635 +		SCreateInfo() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {};
   1.636 +
   1.637 +		/** Identifier used by PSL to select channel to open */
   1.638 +		TUint32 iCookie;
   1.639 +		/** Number of descriptors this channel can use.
   1.640 +
   1.641 +			This number is not used in the upgraded version of the DMA
   1.642 +			framework and is kept there only for source compatibility. If the
   1.643 +			client is certain that it will only ever use that version, then the
   1.644 +			value passed here doesn't matter - the framework will ignore it.
   1.645 +
   1.646 +			@deprecated
   1.647 +		 */
   1.648 +		TInt iDesCount;
   1.649 +		/** DFC queue used to service DMA interrupts.
   1.650 +
   1.651 +			The DFC thread priority must be higher than any client thread
   1.652 +			priority to avoid a situation where a transfer completes while
   1.653 +			being cancelled and another transfer is started before the DFC
   1.654 +			thread gets a chance to run. This would lead to a stray DFC.
   1.655 +		*/
   1.656 +		TDfcQue* iDfcQ;
   1.657 +		/** DFC priority */
   1.658 +		TUint8 iDfcPriority;
   1.659 +		/** Used by PSL to configure a channel priority (if possible).
   1.660 +
   1.661 +			The default is KDmaPriorityNone (the don't care value).
   1.662 +
   1.663 +		    @see TDmaPriority
   1.664 +		*/
   1.665 +		TUint iPriority;
   1.666 +		/** Request a dynamic DMA channel.
   1.667 +
   1.668 +			If this is set to ETrue then the Open call is for a 'dynamic' as
   1.669 +			opposed to a static and solely owned DMA channel. A number of
   1.670 +			properties of the opened TDmaChannel object will be different in
   1.671 +			that case.
   1.672 +
   1.673 +			The default value is EFalse.
   1.674 +		 */
   1.675 +		TBool iDynChannel;
   1.676 +		};
   1.677 +
   1.678 +public:
   1.679 +    /** Opens the DMA channel.
   1.680 +
   1.681 +		Channel selection is done by the hardware-specific layer using a cookie
   1.682 +		passed in via aInfo.
   1.683 +
   1.684 +		The client should not delete the returned pointer as the framework owns
   1.685 +		channel objects. However, the client should explicitly close the
   1.686 +		channel when finished with it.
   1.687 +
   1.688 +		@param aInfo Information passed by caller to select and configure
   1.689 +		channel.
   1.690 +
   1.691 +		@param aChannel Points to open channel on successful return. NULL
   1.692 +		otherwise.
   1.693 +
   1.694 +		@return KErrNone or standard error code.
   1.695 + 	*/
   1.696 +	IMPORT_C static TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel);
   1.697 +
   1.698 +
   1.699 +	/** Closes a previously opened DMA channel.
   1.700 +
   1.701 +		Assumes the channel is idle and all requests have been deleted.
   1.702 +
   1.703 +		The call will cause the resources associated with this channel to be
   1.704 +		released, and the pointer/reference to it mustn't therefore be accessed
   1.705 +		any longer after the function has returned. The channel pointer should
   1.706 +		be set to NULL by the client.
   1.707 + 	*/
   1.708 +	IMPORT_C void Close();
   1.709 +
   1.710 +
   1.711 +	/** Logically links this channel to the one specified as an argument, or,
   1.712 +		if the argument is NULL, unlinks this channel.
   1.713 +
   1.714 +		The effect of channel linking is that once a transfer on this channel
   1.715 +		has finished, instead of causing the associated client callback to be
   1.716 +		called, 'aChannel' will be enabled by hardware and a preconfigured
   1.717 +		transfer on that channel will start.
   1.718 +
   1.719 +		Note that conceptually 'linking' here always refers to the end of a
   1.720 +		channel transfer, not the beginning, i.e. a channel can only be linked
   1.721 +		once and always to a successor, never twice or to a predecessor. (This
   1.722 +		does not preclude the possibility that two channels are linked in a
   1.723 +		circular fashion.)
   1.724 +
   1.725 +		This function can only be used if the DMAC supports logical channel
   1.726 +		linking.
   1.727 +
   1.728 +		@see SDmacCaps::iChannelLinking
   1.729 +
   1.730 +		@param aChannel Points to the channel this one should be linked to, or
   1.731 +		NULL if this channel is to be unlinked from any other one.
   1.732 +
   1.733 +		@return KErrNone if the channel has been linked or unlinked
   1.734 +		successfully, KErrCompletion if this channel was already linked to
   1.735 +		aChannel or already unlinked, KErrNotSupported if the DMAC doesn't
   1.736 +		support channel linking, KErrArgument if this channel was already
   1.737 +		linked to a different channel, KErrGeneral if a general error occurred
   1.738 +		preventing a successful outcome.
   1.739 +	 */
   1.740 +	IMPORT_C TInt LinkToChannel(TDmaChannel* aChannel);
   1.741 +
   1.742 +	/** Pauses an active transfer on this channel.
   1.743 +
   1.744 +		A paused channel transfer can be resumed by calling Resume() or it can
   1.745 +		be stopped altogether by calling CancelAll().
   1.746 +
   1.747 +		@see TDmaChannel::Resume()
   1.748 +
   1.749 +		Function can only be used if the DMAC supports this functionality.
   1.750 +
   1.751 +		@see SDmacCaps::iChannelPauseAndResume
   1.752 +
   1.753 +		@return KErrNone if a transfer has been paused successfully,
   1.754 +		KErrCompletion if a transfer was already paused, KErrNotSupported if
   1.755 +		the DMAC doesn't support channel transfer pausing/resuming, KErrGeneral
   1.756 +		if a general error occurred preventing a successful outcome.
   1.757 +	 */
   1.758 +	IMPORT_C TInt Pause();
   1.759 +
   1.760 +
   1.761 +	/** Resumes a transfer on this channel that is paused.
   1.762 +
   1.763 +		Resume() can be called to resume channel operation when the transfer is
   1.764 +		paused as a result of a previous call to Pause() or because the DMAC
   1.765 +		has encountered a Pause bit in a H/W descriptor.
   1.766 +
   1.767 +		@see TDmaChannel::Pause()
   1.768 +		@see TDmaCallbackType::EDmaCallbackLinkedListPaused
   1.769 +
   1.770 +		Function can only be used if the DMAC supports this functionality.
   1.771 +
   1.772 +		@see SDmacCaps::iChannelPauseAndResume
   1.773 +
   1.774 +		@return KErrNone if a paused transfer has been resumed successfully,
   1.775 +		KErrCompletion if there was no paused transfer, KErrNotSupported if the
   1.776 +		DMAC doesn't support channel transfer pausing/resuming, KErrGeneral if
   1.777 +		a general error occurred preventing a successful outcome.
   1.778 +	 */
   1.779 +	IMPORT_C TInt Resume();
   1.780 +
   1.781 +
   1.782 +	/** Cancels the current request and all the pending ones.
   1.783 +	 */
   1.784 +	IMPORT_C void CancelAll();
   1.785 +
   1.786 +
   1.787 +	/** Returns the channel's maximum transfer length based on the passed
   1.788 +		arguments.
   1.789 +
   1.790 +		@param aSrcFlags Bitmask characterising transfer source
   1.791 +		@see TDmaTransferArgs::iSrcConfig::iFlags
   1.792 +
   1.793 +		@param aDstFlags Bitmask characterising transfer destination
   1.794 +		@see TDmaTransferArgs::iDstConfig::iFlags
   1.795 +
   1.796 +		@param aPslInfo Cookie passed to the PSL
   1.797 +		@see TDmaTransferArgs::iPslRequestInfo
   1.798 +
   1.799 +		@return 0 if transfer length is not limited, the maximum transfer
   1.800 +		length in bytes otherwise.
   1.801 + 	*/
   1.802 +	IMPORT_C TUint MaxTransferLength(TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo);
   1.803 +
   1.804 +
   1.805 +	/** Retrieves from the PSL the address / memory alignment mask based on the
   1.806 +		parameters passed. Some DMA controllers impose alignment constraints on
   1.807 +		the base address of memory buffers. This mask is AND'ed against memory
   1.808 +		addresses computed during fragmentation.
   1.809 +
   1.810 +		This function needs to be called separately for source and destination.
   1.811 +
   1.812 +		@param aTargetFlags Bitmask characterising transfer source or
   1.813 +		destination
   1.814 +		@see TDmaTransferArgs::iSrcConfig::iFlags
   1.815 +		@see TDmaTransferArgs::iDstConfig::iFlags
   1.816 +
   1.817 +		@param aElementSize Element size used for the transfer. Can be zero if
   1.818 +		not known or 'don't care'.
   1.819 +
   1.820 +		@param aPslInfo Cookie passed to the PSL
   1.821 +		@see TDmaTransferArgs::iPslRequestInfo
   1.822 +
   1.823 +		@return A value representing the alignment mask (e.g. 3 if buffer must
   1.824 +		be 4-byte aligned)
   1.825 +	 */
   1.826 +	IMPORT_C TUint AddressAlignMask(TUint aTargetFlags, TUint aElementSize,
   1.827 +									TUint32 aPslInfo);
   1.828 +
   1.829 +
   1.830 +	/** Returns a reference to a structure containing the capabilities and
   1.831 +		features of the DMA controller associated with this channel.
   1.832 +
   1.833 +		@return A reference to a structure containing the capabilities and
   1.834 +		features of the DMA controller associated with this channel.
   1.835 +	 */
   1.836 +	IMPORT_C const SDmacCaps& DmacCaps();
   1.837 +
   1.838 +
   1.839 +	/** Sets up once more the transfer request that has just completed, after
   1.840 +		optionally having adjusted the transfer parameters as specified.
   1.841 +
   1.842 +		This function is meant to be called exclusively from a client-supplied
   1.843 +		callback that is executed in ISR context, and only in response to a
   1.844 +		transfer completion notification.
   1.845 +
   1.846 +		If this call returns to the caller with KErrNone then the framework's
   1.847 +		ISR handler will subsequently not queue the channel DFC for this
   1.848 +		completed request.
   1.849 +
   1.850 +		The parameters specify which changes the framework should apply to the
   1.851 +		descriptors of the transfer request before rescheduling it. Arguments
   1.852 +		for which no change is required should be passed as their default
   1.853 +		values. The parameters correspond to those in the TDmaTransferArgs
   1.854 +		struct as follows.
   1.855 +
   1.856 +		@param aSrcAddr @see TDmaTransferArgs::iSrcConfig::iAddr
   1.857 +		@param aDstAddr @see TDmaTransferArgs::iDstConfig::iAddr
   1.858 +		@param aTransferCount @see TDmaTransferArgs::iTransferCount
   1.859 +		@param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo
   1.860 +		@param aIsrCb If set to ETrue (the default) then the callback of the
   1.861 +		rescheduled request will again be called in ISR context
   1.862 +
   1.863 +		Since Epoc::LinearToPhysical() cannot be called in ISR context the
   1.864 +		addresses passed into this function must be physical ones, i.e.
   1.865 +		TDmaTransferFlags::KDmaPhysAddr is implied.
   1.866 +
   1.867 +		If an address refers to a memory target then
   1.868 +		TDmaTransferFlags::KDmaMemIsContiguous is implied as well as no
   1.869 +		fragmentation is possible at this point.
   1.870 +
   1.871 +		@pre Must only be called from a 'transfer complete' client callback in
   1.872 +		ISR context.
   1.873 +
   1.874 +		@post Framework won't queue the channel DFC for the completed request
   1.875 +		in success case.
   1.876 +
   1.877 +		@see DDmaRequest::DDmaRequest(TDmaChannel&, TDmaCallback, TAny*, TUint)
   1.878 +		@see TDmaCallbackType::EDmaCallbackRequestCompletion
   1.879 +		@see TDmaPILFlags::KDmaRequestCallbackFromIsr
   1.880 +
   1.881 +		@return KErrGeneral if there was an error, KErrNone otherwise.
   1.882 +	 */
   1.883 +	IMPORT_C TInt IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid,
   1.884 +								 TUint32 aDstAddr=KPhysAddrInvalid,
   1.885 +								 TUint aTransferCount=0,
   1.886 +								 TUint32 aPslRequestInfo=0,
   1.887 +								 TBool aIsrCb=ETrue);
   1.888 +
   1.889 +
   1.890 +	/** Tests whether the channel is currently opened.
   1.891 +
   1.892 +		@return ETrue if channel is currently opened, EFalse otherwise.
   1.893 +
   1.894 +		NB: This API should not be used any longer.
   1.895 +
   1.896 +		After calling TDmaChannel::Open() successfully the channel is
   1.897 +		guaranteed to be open. Therefore there seems no good reason for this
   1.898 +		API to exist.
   1.899 +
   1.900 +		@deprecated
   1.901 +	 */
   1.902 +	inline TBool IsOpened() const;
   1.903 +
   1.904 +
   1.905 +	/** Tests whether the channel's request queue is currently empty.
   1.906 +
   1.907 +		@return ETrue if request queue is currently empty, EFalse otherwise.
   1.908 +	 */
   1.909 +	inline TBool IsQueueEmpty() const;
   1.910 +
   1.911 +
   1.912 +	/** Returns a PSL-specific value which uniquely identifies this channel -
   1.913 +		it is used for debug tracing by the PIL.
   1.914 +
   1.915 +		@return PSL-specific value which uniquely identifies this channel.
   1.916 +	 */
   1.917 +	inline TUint32 PslId() const;
   1.918 +
   1.919 +
   1.920 +	/** Called by a test harness to force an error when the next fragment is
   1.921 +		transferred.
   1.922 +
   1.923 +		@param aFragmentCount The number of consecutive fragments to fail
   1.924 +	 */
   1.925 +	IMPORT_C TInt FailNext(TInt aFragmentCount);
   1.926 +
   1.927 +
   1.928 +	/** Called by a test harness to force the DMA controller to miss one or
   1.929 +		more interrupts.
   1.930 +
   1.931 +		@param aInterruptCount The number of consecutive interrupts to miss
   1.932 +	 */
   1.933 +	IMPORT_C TInt MissNextInterrupts(TInt aInterruptCount);
   1.934 +
   1.935 +
   1.936 +	/** Function allowing platform-specific layer to extend channel API with
   1.937 +		new channel-specific operations.
   1.938 +
   1.939 +		@param aCmd Command identifier. Negative values are reserved for use by
   1.940 +		Nokia.
   1.941 +		@param aArg PSL-specific argument
   1.942 +
   1.943 +		@return KErrNotSupported if aCmd is not supported. PSL-specific value
   1.944 +		otherwise.
   1.945 +	 */
   1.946 +	IMPORT_C TInt Extension(TInt aCmd, TAny* aArg);
   1.947 +
   1.948 +
   1.949 +	/** This is a function that allows the Platform Specific Layer (PSL) to
   1.950 +		extend the DMA API with new channel-independent operations.
   1.951 +
   1.952 +		@param aCmd Command identifier. Negative values are reserved for
   1.953 +		Symbian use.
   1.954 +		@param aArg PSL-specific.
   1.955 +
   1.956 +		@return KErrNotSupported if aCmd is not supported; a PSL specific value
   1.957 +		otherwise.
   1.958 + 	*/
   1.959 +	IMPORT_C TInt StaticExtension(TInt aCmd, TAny* aArg);
   1.960 +
   1.961 +
   1.962 +	/** @deprecated
   1.963 +		@see DmacCaps()
   1.964 +	 */
   1.965 +	inline const TDmac* Controller() const;
   1.966 +
   1.967 +	/** @deprecated
   1.968 +		@see MaxTransferLength()
   1.969 +	 */
   1.970 +	inline TInt MaxTransferSize(TUint aFlags, TUint32 aPslInfo);
   1.971 +
   1.972 +	/** @deprecated
   1.973 +		@see AddressAlignMask()
   1.974 +	 */
   1.975 +	inline TUint MemAlignMask(TUint aFlags, TUint32 aPslInfo);
   1.976 +
   1.977 +protected:
   1.978 +	// Interface with state machines
   1.979 +	TDmaChannel();
   1.980 +
   1.981 +	/** Called by the PIL when adding a new request to the channel's queue.
   1.982 +		The implementation should update the channel's state as appropriate
   1.983 +		and begin transfer of aReq if possible.
   1.984 +
   1.985 +		@param aReq The request which has been added to the queue
   1.986 +	*/
   1.987 +	virtual void DoQueue(const DDmaRequest& aReq);
   1.988 +
   1.989 +	/** Called by the PIL in response to a CancelAll call. It should update
   1.990 +		the channel state appropriately.
   1.991 +	*/
   1.992 +	virtual void DoCancelAll() = 0;
   1.993 +
   1.994 +	/** This is called by the PIL when a DDmaRequest is removed from the
   1.995 +		channel's queue. In general the implementation simply needs to unlink
   1.996 +		the hardware descriptor corresponding to aHdr from the next.
   1.997 +
   1.998 +		Since the PIL links the hardware descriptor chains of adjacent queued
   1.999 +		requests (for speed) it is necessary to break the chain when a request
  1.1000 +		is completed so that the request may be requeued by the client without
  1.1001 +		having called DDmaRequest::Fragment again.
  1.1002 +
  1.1003 +		@param aHdr The header for a descriptor, which must be unlinked
  1.1004 +		from its next descriptor (if there is one)
  1.1005 +	*/
  1.1006 +	virtual void DoUnlink(SDmaDesHdr& aHdr);
  1.1007 +
  1.1008 +	/** Called by the PIL whenever a transfer associated with aCurReq is
  1.1009 +		done. The implementation must advance the channel's state and
  1.1010 +		may transfer the next header if necessary (the provided
  1.1011 +		scatter-gather channel does not do this). It must also report
  1.1012 +		back which header was associated with the last transfer to
  1.1013 +		complete.
  1.1014 +
  1.1015 +		@param aCurReq The current request.
  1.1016 +		@param aCompletedHdr Must be set by the implementation to the header
  1.1017 +		of the last transfer to complete.
  1.1018 +	*/
  1.1019 +	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
  1.1020 +
  1.1021 +	/** Called by the PIL whenever a transfer associated with aCurReq is
  1.1022 +		done. The implementation must advance the channel's state and
  1.1023 +		may start the transfer for the next headers if necessary (the
  1.1024 +		provided scatter-gather channels do not do this). If one
  1.1025 +		header has a successor but the other is the last in the chain it
  1.1026 +		is an error.
  1.1027 +
  1.1028 +		@note Must be implemented by PSL if channel uses asymmetric hardware
  1.1029 +		descriptors and is not derived from TDmaAsymSgChannel.
  1.1030 +
  1.1031 +		@param aCurReq The current request.
  1.1032 +
  1.1033 +		@param aSrcCompletedHdr Must be set by the implementation to
  1.1034 +		the header of the last source descriptor to complete.
  1.1035 +
  1.1036 +		@param aDstCompletedHdr Must be set by the implementation to
  1.1037 +		the header of the last destination descriptor to complete.
  1.1038 +	*/
  1.1039 +	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
  1.1040 +					   SDmaDesHdr*& aDstCompletedHdr);
  1.1041 +
  1.1042 +	virtual ~TDmaChannel();
  1.1043 +
  1.1044 +private:
  1.1045 +	static void Dfc(TAny*);
  1.1046 +	void DoDfc();
  1.1047 +	inline void Wait();
  1.1048 +	inline void Signal();
  1.1049 +	inline void Flash();
  1.1050 +	void ResetStateMachine();
  1.1051 +
  1.1052 +protected:
  1.1053 +	TDmac* iController;		 // DMAC this channel belongs to (NULL when closed)
  1.1054 +	const SDmacCaps* iDmacCaps;	// what is supported by DMAC on this channel
  1.1055 +	TUint32 iPslId;			 // unique identifier provided by PSL
  1.1056 +	TBool iDynChannel;		 // this is a dynamically allocated channel
  1.1057 +	TUint iPriority;		 // hardware priority of this channel
  1.1058 +	DMutex* iMutex;			 // for data accessed in both client & DFC context
  1.1059 +	SDmaDesHdr* iCurHdr;	 // fragment being transferred or NULL
  1.1060 +	SDmaDesHdr** iNullPtr;	 // Pointer to NULL pointer following last fragment
  1.1061 +	TDfc iDfc;				  // transfer completion/failure DFC
  1.1062 +	TInt iMaxDesCount;		  // maximum number of allocable descriptors
  1.1063 +	TInt iAvailDesCount;	  // available number of descriptors
  1.1064 +	volatile TUint32 iIsrDfc; // Interface between ISR and DFC:
  1.1065 +	enum {KErrorFlagMask = 0x80000000};	   // bit 31 - error flag
  1.1066 +	enum {KCancelFlagMask = 0x40000000};   // bit 30 - cancel flag
  1.1067 +	enum {KDfcCountMask = 0x3FFFFFFF};	   // bits 0-29 - number of queued DFCs
  1.1068 +	SDblQue iReqQ;				 // being/about to be transferred request queue
  1.1069 +	TInt iReqCount;				 // number of requests attached to this channel
  1.1070 +private:
  1.1071 +	TDmaCancelInfo* iCancelInfo; // ...
  1.1072 +	TBool iRedoRequest;			 // client ISR callback wants a redo of request
  1.1073 +	TBool iIsrCbRequest;		 // request on queue using ISR callback
  1.1074 +
  1.1075 +	__DMA_DECLARE_INVARIANT
  1.1076 +	};
  1.1077 +
  1.1078 +
  1.1079 +//////////////////////////////////////////////////////////////////////////////
  1.1080 +// INTERFACE WITH TEST HARNESS
  1.1081 +//////////////////////////////////////////////////////////////////////////////
  1.1082 +
  1.1083 +/** Set of information used by test harness.
  1.1084 +
  1.1085 +	@publishedPartner
  1.1086 +	@released
  1.1087 +*/
  1.1088 +struct TDmaTestInfo
  1.1089 +	{
  1.1090 +	/** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/
  1.1091 +	TUint iMaxTransferSize;
  1.1092 +	/** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
  1.1093 +	TUint iMemAlignMask;
  1.1094 +	/** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/
  1.1095 +	TUint32 iMemMemPslInfo;
  1.1096 +	/** Number of test single-buffer channels */
  1.1097 +	TInt iMaxSbChannels;
  1.1098 +	/** Pointer to array containing single-buffer test channel ids */
  1.1099 +	TUint32* iSbChannels;
  1.1100 +	/** Number of test double-buffer channels */
  1.1101 +	TInt iMaxDbChannels;
  1.1102 +	/** Pointer to array containing double-buffer test channel ids */
  1.1103 +	TUint32* iDbChannels;
  1.1104 +	/** Number of test scatter-gather channels */
  1.1105 +	TInt iMaxSgChannels;
  1.1106 +	/** Pointer to array containing scatter-gather test channel ids */
  1.1107 +	TUint32* iSgChannels;
  1.1108 +	};
  1.1109 +
  1.1110 +
  1.1111 +/** Provides access to test information structure stored in the PSL.
  1.1112 +
  1.1113 +	Must be implemented by the PSL.
  1.1114 +
  1.1115 +	@publishedPartner
  1.1116 +	@released
  1.1117 +*/
  1.1118 +IMPORT_C const TDmaTestInfo& DmaTestInfo();
  1.1119 +
  1.1120 +/** Provides access to test information structure stored in the PSL.
  1.1121 +
  1.1122 +	Must be implemented by the PSL.
  1.1123 +
  1.1124 +	@publishedPartner
  1.1125 +	@released
  1.1126 +*/
  1.1127 +IMPORT_C const TDmaV2TestInfo& DmaTestInfoV2();
  1.1128 +
  1.1129 +
  1.1130 +
  1.1131 +//////////////////////////////////////////////////////////////////////////////
  1.1132 +
  1.1133 +
  1.1134 +#include <drivers/dma_compat.inl>
  1.1135 +#include <drivers/dma_v2.inl>
  1.1136 +
  1.1137 +
  1.1138 +#endif	// #ifndef __DMA_V2_H__