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: |