diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/drivers/dma/dma2_pil.cpp --- 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(*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(*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(*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