--- a/kernel/eka/drivers/dma/dma2_pil.cpp Mon Jul 26 10:52:56 2010 +0100
+++ b/kernel/eka/drivers/dma/dma2_pil.cpp Fri Aug 06 16:34:38 2010 +0100
@@ -1932,9 +1932,7 @@
{
iQueued = ETrue;
iChannel.iReqQ.Add(&iLink);
- // iChannel.iNullPtr points to iChannel.iCurHdr for an empty queue
- *iChannel.iNullPtr = iFirstHdr;
- iChannel.iNullPtr = &(iLastHdr->iNext);
+ iChannel.SetNullPtr(*this);
if (iIsrCb)
{
// Since we've made sure that there is no other request in the
@@ -1946,7 +1944,7 @@
// possible.
__e32_atomic_store_rel32(&iChannel.iIsrCbRequest, ETrue);
}
- iChannel.DoQueue(const_cast<const DDmaRequest&>(*this));
+ iChannel.DoQueue(*this);
r = KErrNone;
__DMA_INVARIANT();
iChannel.Signal();
@@ -2124,21 +2122,6 @@
__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::TotalNumSrcElementsTransferred"));
// Not yet implemented.
-
- // So far largely bogus code (just to touch some symbols)...
- iTotalNumSrcElementsTransferred = 0;
- TDmac& c = *(iChannel.iController);
- if (c.iCapsHwDes)
- {
- for (const SDmaDesHdr* pH = iFirstHdr; pH != NULL; pH = pH->iNext)
- {
- iTotalNumSrcElementsTransferred += c.HwDesNumDstElementsTransferred(*pH);
- }
- }
- else
- {
- // Do something different for pseudo descriptors...
- }
return iTotalNumSrcElementsTransferred;
}
@@ -2433,7 +2416,8 @@
// ISR should not happen after this function returns.
iController->StopTransfer(*this);
- ResetStateMachine();
+ DoCancelAll();
+ ResetNullPtr();
// Clean-up the request queue.
SDblQueLink* pL;
@@ -2707,8 +2691,7 @@
{
SDmaDesHdr* pCompletedSrcHdr = NULL;
SDmaDesHdr* pCompletedDstHdr = NULL;
- DoDfc(const_cast<const DDmaRequest&>(*pCurReq),
- pCompletedSrcHdr, pCompletedDstHdr);
+ DoDfc(*pCurReq, pCompletedSrcHdr, pCompletedDstHdr);
// We don't support asymmetrical ISR notifications and request
// completions yet, hence we can do the following assert test
// here; also 'complete' is determined equally by either the
@@ -2720,7 +2703,7 @@
else
{
SDmaDesHdr* pCompletedHdr = NULL;
- DoDfc(const_cast<const DDmaRequest&>(*pCurReq), pCompletedHdr);
+ DoDfc(*pCurReq, pCompletedHdr);
complete = (pCompletedHdr == pCurReq->iLastHdr);
}
// If just completed last fragment from current request, switch to
@@ -2731,7 +2714,7 @@
pCurReq->iLink.Deque();
iQueuedRequests--;
if (iReqQ.IsEmpty())
- iNullPtr = &iCurHdr;
+ ResetNullPtr();
pCompletedReq->OnDeque();
}
}
@@ -2818,17 +2801,6 @@
}
-//
-// Reset state machine only, request queue is unchanged */
-//
-void TDmaChannel::ResetStateMachine()
- {
- DoCancelAll();
- iCurHdr = NULL;
- iNullPtr = &iCurHdr;
- }
-
-
void TDmaChannel::DoQueue(const DDmaRequest& /*aReq*/)
{
// Must be overridden
@@ -2865,6 +2837,21 @@
}
+void TDmaChannel::SetNullPtr(const DDmaRequest& aReq)
+ {
+ // iNullPtr points to iCurHdr for an empty queue
+ *iNullPtr = aReq.iFirstHdr;
+ iNullPtr = &(aReq.iLastHdr->iNext);
+ }
+
+
+void TDmaChannel::ResetNullPtr()
+ {
+ iCurHdr = NULL;
+ iNullPtr = &iCurHdr;
+ }
+
+
/** PSL may override */
void TDmaChannel::QueuedRequestCountChanged()
{
@@ -3038,6 +3025,35 @@
//////////////////////////////////////////////////////////////////////////////
// TDmaAsymSgChannel
+TDmaAsymSgChannel::TDmaAsymSgChannel()
+ : iSrcCurHdr(NULL),
+ iSrcNullPtr(&iSrcCurHdr),
+ iDstCurHdr(NULL),
+ iDstNullPtr(&iDstCurHdr)
+ {
+ __DMA_INVARIANT();
+ }
+
+
+void TDmaAsymSgChannel::SetNullPtr(const DDmaRequest& aReq)
+ {
+ // i{Src|Dst}NullPtr points to i{Src|Dst}CurHdr for an empty queue
+ *iSrcNullPtr = aReq.iSrcFirstHdr;
+ *iDstNullPtr = aReq.iDstFirstHdr;
+ iSrcNullPtr = &(aReq.iSrcLastHdr->iNext);
+ iDstNullPtr = &(aReq.iDstLastHdr->iNext);
+ }
+
+
+void TDmaAsymSgChannel::ResetNullPtr()
+ {
+ iSrcCurHdr = NULL;
+ iSrcNullPtr = &iSrcCurHdr;
+ iDstCurHdr = NULL;
+ iDstNullPtr = &iDstCurHdr;
+ }
+
+
void TDmaAsymSgChannel::DoQueue(const DDmaRequest& aReq)
{
if (iState == ETransferring)
@@ -3082,3 +3098,34 @@
iState = (iSrcCurHdr != NULL) ? ETransferring : EIdle;
}
+
+#ifdef _DEBUG
+void TDmaAsymSgChannel::Invariant()
+ {
+ Wait();
+
+ __DMA_ASSERTD(iReqCount >= 0);
+
+ __DMA_ASSERTD(iSrcCurHdr == NULL || iController->IsValidHdr(iSrcCurHdr));
+ __DMA_ASSERTD(iDstCurHdr == NULL || iController->IsValidHdr(iDstCurHdr));
+
+ // should always point to NULL pointer ending fragment queue
+ __DMA_ASSERTD(*iSrcNullPtr == NULL);
+ __DMA_ASSERTD(*iDstNullPtr == NULL);
+
+ __DMA_ASSERTD((0 <= iAvailDesCount) && (iAvailDesCount <= iMaxDesCount));
+
+ __DMA_ASSERTD((iSrcCurHdr && iDstCurHdr && !IsQueueEmpty()) ||
+ (!iSrcCurHdr && !iDstCurHdr && IsQueueEmpty()));
+ if (iSrcCurHdr == NULL)
+ {
+ __DMA_ASSERTD(iSrcNullPtr == &iSrcCurHdr);
+ }
+ if (iDstCurHdr == NULL)
+ {
+ __DMA_ASSERTD(iDstNullPtr == &iDstCurHdr);
+ }
+
+ Signal();
+ }
+#endif