kernel/eka/include/drivers/dma_v2.h
changeset 45 329ab0095843
child 90 947f0dc9f7a8
equal deleted inserted replaced
44:36bfc973b146 45:329ab0095843
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0""
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // include/drivers/dma_v2.h
       
    15 // DMA Framework - Client API v2 definition.
       
    16 //
       
    17 // NB: DMA clients should never include this file directly, but only ever the
       
    18 // generic header file <drivers/dma.h>.
       
    19 //
       
    20 
       
    21 #ifndef __DMA_H__
       
    22 #error "dma_v2.h must'n be included directly - use <drivers/dma.h> instead"
       
    23 #endif	// #ifndef __DMA_H__
       
    24 
       
    25 #ifndef __DMA_V2_H__
       
    26 #define __DMA_V2_H__
       
    27 
       
    28 
       
    29 #include <kernel/kernel.h>
       
    30 #include <drivers/dmadefs.h>
       
    31 
       
    32 
       
    33 //////////////////////////////////////////////////////////////////////////////
       
    34 // Debug Support - KDmaPanicCat is defined in each source file
       
    35 
       
    36 #define __DMA_ASSERTD(e) __ASSERT_DEBUG(e, Kern::Fault(KDmaPanicCat, __LINE__))
       
    37 #define __DMA_ASSERTA(e) __ASSERT_ALWAYS(e, Kern::Fault(KDmaPanicCat, __LINE__))
       
    38 #ifdef _DEBUG
       
    39 #define __DMA_CANT_HAPPEN() Kern::Fault(KDmaPanicCat, __LINE__)
       
    40 #define __DMA_DECLARE_INVARIANT public: void Invariant();
       
    41 #define __DMA_INVARIANT() Invariant()
       
    42 #else
       
    43 #define __DMA_CANT_HAPPEN()
       
    44 #define __DMA_DECLARE_INVARIANT
       
    45 #define __DMA_INVARIANT()
       
    46 #endif
       
    47 
       
    48 
       
    49 //////////////////////////////////////////////////////////////////////////////
       
    50 // INTERFACE EXPOSED TO DEVICE-DRIVERS
       
    51 //////////////////////////////////////////////////////////////////////////////
       
    52 
       
    53 //////////////////////////////////////////////////////////////////////////////
       
    54 
       
    55 /** Bitmasks used for configuring a DMA request.
       
    56 
       
    57 	In general, specify KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest)
       
    58 	if the source (resp. destination) is a memory buffer and clear
       
    59 	KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest) if the source
       
    60 	(resp. destination) is a peripheral.
       
    61 
       
    62 	If the location is given as a physical address (rather than a linear one)
       
    63 	then also specify KDmaPhysAddrSrc and/or KDmaPhysAddrDest.
       
    64 
       
    65 	The EKA1 "Fill Mode" can be implemented by omitting KDmaIncSrc.
       
    66 
       
    67 	Some peripherals may require a post-increment address mode.
       
    68 
       
    69 	@see DDmaRequest::Fragment
       
    70 	@publishedPartner
       
    71 	@released
       
    72 */
       
    73 enum TDmaRequestFlags
       
    74 	{
       
    75 	// Note: This enum is only required for backwards compatibility with the
       
    76 	// old DMA framework, it can be removed once this is no longer needed.
       
    77 
       
    78 	/** Source is address of memory buffer */
       
    79 	KDmaMemSrc       = 0x01,
       
    80 	/** Destination is address of memory buffer */
       
    81 	KDmaMemDest      = 0x02,
       
    82 	/** Source address must be post-incremented during transfer */
       
    83 	KDmaIncSrc       = 0x04,
       
    84 	/** Destination address must be post-incremented during transfer */
       
    85 	KDmaIncDest      = 0x08,
       
    86 	/** Source address is a physical address (as opposed to a linear one) */
       
    87 	KDmaPhysAddrSrc  = 0x10,
       
    88 	/** Destination address is a physical address (as opposed to a linear one) */
       
    89 	KDmaPhysAddrDest = 0x20,
       
    90 	/** Request a different max transfer size (for instance for test purposes) */
       
    91 	KDmaAltTransferLen = 0x40
       
    92 	};
       
    93 
       
    94 
       
    95 /** Each hardware or pseudo descriptor is associated with a header.  Headers
       
    96 	are needed because hardware descriptors can not easily be extended to store
       
    97 	additional information.
       
    98 
       
    99 	@publishedPartner
       
   100 	@released
       
   101 */
       
   102 struct SDmaDesHdr
       
   103 	{
       
   104 	SDmaDesHdr* iNext;
       
   105 	};
       
   106 
       
   107 /** Pointer to signature of the new extended callback function.
       
   108 
       
   109 	TUint - bitmask of one or more TDmaCallbackType values
       
   110 	TDmaResult - just that
       
   111 	TAny* - was provided by client in DDmaRequest constructor
       
   112 	SDmaDesHdr* - points to header (and thus descriptor) which caused a
       
   113 	'descriptor completed' or 'descriptor paused' event.
       
   114  */
       
   115 typedef void (*TDmaCallback)(TUint, TDmaResult, TAny*, SDmaDesHdr*);
       
   116 
       
   117 class TDmaChannel;
       
   118 
       
   119 /** A DMA request is a list of fragments small enough to be transferred in one go
       
   120 	by the DMAC.
       
   121 
       
   122 	In general, fragmentation is done in the framework by calling Fragment() but
       
   123 	clients with special needs can allocate a blank descriptor list with
       
   124 	ExpandDesList() and customise it to fit their needs.
       
   125 
       
   126 	Clients should not set attributes directly, but should use the various functions
       
   127 	instead.
       
   128 
       
   129 	This class has not been designed to be called from several concurrent threads.
       
   130 	Multithreaded clients must implement their own locking scheme (via DMutex).
       
   131 
       
   132 	Mutexes are used internally to protect data structures accessed both by the
       
   133 	client thread and the DFC thread. Therefore no fast mutex can be held when
       
   134 	calling a request function.
       
   135 
       
   136 	@publishedPartner
       
   137 	@released
       
   138  */
       
   139 class DDmaRequest : public DBase
       
   140 	{
       
   141 	friend class TDmaChannel;
       
   142 
       
   143 public:
       
   144 	/** The outcome of the transfer
       
   145 
       
   146 		@deprecated
       
   147 		@see TDmaResult
       
   148 	*/
       
   149 	enum TResult {EBadResult=0, EOk, EError};
       
   150 	/** The signature of the completion/failure callback function
       
   151 
       
   152 		@deprecated
       
   153 		@see TDmaCallback
       
   154 	*/
       
   155 	typedef void (*TCallback)(TResult, TAny*);
       
   156 
       
   157 public:
       
   158     /** Constructor.
       
   159 
       
   160 		Create a new transfer request.
       
   161 
       
   162 		@param aChannel The channel this request is bound to.
       
   163 		@param aCb Callback function called on transfer completion or failure
       
   164 		(in channel DFC context).  Can be NULL.
       
   165 		@param aCbArg   Argument passed to callback function.
       
   166 		@param aMaxTransferSize Maximum fragment size.  If not specified, defaults to the maximum size
       
   167 		supported by the DMA controller for the type of transfer that is later scheduled.
       
   168 
       
   169 		@deprecated
       
   170     */
       
   171 	IMPORT_C DDmaRequest(TDmaChannel& aChannel, TCallback aCb=NULL, TAny* aCbArg=NULL,
       
   172 						 TInt aMaxTransferSize=0);
       
   173 
       
   174 
       
   175 	/** Constructor.
       
   176 
       
   177 		Create a new transfer request.
       
   178 
       
   179 		@param aChannel The channel this request is bound to.
       
   180 		@param aDmaCb Callback function called on transfer completion or
       
   181 		failure (in channel DFC or ISR context). Can be NULL.
       
   182 		@param aCbArg Argument passed to callback function.
       
   183 		@param aMaxTransferSize Maximum fragment size. If not specified,
       
   184 		defaults to the maximum size supported by the DMA controller for the
       
   185 		type of transfer that is later scheduled.
       
   186 	*/
       
   187 	IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb, TAny* aCbArg=NULL,
       
   188 						 TUint aMaxTransferSize=0);
       
   189 
       
   190 
       
   191 	/** Destructor.
       
   192 
       
   193 		Assume the request is not being transferred or pending.
       
   194     */
       
   195 	IMPORT_C ~DDmaRequest();
       
   196 
       
   197 
       
   198 	/** Split request into a list of fragments small enough to be fed to the
       
   199 		DMAC.
       
   200 
       
   201 		The size of each fragment is smaller than or equal to the maximum
       
   202 		transfer size supported by the DMAC. If the source and/or destination
       
   203 		is memory, each fragment points to memory which is physically
       
   204 		contiguous.
       
   205 
       
   206 		The kind of transfer to perform is specified via a set of flags used by
       
   207 		a PIL and a magic cookie passed to the PSL. If the source
       
   208 		(resp. destination) is a peripheral, aSrc (resp. aDest) is treated as a
       
   209 		magic cookie by the PIL and passed straight to the PSL.
       
   210 
       
   211 		The request can be uninitialised or may have been fragmented
       
   212 		previously. The previous configuration if any is lost whether or not
       
   213 		the function succeeds.
       
   214 
       
   215 		@param aSrc Source memory buffer linear address or peripheral magic
       
   216 		cookie.
       
   217 		@param aDest Destination memory buffer linear address or peripheral
       
   218 		magic cookie.
       
   219 		@param aCount Number of bytes to transfer.
       
   220 		@param aFlags Bitmask characterising the transfer.
       
   221 		@param aPslInfo Hardware-specific information passed to PSL.
       
   222 
       
   223 		@return KErrNone if success. KErrArgument if aFlags and/or aPslInfo are
       
   224 		invalid when finding the maximum transfer size. May also fail if
       
   225 		running out of descriptors.
       
   226 
       
   227 		@pre The request is not being transferred or pending.
       
   228 		@pre The various parameters must be valid. The PIL or PSL will fault the
       
   229 		kernel if not.
       
   230 
       
   231 		@see TDmaRequestFlags
       
   232 
       
   233 		@deprecated
       
   234     */
       
   235 	IMPORT_C TInt Fragment(TUint32 aSrc, TUint32 aDest, TInt aCount, TUint aFlags, TUint32 aPslInfo);
       
   236 
       
   237 
       
   238 	/** New version of the DMA request fragment function, to be used with the
       
   239 		TDmaTransferArgs structure.
       
   240 	*/
       
   241 	IMPORT_C TInt Fragment(const TDmaTransferArgs& aTransferArgs);
       
   242 
       
   243 
       
   244 	/** Transfer asynchronously this request.
       
   245 
       
   246 		If this request's channel is idle, the request is transferred
       
   247 		immediately. Otherwise, it is queued and transferred later.
       
   248 
       
   249 		The client is responsible for ensuring cache consistency before and/or
       
   250 		after the transfer if necessary.
       
   251 
       
   252 		@return KErrNone if success, KErrGeneral otherwise.
       
   253     */
       
   254 	IMPORT_C TInt Queue();
       
   255 
       
   256 
       
   257     /** Append new descriptor(s) to existing list.
       
   258 
       
   259 		Clients needing to build a custom descriptor list should call this
       
   260 		function to allocate the list and access the resulting list through
       
   261 		iFirstHdr and iLastHdr.
       
   262 
       
   263 		Clients should not change the value of iFirstHdr, iLastHdr and the
       
   264 		iNext field of the descriptor headers to ensure descriptors can be
       
   265 		deallocated. Clients are free to change hardware descriptors, including
       
   266 		chaining, in whatever way suit them.
       
   267 
       
   268 		Assume the request is not being transferred or pending.
       
   269 
       
   270 		@param aCount Number of descriptors to append.
       
   271 
       
   272 		@return KErrNone or standard error code.
       
   273     */
       
   274 	IMPORT_C TInt ExpandDesList(TInt aCount=1);
       
   275 
       
   276 
       
   277     /** Append new descriptor(s) to existing list. This function variant
       
   278 		operates on the source port descriptor chain.
       
   279 
       
   280 		Works like ExpandDesList except that it uses the iSrcFirstHdr and
       
   281 		iSrcLastHdr fields.
       
   282 
       
   283 		@see ExpandDesList
       
   284 
       
   285 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
       
   286 		true, otherwise it will just return KErrGeneral.
       
   287 
       
   288 		@param aCount Number of descriptors to append.
       
   289 
       
   290 		@return KErrNone or standard error code.
       
   291     */
       
   292 	IMPORT_C TInt ExpandSrcDesList(TInt aCount=1);
       
   293 
       
   294 
       
   295     /** Append new descriptor(s) to existing list. This function variant
       
   296 		operates on the destination port descriptor chain.
       
   297 
       
   298 		Works like ExpandDesList except that it uses the iDstFirstHdr and
       
   299 		iDstLastHdr fields.
       
   300 
       
   301 		@see ExpandDesList
       
   302 
       
   303 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
       
   304 		true, otherwise it will just return KErrGeneral.
       
   305 
       
   306 		@param aCount Number of descriptors to append.
       
   307 
       
   308 		@return KErrNone or standard error code.
       
   309     */
       
   310 	IMPORT_C TInt ExpandDstDesList(TInt aCount=1);
       
   311 
       
   312 
       
   313 	/** Free resources associated with this request.
       
   314 
       
   315 		Assume the request is not being transferred or pending.
       
   316     */
       
   317 	IMPORT_C void FreeDesList();
       
   318 
       
   319 
       
   320 	/** Free resources associated with this request. This function variant
       
   321 		operates on the source port descriptor chain.
       
   322 
       
   323 		@see FreeDesList
       
   324 
       
   325 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
       
   326 		true, otherwise it will do nothing.
       
   327     */
       
   328 	IMPORT_C void FreeSrcDesList();
       
   329 
       
   330 
       
   331 	/** Free resources associated with this request. This function variant
       
   332 		operates on the destination port descriptor chain.
       
   333 
       
   334 		@see FreeDesList
       
   335 
       
   336 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
       
   337 		true, otherwise it will do nothing.
       
   338     */
       
   339 	IMPORT_C void FreeDstDesList();
       
   340 
       
   341 
       
   342 	/** Enables the functionality for counting the transferred source
       
   343 		elements.
       
   344 
       
   345 		This function can be called at any time, but the enabled/disabled
       
   346 		status is checked by the framework only at two points in time.
       
   347 
       
   348 		The first one is after a request has been queued, and if it is enabled
       
   349 		then the counting will commence as soon as the transfer starts.
       
   350 
       
   351 		The second point is when Resume() is called for a paused transfer, and
       
   352 		in this case the following applies. If counting was enabled when the
       
   353 		transfer was paused and it is now disabled then the counting is stopped
       
   354 		at that point and the count value frozen. If counting was disabled when
       
   355 		the transfer was paused and it is now enabled then the counting will
       
   356 		commence when the transfer resumes. (The starting value will depend on
       
   357 		the argument of the enable function.) Otherwise nothing will change,
       
   358 		i.e. counting will either continue normally (enabled/enabled) or
       
   359 		neither stop nor continue (disabled/disabled).
       
   360 
       
   361 		Once a status has been set, it remains valid for the entire duration of
       
   362 		the transfer (and beyond, if it is not changed again).
       
   363 
       
   364 		@param aResetElementCount If ETrue (the default) then the count
       
   365 		variable will be reset to zero, otherwise it will retain its current
       
   366 		value.
       
   367 
       
   368 		@see Queue()
       
   369 		@see TotalNumSrcElementsTransferred()
       
   370 	*/
       
   371 	IMPORT_C void EnableSrcElementCounting(TBool aResetElementCount=ETrue);
       
   372 
       
   373 
       
   374 	/** Enables the functionality for counting the transferred destination
       
   375 		elements.
       
   376 
       
   377 		This function can be called at any time, but the enabled/disabled
       
   378 		status is checked by the framework only at two points in time.
       
   379 
       
   380 		The first one is after a request has been queued, and if it is enabled
       
   381 		then the counting will commence as soon as the transfer starts.
       
   382 
       
   383 		The second point is when Resume() is called for a paused transfer, and
       
   384 		in this case the following applies. If counting was enabled when the
       
   385 		transfer was paused and it is now disabled then the counting is stopped
       
   386 		at that point and the count value frozen. If counting was disabled when
       
   387 		the transfer was paused and it is now enabled then the counting will
       
   388 		commence when the transfer resumes. (The starting value will depend on
       
   389 		the argument of the enable function.) Otherwise nothing will change,
       
   390 		i.e. counting will either continue normally (enabled/enabled) or
       
   391 		neither stop nor continue (disabled/disabled).
       
   392 
       
   393 		Once a status has been set, it remains valid for the entire duration of
       
   394 		the transfer (and beyond, if it is not changed again).
       
   395 
       
   396 		@param aResetElementCount If ETrue (the default) then the count
       
   397 		variable will be reset to zero, otherwise it will retain its current
       
   398 		value.
       
   399 
       
   400 		@see Queue()
       
   401 		@see TotalNumDstElementsTransferred()
       
   402 	*/
       
   403 	IMPORT_C void EnableDstElementCounting(TBool aResetElementCount=ETrue);
       
   404 
       
   405 
       
   406 	/** Disables the functionality for counting the transferred source
       
   407 		elements.
       
   408 
       
   409 		This function can be called at any time, but the enabled/disabled
       
   410 		status is checked by the framework only at two points in time.
       
   411 
       
   412 		The first one is after a request has been queued, and if it is enabled
       
   413 		then the counting will commence as soon as the transfer starts.
       
   414 
       
   415 		The second point is when Resume() is called for a paused transfer, and
       
   416 		in this case the following applies. If counting was enabled when the
       
   417 		transfer was paused and it is now disabled then the counting is stopped
       
   418 		at that point and the count value frozen. If counting was disabled when
       
   419 		the transfer was paused and it is now enabled then the counting will
       
   420 		commence when the transfer resumes. (The starting value will depend on
       
   421 		the argument of the enable function.) Otherwise nothing will change,
       
   422 		i.e. counting will either continue normally (enabled/enabled) or
       
   423 		neither stop nor continue (disabled/disabled).
       
   424 
       
   425 		Once a status has been set, it remains valid for the entire duration of
       
   426 		the transfer (and beyond, if it is not changed again).
       
   427 
       
   428 		@see Queue()
       
   429 		@see TotalNumSrcElementsTransferred()
       
   430 	*/
       
   431 	IMPORT_C void DisableSrcElementCounting();
       
   432 
       
   433 
       
   434 	/** Disables the functionality for counting the transferred destination
       
   435 		elements.
       
   436 
       
   437 		This function can be called at any time, but the enabled/disabled
       
   438 		status is checked by the framework only at two points in time.
       
   439 
       
   440 		The first one is after a request has been queued, and if it is enabled
       
   441 		then the counting will commence as soon as the transfer starts.
       
   442 
       
   443 		The second point is when Resume() is called for a paused transfer, and
       
   444 		in this case the following applies. If counting was enabled when the
       
   445 		transfer was paused and it is now disabled then the counting is stopped
       
   446 		at that point and the count value frozen. If counting was disabled when
       
   447 		the transfer was paused and it is now enabled then the counting will
       
   448 		commence when the transfer resumes. (The starting value will depend on
       
   449 		the argument of the enable function.) Otherwise nothing will change,
       
   450 		i.e. counting will either continue normally (enabled/enabled) or
       
   451 		neither stop nor continue (disabled/disabled).
       
   452 
       
   453 		Once a status has been set, it remains valid for the entire duration of
       
   454 		the transfer (and beyond, if it is not changed again).
       
   455 
       
   456 		@see Queue()
       
   457 		@see TotalNumDstElementsTransferred()
       
   458 	*/
       
   459 	IMPORT_C void DisableDstElementCounting();
       
   460 
       
   461 
       
   462 	/** Returns the number of elements that have been transferred by this
       
   463 		transfer request at the source port.
       
   464 
       
   465 		To use this method, the counting functionality has to be explicitly
       
   466 		enabled, either before the transfer request is queued or while it is
       
   467 		paused.
       
   468 
       
   469 		@see EnableSrcElementCounting()
       
   470 		@see DisableSrcElementCounting()
       
   471 
       
   472 		This function should only be called after the transfer has finished
       
   473 		(completed with or without error, or because it was cancelled) or while
       
   474 		it is paused. Otherwise it may just return 0.
       
   475 
       
   476 		@return The number of elements that have been transferred by this
       
   477 		transfer request at the source port.
       
   478 	*/
       
   479 	IMPORT_C TUint32 TotalNumSrcElementsTransferred();
       
   480 
       
   481 
       
   482 	/** Returns the number of elements that have been transferred by this
       
   483 		transfer request at the destination port.
       
   484 
       
   485 		To use this method, the counting functionality has to be explicitly
       
   486 		enabled, either before the transfer request is queued or while it is
       
   487 		paused.
       
   488 
       
   489 		@see EnableDstElementCounting()
       
   490 		@see DisableDstElementCounting()
       
   491 
       
   492 		This function should only be called after the transfer has finished
       
   493 		(completed with or without error, or because it was cancelled) or while
       
   494 		it is paused. Otherwise it may just return 0.
       
   495 
       
   496 		@return The number of elements that have been transferred by this
       
   497 		transfer request at the destination port.
       
   498 	*/
       
   499 	IMPORT_C TUint32 TotalNumDstElementsTransferred();
       
   500 
       
   501 
       
   502 	/** Returns the number of fragments that this transfer request has been
       
   503 		split into.
       
   504 
       
   505 		This number will only be different from 0 once Fragment() has been
       
   506 		called or after descriptors have been manually allocated by the client
       
   507 		using ExpandDesList().
       
   508 
       
   509 		If SDmacCaps::iAsymHwDescriptors is true then this function will always
       
   510 		return 0, and SrcFragmentCount() / DstFragmentCount() should be used
       
   511 		instead.
       
   512 
       
   513 		@return The number of fragments (descriptors / pseudo descriptors) that
       
   514 		this transfer request has been split into.
       
   515 	 */
       
   516 	IMPORT_C TInt FragmentCount();
       
   517 
       
   518 	/** Returns the number of source port fragments that this transfer request
       
   519 		has been split into.
       
   520 
       
   521 		This number will only be different from 0 once Fragment() has been
       
   522 		called or after descriptors have been manually allocated by the client
       
   523 		using ExpandSrcDesList().
       
   524 
       
   525 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
       
   526 		true, otherwise it will always return 0.
       
   527 
       
   528 		@return The number of source port fragments (descriptors) that this
       
   529 		transfer request has been split into.
       
   530 	 */
       
   531 	IMPORT_C TInt SrcFragmentCount();
       
   532 
       
   533 
       
   534 	/** Returns the number of destination port fragments that this transfer
       
   535 		request has been split into.
       
   536 
       
   537 		This number will only be different from 0 once Fragment() has been
       
   538 		called or after descriptors have been manually allocated by the client
       
   539 		using ExpandDstDesList().
       
   540 
       
   541 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
       
   542 		true, otherwise it will always return 0.
       
   543 
       
   544 		@return The number of destination port fragments (descriptors) that
       
   545 		this transfer request has been split into.
       
   546 	 */
       
   547 	IMPORT_C TInt DstFragmentCount();
       
   548 
       
   549 private:
       
   550 	inline void OnDeque();
       
   551 	TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs);
       
   552 	TInt Frag(TDmaTransferArgs& aTransferArgs);
       
   553 	TInt FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
       
   554 	TInt FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
       
   555 	TInt FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
       
   556 	TInt FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
       
   557 	TInt ExpandDesList(TInt aCount, TInt& aDesCount, SDmaDesHdr*& aFirstHdr,
       
   558 					   SDmaDesHdr*& aLastHdr);
       
   559 	void FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr);
       
   560 	TInt FragmentCount(const SDmaDesHdr* aHdr);
       
   561 
       
   562 public:
       
   563 	// WARNING: The following attributes are accessed both in client and DFC
       
   564 	// context and so accesses must be protected with the channel lock.
       
   565 	TDmaChannel& iChannel;		/**< The channel this request is bound to */
       
   566 	TCallback iCb;			 /**< Called on completion/failure (can be NULL) */
       
   567 	TAny* iCbArg;			 /**< Callback argument */
       
   568 	TDmaCallback iDmaCb;		// the new-style callback function
       
   569 	TAny* iDmaCbArg;			// the new-style callback arg
       
   570 	TBool iIsrCb;				// client wants callback in ISR context
       
   571 	TInt iDesCount;			   /**< The number of fragments in list */
       
   572 	SDmaDesHdr* iFirstHdr;	   /**< The first fragment in the list (or NULL) */
       
   573 	SDmaDesHdr* iLastHdr;	   /**< The last fragment in the list (or NULL) */
       
   574 	TInt iSrcDesCount;		   /**< The number of fragments in list */
       
   575 	SDmaDesHdr* iSrcFirstHdr;  /**< The first fragment in the list (or NULL) */
       
   576 	SDmaDesHdr* iSrcLastHdr;   /**< The last fragment in the list (or NULL) */
       
   577 	TInt iDstDesCount;		   /**< The number of fragments in list */
       
   578 	SDmaDesHdr* iDstFirstHdr;  /**< The first fragment in the list (or NULL) */
       
   579 	SDmaDesHdr* iDstLastHdr;   /**< The last fragment in the list (or NULL) */
       
   580 	SDblQueLink iLink;			/**< The link on channel queue of pending requests */
       
   581 	TBool iQueued;				/**< Indicates whether request is pending or being transferred */
       
   582 	TUint iMaxTransferSize;		/**< Defaults to DMA controller max. transfer size */
       
   583 
       
   584 	TUint32 iTotalNumSrcElementsTransferred;
       
   585 	TUint32 iTotalNumDstElementsTransferred;
       
   586 
       
   587 	__DMA_DECLARE_INVARIANT
       
   588 	};
       
   589 
       
   590 
       
   591 //////////////////////////////////////////////////////////////////////////////
       
   592 
       
   593 class TDmac;
       
   594 class DmaChannelMgr;
       
   595 class TDmaCancelInfo;
       
   596 
       
   597 /** DMA channel base class.
       
   598 
       
   599 	Standard derived classes are provided for this channel (see
       
   600 	TDmaSbChannel, TDmaDbChannel, TDmaSgChannel, and TDmaAsymSgChannel).
       
   601 	The base-port implementor will only need to write their own derived
       
   602 	class if one of the standard classes is unsuitable.
       
   603 
       
   604 	This class has not been designed to be called from several concurrent
       
   605 	client threads. Multithreaded clients must implement their own locking
       
   606 	scheme (via DMutex).
       
   607 
       
   608 	Mutexes are used internally to protect data structures accessed both by the
       
   609 	client thread and the DFC one. Therefore no fast mutex can be held when
       
   610 	calling a channel function.
       
   611 
       
   612 	@publishedPartner
       
   613 	@released
       
   614  */
       
   615 class TDmaChannel
       
   616 	{
       
   617 	friend class DDmaRequest;
       
   618 	friend class TDmac;
       
   619 	friend class DmaChannelMgr;
       
   620 public:
       
   621 
       
   622 	/** Information passed by client when opening a channel */
       
   623 	struct SCreateInfo
       
   624 		{
       
   625 		/** Default constructor. Initializes all fields with meaningful default
       
   626 			values.
       
   627 
       
   628 			Must be inline (for now) because exporting it would break existing
       
   629 			custom DMA libs as their clients would need the export which would
       
   630 			be missing from the custom .def files.
       
   631 		*/
       
   632 		SCreateInfo() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {};
       
   633 
       
   634 		/** Identifier used by PSL to select channel to open */
       
   635 		TUint32 iCookie;
       
   636 		/** Number of descriptors this channel can use.
       
   637 
       
   638 			This number is not used in the upgraded version of the DMA
       
   639 			framework and is kept there only for source compatibility. If the
       
   640 			client is certain that it will only ever use that version, then the
       
   641 			value passed here doesn't matter - the framework will ignore it.
       
   642 
       
   643 			@deprecated
       
   644 		 */
       
   645 		TInt iDesCount;
       
   646 		/** DFC queue used to service DMA interrupts.
       
   647 
       
   648 			The DFC thread priority must be higher than any client thread
       
   649 			priority to avoid a situation where a transfer completes while
       
   650 			being cancelled and another transfer is started before the DFC
       
   651 			thread gets a chance to run. This would lead to a stray DFC.
       
   652 		*/
       
   653 		TDfcQue* iDfcQ;
       
   654 		/** DFC priority */
       
   655 		TUint8 iDfcPriority;
       
   656 		/** Used by PSL to configure a channel priority (if possible).
       
   657 
       
   658 			The default is KDmaPriorityNone (the don't care value).
       
   659 
       
   660 		    @see TDmaPriority
       
   661 		*/
       
   662 		TUint iPriority;
       
   663 		/** Request a dynamic DMA channel.
       
   664 
       
   665 			If this is set to ETrue then the Open call is for a 'dynamic' as
       
   666 			opposed to a static and solely owned DMA channel. A number of
       
   667 			properties of the opened TDmaChannel object will be different in
       
   668 			that case.
       
   669 
       
   670 			The default value is EFalse.
       
   671 		 */
       
   672 		TBool iDynChannel;
       
   673 		};
       
   674 
       
   675 public:
       
   676     /** Opens the DMA channel.
       
   677 
       
   678 		Channel selection is done by the hardware-specific layer using a cookie
       
   679 		passed in via aInfo.
       
   680 
       
   681 		The client should not delete the returned pointer as the framework owns
       
   682 		channel objects. However, the client should explicitly close the
       
   683 		channel when finished with it.
       
   684 
       
   685 		@param aInfo Information passed by caller to select and configure
       
   686 		channel.
       
   687 
       
   688 		@param aChannel Points to open channel on successful return. NULL
       
   689 		otherwise.
       
   690 
       
   691 		@return KErrNone or standard error code.
       
   692  	*/
       
   693 	IMPORT_C static TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel);
       
   694 
       
   695 
       
   696 	/** Closes a previously opened DMA channel.
       
   697 
       
   698 		Assumes the channel is idle and all requests have been deleted.
       
   699 
       
   700 		The call will cause the resources associated with this channel to be
       
   701 		released, and the pointer/reference to it mustn't therefore be accessed
       
   702 		any longer after the function has returned. The channel pointer should
       
   703 		be set to NULL by the client.
       
   704  	*/
       
   705 	IMPORT_C void Close();
       
   706 
       
   707 
       
   708 	/** Logically links this channel to the one specified as an argument, or,
       
   709 		if the argument is NULL, unlinks this channel.
       
   710 
       
   711 		The effect of channel linking is that once a transfer on this channel
       
   712 		has finished, instead of causing the associated client callback to be
       
   713 		called, 'aChannel' will be enabled by hardware and a preconfigured
       
   714 		transfer on that channel will start.
       
   715 
       
   716 		Note that conceptually 'linking' here always refers to the end of a
       
   717 		channel transfer, not the beginning, i.e. a channel can only be linked
       
   718 		once and always to a successor, never twice or to a predecessor. (This
       
   719 		does not preclude the possibility that two channels are linked in a
       
   720 		circular fashion.)
       
   721 
       
   722 		This function can only be used if the DMAC supports logical channel
       
   723 		linking.
       
   724 
       
   725 		@see SDmacCaps::iChannelLinking
       
   726 
       
   727 		@param aChannel Points to the channel this one should be linked to, or
       
   728 		NULL if this channel is to be unlinked from any other one.
       
   729 
       
   730 		@return KErrNone if the channel has been linked or unlinked
       
   731 		successfully, KErrCompletion if this channel was already linked to
       
   732 		aChannel or already unlinked, KErrNotSupported if the DMAC doesn't
       
   733 		support channel linking, KErrArgument if this channel was already
       
   734 		linked to a different channel, KErrGeneral if a general error occurred
       
   735 		preventing a successful outcome.
       
   736 	 */
       
   737 	IMPORT_C TInt LinkToChannel(TDmaChannel* aChannel);
       
   738 
       
   739 	/** Pauses an active transfer on this channel.
       
   740 
       
   741 		A paused channel transfer can be resumed by calling Resume() or it can
       
   742 		be stopped altogether by calling CancelAll().
       
   743 
       
   744 		@see TDmaChannel::Resume()
       
   745 
       
   746 		Function can only be used if the DMAC supports this functionality.
       
   747 
       
   748 		@see SDmacCaps::iChannelPauseAndResume
       
   749 
       
   750 		@return KErrNone if a transfer has been paused successfully,
       
   751 		KErrCompletion if a transfer was already paused, KErrNotSupported if
       
   752 		the DMAC doesn't support channel transfer pausing/resuming, KErrGeneral
       
   753 		if a general error occurred preventing a successful outcome.
       
   754 	 */
       
   755 	IMPORT_C TInt Pause();
       
   756 
       
   757 
       
   758 	/** Resumes a transfer on this channel that is paused.
       
   759 
       
   760 		Resume() can be called to resume channel operation when the transfer is
       
   761 		paused as a result of a previous call to Pause() or because the DMAC
       
   762 		has encountered a Pause bit in a H/W descriptor.
       
   763 
       
   764 		@see TDmaChannel::Pause()
       
   765 		@see TDmaCallbackType::EDmaCallbackLinkedListPaused
       
   766 
       
   767 		Function can only be used if the DMAC supports this functionality.
       
   768 
       
   769 		@see SDmacCaps::iChannelPauseAndResume
       
   770 
       
   771 		@return KErrNone if a paused transfer has been resumed successfully,
       
   772 		KErrCompletion if there was no paused transfer, KErrNotSupported if the
       
   773 		DMAC doesn't support channel transfer pausing/resuming, KErrGeneral if
       
   774 		a general error occurred preventing a successful outcome.
       
   775 	 */
       
   776 	IMPORT_C TInt Resume();
       
   777 
       
   778 
       
   779 	/** Cancels the current request and all the pending ones.
       
   780 	 */
       
   781 	IMPORT_C void CancelAll();
       
   782 
       
   783 
       
   784 	/** Returns the channel's maximum transfer length based on the passed
       
   785 		arguments.
       
   786 
       
   787 		@param aSrcFlags Bitmask characterising transfer source
       
   788 		@see TDmaTransferArgs::iSrcConfig::iFlags
       
   789 
       
   790 		@param aDstFlags Bitmask characterising transfer destination
       
   791 		@see TDmaTransferArgs::iDstConfig::iFlags
       
   792 
       
   793 		@param aPslInfo Cookie passed to the PSL
       
   794 		@see TDmaTransferArgs::iPslRequestInfo
       
   795 
       
   796 		@return 0 if transfer length is not limited, the maximum transfer
       
   797 		length in bytes otherwise.
       
   798  	*/
       
   799 	IMPORT_C TUint MaxTransferLength(TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo);
       
   800 
       
   801 
       
   802 	/** Retrieves from the PSL the address / memory alignment mask based on the
       
   803 		parameters passed. Some DMA controllers impose alignment constraints on
       
   804 		the base address of memory buffers. This mask is AND'ed against memory
       
   805 		addresses computed during fragmentation.
       
   806 
       
   807 		This function needs to be called separately for source and destination.
       
   808 
       
   809 		@param aTargetFlags Bitmask characterising transfer source or
       
   810 		destination
       
   811 		@see TDmaTransferArgs::iSrcConfig::iFlags
       
   812 		@see TDmaTransferArgs::iDstConfig::iFlags
       
   813 
       
   814 		@param aElementSize Element size used for the transfer. Can be zero if
       
   815 		not known or 'don't care'.
       
   816 
       
   817 		@param aPslInfo Cookie passed to the PSL
       
   818 		@see TDmaTransferArgs::iPslRequestInfo
       
   819 
       
   820 		@return A value representing the alignment mask (e.g. 3 if buffer must
       
   821 		be 4-byte aligned)
       
   822 	 */
       
   823 	IMPORT_C TUint AddressAlignMask(TUint aTargetFlags, TUint aElementSize,
       
   824 									TUint32 aPslInfo);
       
   825 
       
   826 
       
   827 	/** Returns a reference to a structure containing the capabilities and
       
   828 		features of the DMA controller associated with this channel.
       
   829 
       
   830 		@return A reference to a structure containing the capabilities and
       
   831 		features of the DMA controller associated with this channel.
       
   832 	 */
       
   833 	IMPORT_C const SDmacCaps& DmacCaps();
       
   834 
       
   835 
       
   836 	/** Sets up once more the transfer request that has just completed, after
       
   837 		optionally having adjusted the transfer parameters as specified.
       
   838 
       
   839 		This function is meant to be called exclusively from a client-supplied
       
   840 		callback that is executed in ISR context, and only in response to a
       
   841 		transfer completion notification.
       
   842 
       
   843 		If this call returns to the caller with KErrNone then the framework's
       
   844 		ISR handler will subsequently not queue the channel DFC for this
       
   845 		completed request.
       
   846 
       
   847 		The parameters specify which changes the framework should apply to the
       
   848 		descriptors of the transfer request before rescheduling it. Arguments
       
   849 		for which no change is required should be passed as their default
       
   850 		values. The parameters correspond to those in the TDmaTransferArgs
       
   851 		struct as follows.
       
   852 
       
   853 		@param aSrcAddr @see TDmaTransferArgs::iSrcConfig::iAddr
       
   854 		@param aDstAddr @see TDmaTransferArgs::iDstConfig::iAddr
       
   855 		@param aTransferCount @see TDmaTransferArgs::iTransferCount
       
   856 		@param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo
       
   857 		@param aIsrCb If set to ETrue (the default) then the callback of the
       
   858 		rescheduled request will again be called in ISR context
       
   859 
       
   860 		Since Epoc::LinearToPhysical() cannot be called in ISR context the
       
   861 		addresses passed into this function must be physical ones, i.e.
       
   862 		TDmaTransferFlags::KDmaPhysAddr is implied.
       
   863 
       
   864 		If an address refers to a memory target then
       
   865 		TDmaTransferFlags::KDmaMemIsContiguous is implied as well as no
       
   866 		fragmentation is possible at this point.
       
   867 
       
   868 		@pre Must only be called from a 'transfer complete' client callback in
       
   869 		ISR context.
       
   870 
       
   871 		@post Framework won't queue the channel DFC for the completed request
       
   872 		in success case.
       
   873 
       
   874 		@see DDmaRequest::DDmaRequest(TDmaChannel&, TDmaCallback, TAny*, TUint)
       
   875 		@see TDmaCallbackType::EDmaCallbackRequestCompletion
       
   876 		@see TDmaPILFlags::KDmaRequestCallbackFromIsr
       
   877 
       
   878 		@return KErrGeneral if there was an error, KErrNone otherwise.
       
   879 	 */
       
   880 	IMPORT_C TInt IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid,
       
   881 								 TUint32 aDstAddr=KPhysAddrInvalid,
       
   882 								 TUint aTransferCount=0,
       
   883 								 TUint32 aPslRequestInfo=0,
       
   884 								 TBool aIsrCb=ETrue);
       
   885 
       
   886 
       
   887 	/** Tests whether the channel is currently opened.
       
   888 
       
   889 		@return ETrue if channel is currently opened, EFalse otherwise.
       
   890 
       
   891 		NB: This API should not be used any longer.
       
   892 
       
   893 		After calling TDmaChannel::Open() successfully the channel is
       
   894 		guaranteed to be open. Therefore there seems no good reason for this
       
   895 		API to exist.
       
   896 
       
   897 		@deprecated
       
   898 	 */
       
   899 	inline TBool IsOpened() const;
       
   900 
       
   901 
       
   902 	/** Tests whether the channel's request queue is currently empty.
       
   903 
       
   904 		@return ETrue if request queue is currently empty, EFalse otherwise.
       
   905 	 */
       
   906 	inline TBool IsQueueEmpty() const;
       
   907 
       
   908 
       
   909 	/** Returns a PSL-specific value which uniquely identifies this channel -
       
   910 		it is used for debug tracing by the PIL.
       
   911 
       
   912 		@return PSL-specific value which uniquely identifies this channel.
       
   913 	 */
       
   914 	inline TUint32 PslId() const;
       
   915 
       
   916 
       
   917 	/** Called by a test harness to force an error when the next fragment is
       
   918 		transferred.
       
   919 
       
   920 		@param aFragmentCount The number of consecutive fragments to fail
       
   921 	 */
       
   922 	IMPORT_C TInt FailNext(TInt aFragmentCount);
       
   923 
       
   924 
       
   925 	/** Called by a test harness to force the DMA controller to miss one or
       
   926 		more interrupts.
       
   927 
       
   928 		@param aInterruptCount The number of consecutive interrupts to miss
       
   929 	 */
       
   930 	IMPORT_C TInt MissNextInterrupts(TInt aInterruptCount);
       
   931 
       
   932 
       
   933 	/** Function allowing platform-specific layer to extend channel API with
       
   934 		new channel-specific operations.
       
   935 
       
   936 		@param aCmd Command identifier. Negative values are reserved for use by
       
   937 		Nokia.
       
   938 		@param aArg PSL-specific argument
       
   939 
       
   940 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
       
   941 		otherwise.
       
   942 	 */
       
   943 	IMPORT_C TInt Extension(TInt aCmd, TAny* aArg);
       
   944 
       
   945 
       
   946 	/** This is a function that allows the Platform Specific Layer (PSL) to
       
   947 		extend the DMA API with new channel-independent operations.
       
   948 
       
   949 		@param aCmd Command identifier. Negative values are reserved for
       
   950 		Symbian use.
       
   951 		@param aArg PSL-specific.
       
   952 
       
   953 		@return KErrNotSupported if aCmd is not supported; a PSL specific value
       
   954 		otherwise.
       
   955  	*/
       
   956 	IMPORT_C TInt StaticExtension(TInt aCmd, TAny* aArg);
       
   957 
       
   958 
       
   959 	/** @deprecated
       
   960 		@see DmacCaps()
       
   961 	 */
       
   962 	inline const TDmac* Controller() const;
       
   963 
       
   964 	/** @deprecated
       
   965 		@see MaxTransferLength()
       
   966 	 */
       
   967 	inline TInt MaxTransferSize(TUint aFlags, TUint32 aPslInfo);
       
   968 
       
   969 	/** @deprecated
       
   970 		@see AddressAlignMask()
       
   971 	 */
       
   972 	inline TUint MemAlignMask(TUint aFlags, TUint32 aPslInfo);
       
   973 
       
   974 protected:
       
   975 	// Interface with state machines
       
   976 	TDmaChannel();
       
   977 
       
   978 	/** Called by the PIL when adding a new request to the channel's queue.
       
   979 		The implementation should update the channel's state as appropriate
       
   980 		and begin transfer of aReq if possible.
       
   981 
       
   982 		@param aReq The request which has been added to the queue
       
   983 	*/
       
   984 	virtual void DoQueue(const DDmaRequest& aReq);
       
   985 
       
   986 	/** Called by the PIL in response to a CancelAll call. It should update
       
   987 		the channel state appropriately.
       
   988 	*/
       
   989 	virtual void DoCancelAll() = 0;
       
   990 
       
   991 	/** This is called by the PIL when a DDmaRequest is removed from the
       
   992 		channel's queue. In general the implementation simply needs to unlink
       
   993 		the hardware descriptor corresponding to aHdr from the next.
       
   994 
       
   995 		Since the PIL links the hardware descriptor chains of adjacent queued
       
   996 		requests (for speed) it is necessary to break the chain when a request
       
   997 		is completed so that the request may be requeued by the client without
       
   998 		having called DDmaRequest::Fragment again.
       
   999 
       
  1000 		@param aHdr The header for a descriptor, which must be unlinked
       
  1001 		from its next descriptor (if there is one)
       
  1002 	*/
       
  1003 	virtual void DoUnlink(SDmaDesHdr& aHdr);
       
  1004 
       
  1005 	/** Called by the PIL whenever a transfer associated with aCurReq is
       
  1006 		done. The implementation must advance the channel's state and
       
  1007 		may transfer the next header if necessary (the provided
       
  1008 		scatter-gather channel does not do this). It must also report
       
  1009 		back which header was associated with the last transfer to
       
  1010 		complete.
       
  1011 
       
  1012 		@param aCurReq The current request.
       
  1013 		@param aCompletedHdr Must be set by the implementation to the header
       
  1014 		of the last transfer to complete.
       
  1015 	*/
       
  1016 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
       
  1017 
       
  1018 	/** Called by the PIL whenever a transfer associated with aCurReq is
       
  1019 		done. The implementation must advance the channel's state and
       
  1020 		may start the transfer for the next headers if necessary (the
       
  1021 		provided scatter-gather channels do not do this). If one
       
  1022 		header has a successor but the other is the last in the chain it
       
  1023 		is an error.
       
  1024 
       
  1025 		@note Must be implemented by PSL if channel uses asymmetric hardware
       
  1026 		descriptors and is not derived from TDmaAsymSgChannel.
       
  1027 
       
  1028 		@param aCurReq The current request.
       
  1029 
       
  1030 		@param aSrcCompletedHdr Must be set by the implementation to
       
  1031 		the header of the last source descriptor to complete.
       
  1032 
       
  1033 		@param aDstCompletedHdr Must be set by the implementation to
       
  1034 		the header of the last destination descriptor to complete.
       
  1035 	*/
       
  1036 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
       
  1037 					   SDmaDesHdr*& aDstCompletedHdr);
       
  1038 
       
  1039 	virtual ~TDmaChannel();
       
  1040 
       
  1041 private:
       
  1042 	static void Dfc(TAny*);
       
  1043 	void DoDfc();
       
  1044 	inline void Wait();
       
  1045 	inline void Signal();
       
  1046 	inline void Flash();
       
  1047 	void ResetStateMachine();
       
  1048 
       
  1049 protected:
       
  1050 	TDmac* iController;		 // DMAC this channel belongs to (NULL when closed)
       
  1051 	const SDmacCaps* iDmacCaps;	// what is supported by DMAC on this channel
       
  1052 	TUint32 iPslId;			 // unique identifier provided by PSL
       
  1053 	TBool iDynChannel;		 // this is a dynamically allocated channel
       
  1054 	TUint iPriority;		 // hardware priority of this channel
       
  1055 	DMutex* iMutex;			 // for data accessed in both client & DFC context
       
  1056 	SDmaDesHdr* iCurHdr;	 // fragment being transferred or NULL
       
  1057 	SDmaDesHdr** iNullPtr;	 // Pointer to NULL pointer following last fragment
       
  1058 	TDfc iDfc;				  // transfer completion/failure DFC
       
  1059 	TInt iMaxDesCount;		  // maximum number of allocable descriptors
       
  1060 	TInt iAvailDesCount;	  // available number of descriptors
       
  1061 	volatile TUint32 iIsrDfc; // Interface between ISR and DFC:
       
  1062 	enum {KErrorFlagMask = 0x80000000};	   // bit 31 - error flag
       
  1063 	enum {KCancelFlagMask = 0x40000000};   // bit 30 - cancel flag
       
  1064 	enum {KDfcCountMask = 0x3FFFFFFF};	   // bits 0-29 - number of queued DFCs
       
  1065 	SDblQue iReqQ;				 // being/about to be transferred request queue
       
  1066 	TInt iReqCount;				 // number of requests attached to this channel
       
  1067 private:
       
  1068 	TDmaCancelInfo* iCancelInfo; // ...
       
  1069 	TBool iRedoRequest;			 // client ISR callback wants a redo of request
       
  1070 	TBool iIsrCbRequest;		 // request on queue using ISR callback
       
  1071 
       
  1072 	__DMA_DECLARE_INVARIANT
       
  1073 	};
       
  1074 
       
  1075 
       
  1076 //////////////////////////////////////////////////////////////////////////////
       
  1077 // INTERFACE WITH TEST HARNESS
       
  1078 //////////////////////////////////////////////////////////////////////////////
       
  1079 
       
  1080 /** Set of information used by test harness.
       
  1081 
       
  1082 	@publishedPartner
       
  1083 	@released
       
  1084 */
       
  1085 struct TDmaTestInfo
       
  1086 	{
       
  1087 	/** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/
       
  1088 	TUint iMaxTransferSize;
       
  1089 	/** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
       
  1090 	TUint iMemAlignMask;
       
  1091 	/** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/
       
  1092 	TUint32 iMemMemPslInfo;
       
  1093 	/** Number of test single-buffer channels */
       
  1094 	TInt iMaxSbChannels;
       
  1095 	/** Pointer to array containing single-buffer test channel ids */
       
  1096 	TUint32* iSbChannels;
       
  1097 	/** Number of test double-buffer channels */
       
  1098 	TInt iMaxDbChannels;
       
  1099 	/** Pointer to array containing double-buffer test channel ids */
       
  1100 	TUint32* iDbChannels;
       
  1101 	/** Number of test scatter-gather channels */
       
  1102 	TInt iMaxSgChannels;
       
  1103 	/** Pointer to array containing scatter-gather test channel ids */
       
  1104 	TUint32* iSgChannels;
       
  1105 	};
       
  1106 
       
  1107 
       
  1108 /** Provides access to test information structure stored in the PSL.
       
  1109 
       
  1110 	Must be implemented by the PSL.
       
  1111 
       
  1112 	@publishedPartner
       
  1113 	@released
       
  1114 */
       
  1115 IMPORT_C const TDmaTestInfo& DmaTestInfo();
       
  1116 
       
  1117 /** Provides access to test information structure stored in the PSL.
       
  1118 
       
  1119 	Must be implemented by the PSL.
       
  1120 
       
  1121 	@publishedPartner
       
  1122 	@released
       
  1123 */
       
  1124 IMPORT_C const TDmaV2TestInfo& DmaTestInfoV2();
       
  1125 
       
  1126 
       
  1127 
       
  1128 //////////////////////////////////////////////////////////////////////////////
       
  1129 
       
  1130 
       
  1131 #include <drivers/dma_compat.inl>
       
  1132 #include <drivers/dma_v2.inl>
       
  1133 
       
  1134 
       
  1135 #endif	// #ifndef __DMA_V2_H__