kernel/eka/include/drivers/dma_v1.h
changeset 247 d8d70de2bd36
parent 152 657f875b013e
equal deleted inserted replaced
201:43365a9b78a3 247:d8d70de2bd36
   277 		{
   277 		{
   278 		/** Identifier used by PSL to select channel to open */
   278 		/** Identifier used by PSL to select channel to open */
   279 		TUint32 iCookie;
   279 		TUint32 iCookie;
   280 		/** Number of descriptors this channel can use */
   280 		/** Number of descriptors this channel can use */
   281 		TInt iDesCount;
   281 		TInt iDesCount;
   282 		/** DFC queue used to service DMA interrupts.  The DFC thread
   282 		/** DFC queue used to service DMA interrupts */
   283 			priority must be higher than any client thread priority to
       
   284 			avoid a situation where a transfer completes while being
       
   285 			cancelled and another transfer is started before the DFC
       
   286 			thread gets a chance to run.  This would lead to a stray
       
   287 			DFC.
       
   288 		*/
       
   289 		TDfcQue* iDfcQ;
   283 		TDfcQue* iDfcQ;
   290 		/** DFC priority */
   284 		/** DFC priority */
   291 		TUint8 iDfcPriority;
   285 		TUint8 iDfcPriority;
   292 		};
   286 		};
   293 public:
   287 public:
   391 			};
   385 			};
   392 
   386 
   393 		void TFooDmaChannel::QueuedRequestCountChanged()
   387 		void TFooDmaChannel::QueuedRequestCountChanged()
   394 			{
   388 			{
   395 			Kern::MutexWait(*iDmaMutex);
   389 			Kern::MutexWait(*iDmaMutex);
   396 			if ((iQueuedRequests > 0) && (iPrevQueuedRequests == 0))
   390 			const TInt queued_now = __e32_atomic_load_acq32(&iQueuedRequests);
       
   391 			if ((queued_now > 0) && (iPrevQueuedRequests == 0))
   397 				{
   392 				{
   398 				IncreasePowerCount(); // Base port specific
   393 				IncreasePowerCount(); // Base port specific
   399 				}
   394 				}
   400 			else if ((iQueuedRequests == 0) && (iPrevQueuedRequests > 0))
   395 			else if ((queued_now == 0) && (iPrevQueuedRequests > 0))
   401 				{
   396 				{
   402 				DecreasePowerCount(); // Base port specific
   397 				DecreasePowerCount(); // Base port specific
   403 				}
   398 				}
   404 			iPrevQueuedRequests = iQueuedRequests;
   399 			iPrevQueuedRequests = queued_now;
   405 			Kern::MutexSignal(*iDmaMutex);
   400 			Kern::MutexSignal(*iDmaMutex);
   406 			}
   401 			}
   407 
   402 
   408 		@endcode
   403 		@endcode
   409 
   404 
   434 	enum { KCancelFlagMask = 0x40000000 };					// bit 30 - cancel flag
   429 	enum { KCancelFlagMask = 0x40000000 };					// bit 30 - cancel flag
   435 	enum { KDfcCountMask = 0x3FFFFFFF };					// bits 0-29 - number of queued DFCs
   430 	enum { KDfcCountMask = 0x3FFFFFFF };					// bits 0-29 - number of queued DFCs
   436 	SDblQue iReqQ;											// being/about to be transferred request queue
   431 	SDblQue iReqQ;											// being/about to be transferred request queue
   437 	TInt iReqCount;											// number of requests attached to this channel
   432 	TInt iReqCount;											// number of requests attached to this channel
   438 	TInt iQueuedRequests; 									// number of requests currently queued on this channel
   433 	TInt iQueuedRequests; 									// number of requests currently queued on this channel
       
   434 	TBool iCallQueuedRequestFn;								// call QueuedRequestCountChanged? (default: true)
   439 private:
   435 private:
   440 	TDmaCancelInfo* iCancelInfo;
   436 	TDmaCancelInfo* iCancelInfo;
   441 	__DMA_DECLARE_INVARIANT
   437 	__DMA_DECLARE_INVARIANT
   442 	};
   438 	};
   443 
   439