kernel/eka/include/drivers/dma_hai.h
changeset 139 95f71bcdcdb7
parent 90 947f0dc9f7a8
child 199 189ece41fa29
child 247 d8d70de2bd36
equal deleted inserted replaced
109:b3a1d9898418 139:95f71bcdcdb7
    14 // include/drivers/dma_hai.h
    14 // include/drivers/dma_hai.h
    15 // DMA Framework - Symbian Hardware Abstraction Interface (SHAI).
    15 // DMA Framework - Symbian Hardware Abstraction Interface (SHAI).
    16 //
    16 //
    17 //
    17 //
    18 
    18 
    19 #ifndef __DMA_HAI_H__
    19 /** @file
    20 #define __DMA_HAI_H__
       
    21 
       
    22 
       
    23 #include <kernel/kern_priv.h>
       
    24 
       
    25 
       
    26 //////////////////////////////////////////////////////////////////////////////
       
    27 
       
    28 
       
    29 /** Interface used by PIL to open and close DMA channels.
       
    30 
       
    31 	Must be implemented by the PSL.
       
    32 
       
    33 	@publishedPartner
    20 	@publishedPartner
    34 	@released
    21 	@released
    35 */
    22 */
       
    23 
       
    24 #ifndef __DMA_HAI_H__
       
    25 #define __DMA_HAI_H__
       
    26 
       
    27 
       
    28 #include <kernel/kern_priv.h>
       
    29 
       
    30 
       
    31 //////////////////////////////////////////////////////////////////////////////
       
    32 
       
    33 
       
    34 /** Interface used by PIL to open and close DMA channels.
       
    35 
       
    36 	Must be implemented by the PSL.
       
    37 */
    36 class DmaChannelMgr
    38 class DmaChannelMgr
    37 	{
    39 	{
       
    40 
    38 public:
    41 public:
    39 	/** Opens a channel using a client-provided identifier.
    42 	/** Opens a channel using a client-provided identifier.
    40 
    43 
    41 		This function must be implemented by the PSL.
    44 		This function must be implemented by the PSL.
    42 
    45 
    92 		that has been configured or reserved. Otherwise it may be left at its
    95 		that has been configured or reserved. Otherwise it may be left at its
    93 		default value TDmaPriority::KDmaPriorityNone.
    96 		default value TDmaPriority::KDmaPriorityNone.
    94 	*/
    97 	*/
    95 	static TDmaChannel* Open(TUint32 aOpenId, TBool aDynChannel, TUint aPriority);
    98 	static TDmaChannel* Open(TUint32 aOpenId, TBool aDynChannel, TUint aPriority);
    96 
    99 
       
   100 
    97 	/** Performs platform-specific operations when a channel is closed.
   101 	/** Performs platform-specific operations when a channel is closed.
    98 
   102 
    99 		If aChannel was opened as a dynamic channel then this call is a sign
   103 		If aChannel was opened as a dynamic channel then this call is a sign
   100 		that there is a client which does not intend to queue any further
   104 		that there is a client which does not intend to queue any further
   101 		transfer requests via this channel.
   105 		transfer requests via this channel.
   108 		@pre The PIL calls this function with a global fast mutex held to avoid
   112 		@pre The PIL calls this function with a global fast mutex held to avoid
   109 		race conditions.
   113 		race conditions.
   110 	*/
   114 	*/
   111 	static void Close(TDmaChannel* aChannel);
   115 	static void Close(TDmaChannel* aChannel);
   112 
   116 
       
   117 
   113 	/** Function allowing PSL to extend DMA API with new channel-independent
   118 	/** Function allowing PSL to extend DMA API with new channel-independent
   114 		operations.
   119 		operations.
   115 
   120 
   116 		This function must be implemented by the PSL.
   121 		This function must be implemented by the PSL.
   117 
   122 
   120 
   125 
   121 		@param aArg PSL-specific
   126 		@param aArg PSL-specific
   122 
   127 
   123 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
   128 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
   124 		otherwise.
   129 		otherwise.
   125 	 */
   130 	*/
   126 	static TInt StaticExtension(TInt aCmd, TAny* aArg);
   131 	static TInt StaticExtension(TInt aCmd, TAny* aArg);
       
   132 
   127 
   133 
   128 	/** Acquires the channel manager lock. Called by the PIL before opening and
   134 	/** Acquires the channel manager lock. Called by the PIL before opening and
   129 		closing a channel.
   135 		closing a channel.
   130 	*/
   136 	*/
   131 	static void Wait();
   137 	static void Wait();
   132 
   138 
       
   139 
   133 	/** Releases the channel manager lock. Called by the PIL after opening and
   140 	/** Releases the channel manager lock. Called by the PIL after opening and
   134 		closing a channel.
   141 		closing a channel.
   135 	*/
   142 	*/
   136 	static void Signal();
   143 	static void Signal();
   137 
   144 
   138 private:
   145 private:
   139 	/** Declared, defined, and called by PSL's DECLARE_STANDARD_EXTENSION(). */
   146 	/** Declared, defined, and called by PSL's DECLARE_STANDARD_EXTENSION(). */
   140 	friend TInt InitExtension();
   147 	friend TInt InitExtension();
   141 
   148 
   142 	/** Must be called in the DMA DLL entry point. */
   149 	/** Must be called in the PSL's DECLARE_STANDARD_EXTENSION(). */
   143 	static TInt Initialise();
   150 	static TInt Initialise();
   144 
   151 
   145 	static NFastMutex Lock;
   152 	static NFastMutex Lock;
   146 	};
   153 	};
   147 
   154 
   158 	Second, it exposes a set of virtual functions implemented by the PSL
   165 	Second, it exposes a set of virtual functions implemented by the PSL
   159 	(platform-specific layer).
   166 	(platform-specific layer).
   160 
   167 
   161 	These functions are the main interfaces between the PIL
   168 	These functions are the main interfaces between the PIL
   162 	(platform-independent layer) and PSL.
   169 	(platform-independent layer) and PSL.
   163 
       
   164 	@publishedPartner
       
   165 	@released
       
   166 */
   170 */
   167 class TDmac
   171 class TDmac
   168 	{
   172 	{
   169 	friend class DmaChannelMgr;
   173 friend class DmaChannelMgr;
       
   174 
       
   175 // The following two friend declarations will become obsolete once that
       
   176 // functionality is owned and provided by the controller class instead of the
       
   177 // request class. (TDmac::iFreeHdr could then also be made private.)
       
   178 friend TInt DDmaRequest::ExpandDesList(TInt, TInt&, SDmaDesHdr*&, SDmaDesHdr*&);
       
   179 friend void DDmaRequest::FreeDesList(TInt&, SDmaDesHdr*&, SDmaDesHdr*&);
   170 
   180 
   171 protected:
   181 protected:
   172 	/** Data required for creating a new instance */
   182 	/** Data required for creating a new instance. */
   173 	struct SCreateInfo
   183 	struct SCreateInfo
   174 		{
   184 		{
   175 		/** True if DMAC uses hardware descriptors (i.e. supports
   185 		/** True if DMAC uses hardware descriptors (i.e. supports
   176 			scatter/gather mode).
   186 			scatter/gather mode).
   177 		*/
   187 		*/
   178 		TBool iCapsHwDes;
   188 		TBool iCapsHwDes;
       
   189 
   179 		/** Initial maximum number of descriptors and headers (shared by all
   190 		/** Initial maximum number of descriptors and headers (shared by all
   180 			channels) to be allocated by the PIL. If at run time more
   191 			channels) to be allocated by the PIL. If at run time more
   181 			descriptors are needed then they will be dynamically allocated and
   192 			descriptors are needed then they will be dynamically allocated and
   182 			added to the available pool.
   193 			added to the available pool.
   183 
   194 
   184 			The PSL may consider a number of factors when providing this
   195 			The PSL may consider a number of factors when providing this
   185 			initial value, such as the number of channels on this controller,
   196 			initial value, such as the number of channels on this controller,
   186 			the maximum transfer size per descriptor and also likely usage
   197 			the maximum transfer size per descriptor and also likely usage
   187 			scenarios for the platform or device (number of drivers using DMA,
   198 			scenarios for the platform or device (number of drivers using DMA,
   188 			their traffic patterns, simultaneity of operations, etc.).
   199 			their traffic patterns, simultaneity of operations, etc.).
       
   200 
       
   201 			(NB: Dynamic growing of the descriptor pool is not yet implemented
       
   202 			in the PIL, so this value is currently also the final maximum
       
   203 			number of descriptors.)
   189 		*/
   204 		*/
   190 		TInt iDesCount;
   205 		TInt iDesCount;
   191 		/** Size of individual descriptors. Use sizeof(TDmaTransferArgs) for
   206 
   192 		 	single-buffer and double-buffer (i.e. non-s/g) controllers.
   207 		/** Size of an individual descriptor.
       
   208 
       
   209 			Use sizeof(TDmaTransferArgs) for single-buffer and double-buffer
       
   210 		 	(i.e. non-s/g) controllers.
   193 		*/
   211 		*/
   194 		TInt iDesSize;
   212 		TInt iDesSize;
       
   213 
   195 		/** Bitmask used when creating the memory chunk storing the descriptor
   214 		/** Bitmask used when creating the memory chunk storing the descriptor
   196 			pool. Used only for hardware descriptors.
   215 			pool in the PIL. Used only for hardware descriptors.
   197 
   216 
   198 			The access part must be EMapAttrSupRw. If the chunk is cached
   217 			The access part must be EMapAttrSupRw. If the chunk is cached
   199 			and/or buffered, the PSL must flush the data cache and/or drain the
   218 			and/or buffered, the PSL must flush the data cache and/or drain the
   200 			write buffer in InitHwDes() and related functions.
   219 			write buffer in InitHwDes() and related functions.
   201 
   220 
   205 		 	@see TMappingAttributes
   224 		 	@see TMappingAttributes
   206 		 */
   225 		 */
   207 		TUint iDesChunkAttribs;
   226 		TUint iDesChunkAttribs;
   208 		};
   227 		};
   209 
   228 
   210 	/** Base class constructor. */
   229 	/** Base class constructor.
       
   230 	 */
   211 	TDmac(const SCreateInfo& aInfo);
   231 	TDmac(const SCreateInfo& aInfo);
   212 
   232 
   213 	/** Base class 2nd-phase constructor. */
   233 	/** Base class 2nd-phase constructor.
       
   234 	 */
   214 	TInt Create(const SCreateInfo& aInfo);
   235 	TInt Create(const SCreateInfo& aInfo);
   215 
   236 
   216 public:
   237 public:
   217 	/** Base class virtual destructor. */
   238 	/** Base class virtual destructor.
       
   239 	 */
   218 	virtual ~TDmac();
   240 	virtual ~TDmac();
       
   241 
   219 
   242 
   220 	/** Allocates a number of headers (and hence also descriptors) from the
   243 	/** Allocates a number of headers (and hence also descriptors) from the
   221 		header/descriptor pools. Called by the PIL but may also be used by the
   244 		header/descriptor pools. Called by the PIL but may also be used by the
   222 		PSL.
   245 		PSL.
   223 	*/
   246 	*/
   224 	TInt ReserveSetOfDes(TInt aCount);
   247 	TInt ReserveSetOfDes(TInt aCount);
   225 
   248 
       
   249 
   226 	/** Returns previously allocated headers (and hence also descriptors) to
   250 	/** Returns previously allocated headers (and hence also descriptors) to
   227 		the header/descriptor pools. Called by the PIL but may also be used by
   251 		the header/descriptor pools. Called by the PIL but may also be used by
   228 		the PSL.
   252 		the PSL.
   229 	*/
   253 	*/
   230 	void ReleaseSetOfDes(TInt aCount);
   254 	void ReleaseSetOfDes(TInt aCount);
   231 
   255 
       
   256 
   232 	/** Called by the PIL during request fragmentation to fill a descriptor or
   257 	/** Called by the PIL during request fragmentation to fill a descriptor or
   233 		pseudo descriptor with transfer arguments.
   258 		pseudo descriptor with transfer arguments.
   234 	*/
   259 	*/
   235 	TInt InitDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   260 	TInt InitDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   236 
   261 
       
   262 
   237 	/** Called by the PIL in TDmaChannel::IsrRedoRequest() if any of the
   263 	/** Called by the PIL in TDmaChannel::IsrRedoRequest() if any of the
   238 		latter's arguments is non-zero.
   264 		latter's arguments is non-zero.
   239 	*/
   265 	*/
   240 	TInt UpdateDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
   266 	TInt UpdateDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
   241 				   TUint aTransferCount, TUint32 aPslRequestInfo);
   267 				   TUint aTransferCount, TUint32 aPslRequestInfo);
   242 
   268 
       
   269 
   243 	/** Returns a reference to the associated pseudo descriptor for a given
   270 	/** Returns a reference to the associated pseudo descriptor for a given
   244 		descriptor header. For use by PIL and PSL.
   271 		descriptor header. For use by PIL and PSL.
   245 	*/
   272 	*/
   246 	inline TDmaTransferArgs& HdrToDes(const SDmaDesHdr& aHdr) const;
   273 	inline TDmaTransferArgs& HdrToDes(const SDmaDesHdr& aHdr) const;
   247 
   274 
       
   275 
   248 	/** Returns a reference to the associated hardware descriptor for a given
   276 	/** Returns a reference to the associated hardware descriptor for a given
   249 		descriptor header. For use by PIL and PSL.
   277 		descriptor header. For use by PIL and PSL.
   250 	*/
   278 	*/
   251 	inline TAny* HdrToHwDes(const SDmaDesHdr& aHdr) const;
   279 	inline TAny* HdrToHwDes(const SDmaDesHdr& aHdr) const;
   252 
   280 
       
   281 
   253 	/** Returns the physical address of the hardware descriptor
   282 	/** Returns the physical address of the hardware descriptor
   254 		pointed to by aDes. For use by PIL and PSL.
   283 		pointed to by aDes. For use by PIL and PSL.
   255 	*/
   284 	*/
   256 	inline TUint32 HwDesLinToPhys(TAny* aDes) const;
   285 	inline TUint32 HwDesLinToPhys(TAny* aDes) const;
   257 
   286 
   258 	/** Called by the PIL to acquire the controller lock which protects the
   287 
   259 		header and descriptor pools.
       
   260 	*/
       
   261 	inline void Wait();
       
   262 
       
   263 	/** Called by the PIL to release the controller lock which protects the
       
   264 		header and descriptor pools.
       
   265 	*/
       
   266 	inline void Signal();
       
   267 
       
   268 public:
       
   269 	/** Called by PIL when one fragment (single-buffer and double-buffer DMACs)
   288 	/** Called by PIL when one fragment (single-buffer and double-buffer DMACs)
   270 		or list of fragments (scatter/gather DMAC) is to be transferred.
   289 		or list of fragments (scatter/gather DMAC) is to be transferred.
   271 
   290 
   272 		Called when initiating a new transfer and also, for double-buffer
   291 		Called when initiating a new transfer and also, for double-buffer
   273 		DMACs, for configuring the next fragment to transfer while the current
   292 		DMACs, for configuring the next fragment to transfer while the current
   280 
   299 
   281 		@param aChannel The channel to use.
   300 		@param aChannel The channel to use.
   282 		@param aHdr Header associated with fragment to transfer.
   301 		@param aHdr Header associated with fragment to transfer.
   283 	*/
   302 	*/
   284 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
   303 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
       
   304 
   285 
   305 
   286 	/** Called by PIL when two lists of fragments (scatter/gather DMAC with
   306 	/** Called by PIL when two lists of fragments (scatter/gather DMAC with
   287 		asymmetrical linked-list capability) are to be transferred.
   307 		asymmetrical linked-list capability) are to be transferred.
   288 
   308 
   289 		Called when initiating a new transfer.
   309 		Called when initiating a new transfer.
   300 		destination side.
   320 		destination side.
   301 	*/
   321 	*/
   302 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aSrcHdr,
   322 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aSrcHdr,
   303 						  const SDmaDesHdr& aDstHdr);
   323 						  const SDmaDesHdr& aDstHdr);
   304 
   324 
       
   325 
   305 	/** Called by PIL to stop a transfer on a given channel.
   326 	/** Called by PIL to stop a transfer on a given channel.
   306 
   327 
   307 		The stopping must occur synchronously as the PIL assumes the channel
   328 		The stopping must occur synchronously as the PIL assumes the channel
   308 		is halted after calling this function. A channel stopped via this
   329 		is halted after calling this function. A channel stopped via this
   309 		function is not intended to be resumed. Function must always be
   330 		function is not intended to be resumed. Function must always be
   314 		@post No interrupt will occur from this channel until a new
   335 		@post No interrupt will occur from this channel until a new
   315 		request is queued.
   336 		request is queued.
   316 	*/
   337 	*/
   317 	virtual void StopTransfer(const TDmaChannel& aChannel) = 0;
   338 	virtual void StopTransfer(const TDmaChannel& aChannel) = 0;
   318 
   339 
       
   340 
   319 	/** Called by PIL to pause (suspend) a transfer on a given channel.
   341 	/** Called by PIL to pause (suspend) a transfer on a given channel.
   320 
   342 
   321 		A paused channel transfer must be able to be resumed by calling
   343 		A paused channel transfer must be able to be resumed by calling
   322 		ResumeTransfer().
   344 		ResumeTransfer().
   323 
   345 
   328 		KErrCompletion if the transfer was already paused, KErrGeneral
   350 		KErrCompletion if the transfer was already paused, KErrGeneral
   329 		if a general error occurred preventing a successful outcome.
   351 		if a general error occurred preventing a successful outcome.
   330 
   352 
   331 		@post No interrupt will occur from this channel until it is
   353 		@post No interrupt will occur from this channel until it is
   332 		resumed.
   354 		resumed.
   333 	 */
   355 	*/
   334 	virtual TInt PauseTransfer(const TDmaChannel& aChannel);
   356 	virtual TInt PauseTransfer(const TDmaChannel& aChannel);
       
   357 
   335 
   358 
   336 	/** Called by PIL to resume a paused (suspended) transfer on a given
   359 	/** Called by PIL to resume a paused (suspended) transfer on a given
   337 		channel.
   360 		channel.
   338 
   361 
   339 		Resume() can be called when the transfer is paused as a result of a
   362 		Resume() can be called when the transfer is paused as a result of a
   340 		previous call to PauseTransfer() or because the DMAC has encountered a
   363 		previous call to PauseTransfer() or because the DMAC has encountered a
   341 		Pause bit in a H/W descriptor.
   364 		Pause bit in a H/W descriptor.
   342 
   365 
   343 		The function must be implemented by the PSL if
   366 		The function must be implemented by the PSL if
   344 		SDmacCaps::iChannelPauseAndResume is reported as true.
   367 		SDmacCaps::iChannelPauseAndResume or
       
   368 		SDmacCaps::iLinkedListPausedInterrupt is reported as true.
   345 
   369 
   346 		@return KErrNone if the transfer has been resumed successfully,
   370 		@return KErrNone if the transfer has been resumed successfully,
   347 		KErrCompletion if there was no paused transfer, KErrGeneral
   371 		KErrCompletion if there was no paused transfer, KErrGeneral
   348 		if a general error occurred preventing a successful outcome.
   372 		if a general error occurred preventing a successful outcome.
   349 	 */
   373 	*/
   350 	virtual TInt ResumeTransfer(const TDmaChannel& aChannel);
   374 	virtual TInt ResumeTransfer(const TDmaChannel& aChannel);
       
   375 
   351 
   376 
   352 	/** Called by PIL to check whether a DMA channel is idle.
   377 	/** Called by PIL to check whether a DMA channel is idle.
   353 
   378 
   354 		'Idle' here means that the channel is ultimately stopped, for example
   379 		'Idle' here means that the channel is ultimately stopped, for example
   355 		because the transfer has finished, or an error was encountered, or it
   380 		because the transfer has finished, or an error was encountered, or it
   360 		@param aChannel The channel to test
   385 		@param aChannel The channel to test
   361 
   386 
   362 		@return ETrue if channel idle, EFalse if transferring.
   387 		@return ETrue if channel idle, EFalse if transferring.
   363 	*/
   388 	*/
   364 	virtual TBool IsIdle(const TDmaChannel& aChannel) = 0;
   389 	virtual TBool IsIdle(const TDmaChannel& aChannel) = 0;
       
   390 
   365 
   391 
   366 	/** Called by PIL to retrieve from the PSL the maximum transfer length
   392 	/** Called by PIL to retrieve from the PSL the maximum transfer length
   367 		based on the parameters passed.
   393 		based on the parameters passed.
   368 
   394 
   369 		@param aChannel Channel to be used for the transfer
   395 		@param aChannel Channel to be used for the transfer
   377 		@return 0 if transfer length is not limited, the maximum transfer
   403 		@return 0 if transfer length is not limited, the maximum transfer
   378 		length in bytes otherwise.
   404 		length in bytes otherwise.
   379 	*/
   405 	*/
   380 	virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
   406 	virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
   381 									TUint aDstFlags, TUint32 aPslInfo) = 0;
   407 									TUint aDstFlags, TUint32 aPslInfo) = 0;
       
   408 
   382 
   409 
   383 	/** Called by PIL to retrieve from the PSL the memory alignment mask based
   410 	/** Called by PIL to retrieve from the PSL the memory alignment mask based
   384 		on the parameters passed. Some DMA controllers impose alignment
   411 		on the parameters passed. Some DMA controllers impose alignment
   385 		constraints on the base address of memory buffers. This mask is AND'ed
   412 		constraints on the base address of memory buffers. This mask is AND'ed
   386 		against memory addresses computed during fragmentation.
   413 		against memory addresses computed during fragmentation.
   410 		be 4-byte aligned)
   437 		be 4-byte aligned)
   411 	*/
   438 	*/
   412 	virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aTargetFlags,
   439 	virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aTargetFlags,
   413 								   TUint aElementSize, TUint32 aPslInfo) = 0;
   440 								   TUint aElementSize, TUint32 aPslInfo) = 0;
   414 
   441 
       
   442 
   415 	/** Called by PIL during fragmentation to initialise a hardware descriptor.
   443 	/** Called by PIL during fragmentation to initialise a hardware descriptor.
   416 
   444 
   417 		The PSL must assume the descriptor is the last in the chain and so set
   445 		The PSL must assume the descriptor is the last in the chain and so set
   418 		the interrupt bit and set the next descriptor field to an end of chain
   446 		the interrupt bit and set the next descriptor field to an end of chain
   419 		marker.
   447 		marker.
   430 		KErrArgument if any of the transfer arguments were detected to be
   458 		KErrArgument if any of the transfer arguments were detected to be
   431 		invalid, KErrGeneral if a general error occurred preventing a
   459 		invalid, KErrGeneral if a general error occurred preventing a
   432 		successful outcome.
   460 		successful outcome.
   433 	*/
   461 	*/
   434 	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   462 	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
       
   463 
   435 
   464 
   436 	/** Called by PIL during fragmentation to initialise a hardware descriptor
   465 	/** Called by PIL during fragmentation to initialise a hardware descriptor
   437 		on the source side of an asymmetric linked list.
   466 		on the source side of an asymmetric linked list.
   438 
   467 
   439 		The function must be implemented by the PSL if
   468 		The function must be implemented by the PSL if
   450 		invalid, KErrGeneral if a general error occurred preventing a
   479 		invalid, KErrGeneral if a general error occurred preventing a
   451 		successful outcome.
   480 		successful outcome.
   452 	*/
   481 	*/
   453 	virtual TInt InitSrcHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   482 	virtual TInt InitSrcHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   454 
   483 
       
   484 
   455 	/** Called by PIL during fragmentation to initialise a hardware descriptor
   485 	/** Called by PIL during fragmentation to initialise a hardware descriptor
   456 		on the destination side of an asymmetric linked list.
   486 		on the destination side of an asymmetric linked list.
   457 
   487 
   458 		The function must be implemented by the PSL if
   488 		The function must be implemented by the PSL if
   459 		SDmaCaps::iAsymHwDescriptors is reported as true.
   489 		SDmaCaps::iAsymHwDescriptors is reported as true.
   468 		KErrArgument if any of the transfer arguments were detected to be
   498 		KErrArgument if any of the transfer arguments were detected to be
   469 		invalid, KErrGeneral if a general error occurred preventing a
   499 		invalid, KErrGeneral if a general error occurred preventing a
   470 		successful outcome.
   500 		successful outcome.
   471 	*/
   501 	*/
   472 	virtual TInt InitDstHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
   502 	virtual TInt InitDstHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
       
   503 
   473 
   504 
   474 	/** Called by the PIL in ISR context to change specific fields in a
   505 	/** Called by the PIL in ISR context to change specific fields in a
   475 		hardware descriptor.
   506 		hardware descriptor.
   476 
   507 
   477 		The function must be implemented by the PSL if and only if the DMAC
   508 		The function must be implemented by the PSL if and only if the DMAC
   495 		successful outcome.
   526 		successful outcome.
   496 	*/
   527 	*/
   497 	virtual TInt UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
   528 	virtual TInt UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
   498 							 TUint aTransferCount, TUint32 aPslRequestInfo);
   529 							 TUint aTransferCount, TUint32 aPslRequestInfo);
   499 
   530 
       
   531 
   500 	/** Called by the PIL in ISR context to change specific fields in a
   532 	/** Called by the PIL in ISR context to change specific fields in a
   501 		hardware descriptor.
   533 		hardware descriptor.
   502 
   534 
   503 		The function must be implemented by the PSL if
   535 		The function must be implemented by the PSL if
   504 		SDmaCaps::iAsymHwDescriptors is reported as true.
   536 		SDmaCaps::iAsymHwDescriptors is reported as true.
   519 		successful outcome.
   551 		successful outcome.
   520 	*/
   552 	*/
   521 	virtual TInt UpdateSrcHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr,
   553 	virtual TInt UpdateSrcHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr,
   522 								TUint aTransferCount, TUint32 aPslRequestInfo);
   554 								TUint aTransferCount, TUint32 aPslRequestInfo);
   523 
   555 
       
   556 
   524 	/** Called by the PIL in ISR context to change specific fields in a
   557 	/** Called by the PIL in ISR context to change specific fields in a
   525 		hardware descriptor.
   558 		hardware descriptor.
   526 
   559 
   527 		The function must be implemented by the PSL if
   560 		The function must be implemented by the PSL if
   528 		SDmaCaps::iAsymHwDescriptors is reported as true.
   561 		SDmaCaps::iAsymHwDescriptors is reported as true.
   543 		successful outcome.
   576 		successful outcome.
   544 	*/
   577 	*/
   545 	virtual TInt UpdateDstHwDes(const SDmaDesHdr& aHdr, TUint32 aDstAddr,
   578 	virtual TInt UpdateDstHwDes(const SDmaDesHdr& aHdr, TUint32 aDstAddr,
   546 								TUint aTransferCount, TUint32 aPslRequestInfo);
   579 								TUint aTransferCount, TUint32 aPslRequestInfo);
   547 
   580 
       
   581 
   548 	/** Called by PIL, when fragmenting a request, to append a new hardware
   582 	/** Called by PIL, when fragmenting a request, to append a new hardware
   549 		descriptor to an existing descriptor chain. May also be called by
   583 		descriptor to an existing descriptor chain. May also be called by
   550 		clients who wish to create their own descriptor chains.
   584 		clients who wish to create their own descriptor chains.
   551 
   585 
   552 		Must clear the interrupt bit of the descriptor associated with aHdr.
   586 		Must clear the interrupt bit of the descriptor associated with aHdr.
   556 
   590 
   557 		@param aHdr Header associated with last fragment in chain
   591 		@param aHdr Header associated with last fragment in chain
   558 		@param aNextHdr Header associated with fragment to append
   592 		@param aNextHdr Header associated with fragment to append
   559 	*/
   593 	*/
   560 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
   594 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
       
   595 
   561 
   596 
   562 	/** Called by PIL when queuing a new request while the channel is running.
   597 	/** Called by PIL when queuing a new request while the channel is running.
   563 
   598 
   564 		Must append the first hardware descriptor of the new request to the
   599 		Must append the first hardware descriptor of the new request to the
   565 		last descriptor in the existing chain.
   600 		last descriptor in the existing chain.
   573 		@param aNewHdr Header associated with first hardware descriptor in new
   608 		@param aNewHdr Header associated with first hardware descriptor in new
   574 		request
   609 		request
   575 	*/
   610 	*/
   576 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   611 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
   577 							 const SDmaDesHdr& aNewHdr);
   612 							 const SDmaDesHdr& aNewHdr);
       
   613 
   578 
   614 
   579 	/** Called by PIL when queuing a new request while the channel is running.
   615 	/** Called by PIL when queuing a new request while the channel is running.
   580 
   616 
   581 		Must append the first hardware descriptor of the new request to the
   617 		Must append the first hardware descriptor of the new request to the
   582 		last descriptor in the existing chain.
   618 		last descriptor in the existing chain.
   596 	*/
   632 	*/
   597 	virtual void AppendHwDes(const TDmaChannel& aChannel,
   633 	virtual void AppendHwDes(const TDmaChannel& aChannel,
   598 							 const SDmaDesHdr& aSrcLastHdr, const SDmaDesHdr& aSrcNewHdr,
   634 							 const SDmaDesHdr& aSrcLastHdr, const SDmaDesHdr& aSrcNewHdr,
   599 							 const SDmaDesHdr& aDstLastHdr, const SDmaDesHdr& aDstNewHdr);
   635 							 const SDmaDesHdr& aDstLastHdr, const SDmaDesHdr& aDstNewHdr);
   600 
   636 
       
   637 
   601 	/** Called by PIL when completing or cancelling a request to cause the PSL
   638 	/** Called by PIL when completing or cancelling a request to cause the PSL
   602 		to unlink the last item in the h/w descriptor chain from a subsequent
   639 		to unlink the last item in the h/w descriptor chain from a subsequent
   603 		chain that it was possibly linked to.
   640 		chain that it was possibly linked to.
   604 
   641 
   605 		The function must be implemented by the PSL if and only if the DMAC
   642 		The function must be implemented by the PSL if and only if the DMAC
   610 		@param aHdr Header associated with last h/w descriptor in
   647 		@param aHdr Header associated with last h/w descriptor in
   611 		completed / cancelled chain
   648 		completed / cancelled chain
   612 	*/
   649 	*/
   613 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
   650 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
   614 
   651 
       
   652 
   615 	/** Called by PIL when freeing descriptors back to the shared pool in
   653 	/** Called by PIL when freeing descriptors back to the shared pool in
   616 		FreeDesList(). The PSL inside ClearHwDes() can clear the contents of
   654 		FreeDesList(). The PSL inside ClearHwDes() can clear the contents of
   617 		the h/w descriptor.
   655 		the h/w descriptor.
   618 
   656 
   619 		This may be necessary if the PSL implementation uses the h/w descriptor
   657 		This may be necessary if the PSL implementation uses the h/w descriptor
   622 
   660 
   623 		The function may be implemented by the PSL if the DMAC supports
   661 		The function may be implemented by the PSL if the DMAC supports
   624 		hardware descriptors.
   662 		hardware descriptors.
   625 
   663 
   626 		@param aHdr Header associated with the h/w descriptor being freed.
   664 		@param aHdr Header associated with the h/w descriptor being freed.
   627 	 */
   665 	*/
   628 	virtual void ClearHwDes(const SDmaDesHdr& aHdr);
   666 	virtual void ClearHwDes(const SDmaDesHdr& aHdr);
       
   667 
   629 
   668 
   630 	/** Called by PIL to logically link two physical channels.
   669 	/** Called by PIL to logically link two physical channels.
   631 
   670 
   632 		The function must be implemented by the PSL if the DMAC supports
   671 		The function must be implemented by the PSL if the DMAC supports
   633 		logical channel linking.
   672 		logical channel linking.
   640 		@return KErrNone if the two channels have been linked successfully,
   679 		@return KErrNone if the two channels have been linked successfully,
   641 		KErrCompletion if a1stChannel was already linked to a2ndChannel,
   680 		KErrCompletion if a1stChannel was already linked to a2ndChannel,
   642 		KErrArgument if a1stChannel was already linked to a different channel,
   681 		KErrArgument if a1stChannel was already linked to a different channel,
   643 		KErrGeneral if a general error occurred preventing a successful
   682 		KErrGeneral if a general error occurred preventing a successful
   644 		outcome. The default PIL implementation returns KErrNotSupported.
   683 		outcome. The default PIL implementation returns KErrNotSupported.
   645 	 */
   684 	*/
   646 	virtual TInt LinkChannels(TDmaChannel& a1stChannel, TDmaChannel& a2ndChannel);
   685 	virtual TInt LinkChannels(TDmaChannel& a1stChannel, TDmaChannel& a2ndChannel);
       
   686 
   647 
   687 
   648 	/** Called by PIL to logically unlink a physical channel from its linked-to
   688 	/** Called by PIL to logically unlink a physical channel from its linked-to
   649 		successor.
   689 		successor.
   650 
   690 
   651 		The function must be implemented by the PSL if the DMAC supports
   691 		The function must be implemented by the PSL if the DMAC supports
   657 
   697 
   658 		@return KErrNone if the channel has been unlinked successfully,
   698 		@return KErrNone if the channel has been unlinked successfully,
   659 		KErrCompletion if the channel was not linked to another channel,
   699 		KErrCompletion if the channel was not linked to another channel,
   660 		KErrGeneral if a general error occurred preventing a successful
   700 		KErrGeneral if a general error occurred preventing a successful
   661 		outcome. The default PIL implementation returns KErrNotSupported.
   701 		outcome. The default PIL implementation returns KErrNotSupported.
   662 	 */
   702 	*/
   663 	virtual TInt UnlinkChannel(TDmaChannel& aChannel);
   703 	virtual TInt UnlinkChannel(TDmaChannel& aChannel);
       
   704 
   664 
   705 
   665 	/** Called by a test harness to force an error when the next fragment is
   706 	/** Called by a test harness to force an error when the next fragment is
   666 		transferred.
   707 		transferred.
   667 
   708 
   668 		Must be implemented by the PSL only if possible.
   709 		Must be implemented by the PSL only if possible.
   672 		@return KErrNone if implemented. The default PIL implementation
   713 		@return KErrNone if implemented. The default PIL implementation
   673 		returns KErrNotSupported.
   714 		returns KErrNotSupported.
   674 	*/
   715 	*/
   675 	virtual TInt FailNext(const TDmaChannel& aChannel);
   716 	virtual TInt FailNext(const TDmaChannel& aChannel);
   676 
   717 
       
   718 
   677 	/** Called by a test harness to force the DMA controller to miss one or
   719 	/** Called by a test harness to force the DMA controller to miss one or
   678 		more interrupts.
   720 		more interrupts.
   679 
   721 
   680 		The function must be implemented by the PSL only if possible.
   722 		The function must be implemented by the PSL only if possible.
   681 
   723 
   684 
   726 
   685 		@return KErrNone if implemented. The default PIL implementation
   727 		@return KErrNone if implemented. The default PIL implementation
   686 		returns KErrNotSupported.
   728 		returns KErrNotSupported.
   687 	*/
   729 	*/
   688 	virtual TInt MissNextInterrupts(const TDmaChannel& aChannel, TInt aInterruptCount);
   730 	virtual TInt MissNextInterrupts(const TDmaChannel& aChannel, TInt aInterruptCount);
       
   731 
   689 
   732 
   690 	/** Function allowing platform-specific layer to extend channel API with
   733 	/** Function allowing platform-specific layer to extend channel API with
   691 		new channel-specific operations.
   734 		new channel-specific operations.
   692 
   735 
   693 		@see TDmaChannel::ChannelExtension
   736 		@see TDmaChannel::ChannelExtension
   700 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
   743 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
   701 		otherwise.
   744 		otherwise.
   702 	*/
   745 	*/
   703 	virtual TInt Extension(TDmaChannel& aChannel, TInt aCmd, TAny* aArg);
   746 	virtual TInt Extension(TDmaChannel& aChannel, TInt aCmd, TAny* aArg);
   704 
   747 
       
   748 
   705 	/** Called by the PIL to query the number of elements that have so far been
   749 	/** Called by the PIL to query the number of elements that have so far been
   706 		transferred by the hardware descriptor associated with aHdr at the
   750 		transferred by the hardware descriptor associated with aHdr at the
   707 		source port.
   751 		source port.
   708 
   752 
   709 		If SDmacCaps::iAsymHwDescriptors is true then the PIL will call this
   753 		If SDmacCaps::iAsymHwDescriptors is true then the PIL will call this
   719 		@return The number of elements that have been transferred by the
   763 		@return The number of elements that have been transferred by the
   720 		hardware descriptor associated with aHdr at the source port
   764 		hardware descriptor associated with aHdr at the source port
   721 	*/
   765 	*/
   722 	virtual TUint32 HwDesNumSrcElementsTransferred(const SDmaDesHdr& aHdr);
   766 	virtual TUint32 HwDesNumSrcElementsTransferred(const SDmaDesHdr& aHdr);
   723 
   767 
       
   768 
   724 	/** Called by the PIL to query the number of elements that have so far been
   769 	/** Called by the PIL to query the number of elements that have so far been
   725 		transferred by the hardware descriptor associated with aHdr at the
   770 		transferred by the hardware descriptor associated with aHdr at the
   726 		destination port.
   771 		destination port.
   727 
   772 
   728 		If SDmacCaps::iAsymHwDescriptors is true then the PIL will call this
   773 		If SDmacCaps::iAsymHwDescriptors is true then the PIL will call this
   744 	/** Called by the PSL in interrupt context upon a channel interrupt event.
   789 	/** Called by the PSL in interrupt context upon a channel interrupt event.
   745 
   790 
   746 		@param aChannel The channel the ISR relates to
   791 		@param aChannel The channel the ISR relates to
   747 		@param aEventMask Bitmask of one or more TDmaCallbackType values
   792 		@param aEventMask Bitmask of one or more TDmaCallbackType values
   748 		@param aIsComplete Set to ETrue if no error was encountered
   793 		@param aIsComplete Set to ETrue if no error was encountered
   749 	 */
   794 	*/
   750 	static void HandleIsr(TDmaChannel& aChannel, TUint aEventMask, TBool aIsComplete);
   795 	static void HandleIsr(TDmaChannel& aChannel, TUint aEventMask, TBool aIsComplete);
   751 
   796 
   752 private:
   797 private:
   753 	/** Called in Create() */
   798 	/** Called in Create() */
   754 	TInt AllocDesPool(TUint aAttribs);
   799 	TInt AllocDesPool(TUint aAttribs);
   755 
   800 
   756 	/** Called in ~TDmac() */
   801 	/** Called in ~TDmac() */
   757 	void FreeDesPool();
   802 	void FreeDesPool();
       
   803 
       
   804 	/** Called by the PIL to acquire the controller lock which protects the
       
   805 		header and descriptor pools.
       
   806 	*/
       
   807 	inline void Wait();
       
   808 
       
   809 	/** Called by the PIL to release the controller lock which protects the
       
   810 		header and descriptor pools.
       
   811 	*/
       
   812 	inline void Signal();
   758 
   813 
   759 private:
   814 private:
   760 	NFastMutex iLock;			 // protect descriptor reservation and allocation
   815 	NFastMutex iLock;			 // protect descriptor reservation and allocation
   761 	const TInt iMaxDesCount;	 // initial number of descriptors and headers
   816 	const TInt iMaxDesCount;	 // initial number of descriptors and headers
   762 	TInt iAvailDesCount;		 // current available number of descriptors and headers
   817 	TInt iAvailDesCount;		 // current available number of descriptors and headers
   783 
   838 
   784 
   839 
   785 /** Single-buffer DMA channel.
   840 /** Single-buffer DMA channel.
   786 
   841 
   787 	Can be instantiated or further derived by the PSL.
   842 	Can be instantiated or further derived by the PSL.
   788 
       
   789 	@publishedPartner
       
   790 	@released
       
   791 */
   843 */
   792 class TDmaSbChannel : public TDmaChannel
   844 class TDmaSbChannel : public TDmaChannel
   793 	{
   845 	{
   794 private:
   846 private:
   795 	virtual void DoQueue(const DDmaRequest& aReq);
   847 	virtual void DoQueue(const DDmaRequest& aReq);
   796 	virtual void DoCancelAll();
   848 	virtual void DoCancelAll();
   797 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
   849 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
       
   850 
   798 private:
   851 private:
   799 	enum {EIdle = 0, ETransferring} iState;
   852 	enum {EIdle = 0, ETransferring} iState;
   800 	};
   853 	};
   801 
   854 
   802 
   855 
   803 /** Double-buffer DMA channel.
   856 /** Double-buffer DMA channel.
   804 
   857 
   805 	Can be instantiated or further derived by the PSL.
   858 	Can be instantiated or further derived by the PSL.
   806 
       
   807 	@publishedPartner
       
   808 	@released
       
   809 */
   859 */
   810 class TDmaDbChannel : public TDmaChannel
   860 class TDmaDbChannel : public TDmaChannel
   811 	{
   861 	{
   812 private:
   862 private:
   813 	virtual void DoQueue(const DDmaRequest& aReq);
   863 	virtual void DoQueue(const DDmaRequest& aReq);
   814 	virtual void DoCancelAll();
   864 	virtual void DoCancelAll();
   815 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
   865 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
       
   866 
   816 private:
   867 private:
   817 	enum {EIdle = 0, ETransferring, ETransferringLast} iState;
   868 	enum {EIdle = 0, ETransferring, ETransferringLast} iState;
   818 	};
   869 	};
   819 
   870 
   820 
   871 
   821 /** Scatter-gather DMA channel.
   872 /** Scatter-gather DMA channel.
   822 
   873 
   823 	Can be instantiated or further derived by the PSL.
   874 	Can be instantiated or further derived by the PSL.
   824 
       
   825 	@publishedPartner
       
   826 	@released
       
   827 */
   875 */
   828 class TDmaSgChannel : public TDmaChannel
   876 class TDmaSgChannel : public TDmaChannel
   829 	{
   877 	{
   830 private:
   878 private:
   831 	virtual void DoQueue(const DDmaRequest& aReq);
   879 	virtual void DoQueue(const DDmaRequest& aReq);
   832 	virtual void DoCancelAll();
   880 	virtual void DoCancelAll();
   833 	virtual void DoUnlink(SDmaDesHdr& aHdr);
   881 	virtual void DoUnlink(SDmaDesHdr& aHdr);
   834 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
   882 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
       
   883 
   835 private:
   884 private:
   836 	enum {EIdle = 0, ETransferring} iState;
   885 	enum {EIdle = 0, ETransferring} iState;
   837 	};
   886 	};
   838 
   887 
   839 
   888 
   840 /** Scatter-gather DMA channel with asymmetric linked-lists.
   889 /** Scatter-gather DMA channel with asymmetric linked-lists.
   841 
   890 
   842 	Can be instantiated or further derived by the PSL.
   891 	Can be instantiated or further derived by the PSL.
   843 
   892 
   844 	@publishedPartner
   893 	@prototype
   845 	@released
       
   846 */
   894 */
   847 class TDmaAsymSgChannel : public TDmaChannel
   895 class TDmaAsymSgChannel : public TDmaChannel
   848 	{
   896 	{
   849 private:
   897 private:
   850 	virtual void DoQueue(const DDmaRequest& aReq);
   898 	virtual void DoQueue(const DDmaRequest& aReq);
   851 	virtual void DoCancelAll();
   899 	virtual void DoCancelAll();
   852 	virtual void DoUnlink(SDmaDesHdr& aHdr);
   900 	virtual void DoUnlink(SDmaDesHdr& aHdr);
   853 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
   901 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
   854 					   SDmaDesHdr*& aDstCompletedHdr);
   902 					   SDmaDesHdr*& aDstCompletedHdr);
   855 private:
   903 
   856 	SDmaDesHdr* iSrcCurHdr;		   // source fragment being transferred or NULL
   904 private:
       
   905 	SDmaDesHdr* iSrcCurHdr;	  // source fragment being transferred or NULL
   857 	SDmaDesHdr** iSrcNullPtr; // Pointer to NULL pointer following last source fragment
   906 	SDmaDesHdr** iSrcNullPtr; // Pointer to NULL pointer following last source fragment
   858 	SDmaDesHdr* iDstCurHdr;	  // destination fragment being transferred or NULL
   907 	SDmaDesHdr* iDstCurHdr;	  // destination fragment being transferred or NULL
   859 	SDmaDesHdr** iDstNullPtr; // Pointer to NULL pointer following last destination fragment
   908 	SDmaDesHdr** iDstNullPtr; // Pointer to NULL pointer following last destination fragment
   860 	enum {EIdle = 0, ETransferring} iState;
   909 	enum {EIdle = 0, ETransferring} iState;
   861 	};
   910 	};