kernel/eka/include/drivers/dma.h
branchRCL_3
changeset 41 0ffb4e86fcc9
parent 28 5b5d147c7838
child 43 c1f20ce4abcf
equal deleted inserted replaced
39:2bb754abd467 41:0ffb4e86fcc9
   331 	virtual void DoQueue(DDmaRequest& aReq) = 0;
   331 	virtual void DoQueue(DDmaRequest& aReq) = 0;
   332 	virtual void DoCancelAll() = 0;
   332 	virtual void DoCancelAll() = 0;
   333 	virtual void DoUnlink(SDmaDesHdr& aHdr);
   333 	virtual void DoUnlink(SDmaDesHdr& aHdr);
   334 	virtual void DoDfc(DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr) = 0;
   334 	virtual void DoDfc(DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr) = 0;
   335 	/**
   335 	/**
   336 	   This function allows the Platform Specific Layer (PSL) to control the
   336 	This function allows the Platform Specific Layer (PSL) to control the
   337 	   power management of the channel or its controller by overriding the
   337 	power management of the channel or its controller by overriding the
   338 	   PIL's default implementation (which does nothing) and making appropriate
   338 	PIL's default implementation (which does nothing) and making
   339 	   use of the Power Resource Manager (PRM).
   339 	appropriate use of the Power Resource Manager (PRM).
   340 
   340 
   341 	   The function gets called by the PIL whenever the channel's queued
   341 	The function gets called by the PIL whenever the channel's queued
   342 	   requests count has changed in a significant way, either before the
   342 	requests count has changed in a significant way, either before the
   343 	   channel's Transfer() method is invoked for a request on a previously
   343 	channel's Transfer() method is invoked for a request on a previously
   344 	   empty request queue, or immediately after the request count has become
   344 	empty request queue, or immediately after the request count has become
   345 	   zero because of request cancellation or completion.
   345 	zero because of request cancellation or completion.
   346 
   346 
   347 	   Depending on the current value of iQueuedRequests, the PSL may power
   347 	Depending on the current and previous observed values of
   348 	   down or power up the channel. Note that iQueuedRequests gets accessed
   348 	iQueuedRequests, the PSL may power down or power up the channel.
   349 	   and changed by different threads, so the PSL needs to take the usual
   349 
   350 	   precautions when evaluating the variable's value.
   350 	Note that iQueuedRequests gets accessed and changed by different
   351 
   351 	threads, so the PSL needs to take the usual precautions when evaluating
   352 	   None of the internal DMA framework mutexes is being held by the PIL when
   352 	the variable's value. Also, due to the multithreaded framework
   353 	   calling this function.
   353 	architecture, there is no guarantee that the function calls always
   354 
   354 	arrive at the PSL level in the strict chronological order of
   355 	   @see iQueuedRequests
   355 	iQueuedRequests being incremented/decremented in the PIL, i.e. it might
   356 	 */
   356 	happen that the PSL finds iQueuedRequests to have the same value in two
       
   357 	or more consecutive calls (that's why the previous observed value needs
       
   358 	to be locally available and taken into account). It is however promised
       
   359 	that before any actual transfer commences the PSL will find the request
       
   360 	count to be greater than zero and that after the last request has
       
   361 	finished it will be found to be zero.
       
   362 
       
   363 	None of the internal DMA framework mutexes is being held by the PIL
       
   364 	when calling this function.
       
   365 
       
   366 	Here is an example implementation for a derived channel class:
       
   367 
       
   368 	@code
       
   369 
       
   370 		class TFooDmaChannel : public TDmaSgChannel
       
   371 			{
       
   372 			DMutex* iDmaMutex;
       
   373 			TInt iPrevQueuedRequests;
       
   374 			virtual void QueuedRequestCountChanged();
       
   375 			};
       
   376 
       
   377 		void TFooDmaChannel::QueuedRequestCountChanged()
       
   378 			{
       
   379 			Kern::MutexWait(*iDmaMutex);
       
   380 			const TInt queued_now = __e32_atomic_load_acq32(&iQueuedRequests);
       
   381 			if ((queued_now > 0) && (iPrevQueuedRequests == 0))
       
   382 				{
       
   383 				IncreasePowerCount(); // Base port specific
       
   384 				}
       
   385 			else if ((queued_now == 0) && (iPrevQueuedRequests > 0))
       
   386 				{
       
   387 				DecreasePowerCount(); // Base port specific
       
   388 				}
       
   389 			iPrevQueuedRequests = queued_now;
       
   390 			Kern::MutexSignal(*iDmaMutex);
       
   391 			}
       
   392 
       
   393 	@endcode
       
   394 
       
   395 	@see iQueuedRequests
       
   396 	*/
   357 	virtual void QueuedRequestCountChanged();
   397 	virtual void QueuedRequestCountChanged();
   358 #if defined(__CPU_ARM) && !defined(__EABI__)
   398 #if defined(__CPU_ARM) && !defined(__EABI__)
   359 	inline virtual ~TDmaChannel() {}	// kill really annoying warning
   399 	inline virtual ~TDmaChannel() {}	// kill really annoying warning
   360 #endif
   400 #endif
   361 private:
   401 private: