equal
deleted
inserted
replaced
1930 } |
1930 } |
1931 else |
1931 else |
1932 { |
1932 { |
1933 iQueued = ETrue; |
1933 iQueued = ETrue; |
1934 iChannel.iReqQ.Add(&iLink); |
1934 iChannel.iReqQ.Add(&iLink); |
1935 // iChannel.iNullPtr points to iChannel.iCurHdr for an empty queue |
1935 iChannel.SetNullPtr(*this); |
1936 *iChannel.iNullPtr = iFirstHdr; |
|
1937 iChannel.iNullPtr = &(iLastHdr->iNext); |
|
1938 if (iIsrCb) |
1936 if (iIsrCb) |
1939 { |
1937 { |
1940 // Since we've made sure that there is no other request in the |
1938 // Since we've made sure that there is no other request in the |
1941 // queue before this, the only thing of relevance is the channel |
1939 // queue before this, the only thing of relevance is the channel |
1942 // DFC which might yet have to complete for the previous request, |
1940 // DFC which might yet have to complete for the previous request, |
1944 // the client callback. This should be all right though as once |
1942 // the client callback. This should be all right though as once |
1945 // we've set the following flag no further Queue()'s will be |
1943 // we've set the following flag no further Queue()'s will be |
1946 // possible. |
1944 // possible. |
1947 __e32_atomic_store_rel32(&iChannel.iIsrCbRequest, ETrue); |
1945 __e32_atomic_store_rel32(&iChannel.iIsrCbRequest, ETrue); |
1948 } |
1946 } |
1949 iChannel.DoQueue(const_cast<const DDmaRequest&>(*this)); |
1947 iChannel.DoQueue(*this); |
1950 r = KErrNone; |
1948 r = KErrNone; |
1951 __DMA_INVARIANT(); |
1949 __DMA_INVARIANT(); |
1952 iChannel.Signal(); |
1950 iChannel.Signal(); |
1953 } |
1951 } |
1954 |
1952 |
2122 EXPORT_C TUint32 DDmaRequest::TotalNumSrcElementsTransferred() |
2120 EXPORT_C TUint32 DDmaRequest::TotalNumSrcElementsTransferred() |
2123 { |
2121 { |
2124 __KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::TotalNumSrcElementsTransferred")); |
2122 __KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::TotalNumSrcElementsTransferred")); |
2125 |
2123 |
2126 // Not yet implemented. |
2124 // Not yet implemented. |
2127 |
|
2128 // So far largely bogus code (just to touch some symbols)... |
|
2129 iTotalNumSrcElementsTransferred = 0; |
|
2130 TDmac& c = *(iChannel.iController); |
|
2131 if (c.iCapsHwDes) |
|
2132 { |
|
2133 for (const SDmaDesHdr* pH = iFirstHdr; pH != NULL; pH = pH->iNext) |
|
2134 { |
|
2135 iTotalNumSrcElementsTransferred += c.HwDesNumDstElementsTransferred(*pH); |
|
2136 } |
|
2137 } |
|
2138 else |
|
2139 { |
|
2140 // Do something different for pseudo descriptors... |
|
2141 } |
|
2142 return iTotalNumSrcElementsTransferred; |
2125 return iTotalNumSrcElementsTransferred; |
2143 } |
2126 } |
2144 |
2127 |
2145 |
2128 |
2146 EXPORT_C TUint32 DDmaRequest::TotalNumDstElementsTransferred() |
2129 EXPORT_C TUint32 DDmaRequest::TotalNumDstElementsTransferred() |
2431 // There is a transfer in progress. It may complete before the DMAC |
2414 // There is a transfer in progress. It may complete before the DMAC |
2432 // has stopped, but the resulting ISR will not post a DFC. |
2415 // has stopped, but the resulting ISR will not post a DFC. |
2433 // ISR should not happen after this function returns. |
2416 // ISR should not happen after this function returns. |
2434 iController->StopTransfer(*this); |
2417 iController->StopTransfer(*this); |
2435 |
2418 |
2436 ResetStateMachine(); |
2419 DoCancelAll(); |
|
2420 ResetNullPtr(); |
2437 |
2421 |
2438 // Clean-up the request queue. |
2422 // Clean-up the request queue. |
2439 SDblQueLink* pL; |
2423 SDblQueLink* pL; |
2440 while ((pL = iReqQ.GetFirst()) != NULL) |
2424 while ((pL = iReqQ.GetFirst()) != NULL) |
2441 { |
2425 { |
2705 TBool complete; |
2689 TBool complete; |
2706 if (iDmacCaps->iAsymHwDescriptors) |
2690 if (iDmacCaps->iAsymHwDescriptors) |
2707 { |
2691 { |
2708 SDmaDesHdr* pCompletedSrcHdr = NULL; |
2692 SDmaDesHdr* pCompletedSrcHdr = NULL; |
2709 SDmaDesHdr* pCompletedDstHdr = NULL; |
2693 SDmaDesHdr* pCompletedDstHdr = NULL; |
2710 DoDfc(const_cast<const DDmaRequest&>(*pCurReq), |
2694 DoDfc(*pCurReq, pCompletedSrcHdr, pCompletedDstHdr); |
2711 pCompletedSrcHdr, pCompletedDstHdr); |
|
2712 // We don't support asymmetrical ISR notifications and request |
2695 // We don't support asymmetrical ISR notifications and request |
2713 // completions yet, hence we can do the following assert test |
2696 // completions yet, hence we can do the following assert test |
2714 // here; also 'complete' is determined equally by either the |
2697 // here; also 'complete' is determined equally by either the |
2715 // SRC or DST side. |
2698 // SRC or DST side. |
2716 __DMA_ASSERTD(!LOGICAL_XOR((pCompletedSrcHdr == pCurReq->iSrcLastHdr), |
2699 __DMA_ASSERTD(!LOGICAL_XOR((pCompletedSrcHdr == pCurReq->iSrcLastHdr), |
2718 complete = (pCompletedDstHdr == pCurReq->iDstLastHdr); |
2701 complete = (pCompletedDstHdr == pCurReq->iDstLastHdr); |
2719 } |
2702 } |
2720 else |
2703 else |
2721 { |
2704 { |
2722 SDmaDesHdr* pCompletedHdr = NULL; |
2705 SDmaDesHdr* pCompletedHdr = NULL; |
2723 DoDfc(const_cast<const DDmaRequest&>(*pCurReq), pCompletedHdr); |
2706 DoDfc(*pCurReq, pCompletedHdr); |
2724 complete = (pCompletedHdr == pCurReq->iLastHdr); |
2707 complete = (pCompletedHdr == pCurReq->iLastHdr); |
2725 } |
2708 } |
2726 // If just completed last fragment from current request, switch to |
2709 // If just completed last fragment from current request, switch to |
2727 // next request (if any). |
2710 // next request (if any). |
2728 if (complete) |
2711 if (complete) |
2729 { |
2712 { |
2730 pCompletedReq = pCurReq; |
2713 pCompletedReq = pCurReq; |
2731 pCurReq->iLink.Deque(); |
2714 pCurReq->iLink.Deque(); |
2732 iQueuedRequests--; |
2715 iQueuedRequests--; |
2733 if (iReqQ.IsEmpty()) |
2716 if (iReqQ.IsEmpty()) |
2734 iNullPtr = &iCurHdr; |
2717 ResetNullPtr(); |
2735 pCompletedReq->OnDeque(); |
2718 pCompletedReq->OnDeque(); |
2736 } |
2719 } |
2737 } |
2720 } |
2738 else |
2721 else |
2739 { |
2722 { |
2816 |
2799 |
2817 __DMA_INVARIANT(); |
2800 __DMA_INVARIANT(); |
2818 } |
2801 } |
2819 |
2802 |
2820 |
2803 |
2821 // |
|
2822 // Reset state machine only, request queue is unchanged */ |
|
2823 // |
|
2824 void TDmaChannel::ResetStateMachine() |
|
2825 { |
|
2826 DoCancelAll(); |
|
2827 iCurHdr = NULL; |
|
2828 iNullPtr = &iCurHdr; |
|
2829 } |
|
2830 |
|
2831 |
|
2832 void TDmaChannel::DoQueue(const DDmaRequest& /*aReq*/) |
2804 void TDmaChannel::DoQueue(const DDmaRequest& /*aReq*/) |
2833 { |
2805 { |
2834 // Must be overridden |
2806 // Must be overridden |
2835 __DMA_UNREACHABLE_DEFAULT(); |
2807 __DMA_UNREACHABLE_DEFAULT(); |
2836 } |
2808 } |
2860 { |
2832 { |
2861 // To make sure this version of the function isn't called for channels for |
2833 // To make sure this version of the function isn't called for channels for |
2862 // which it isn't appropriate (and which therefore don't override it) we |
2834 // which it isn't appropriate (and which therefore don't override it) we |
2863 // put this check in here. |
2835 // put this check in here. |
2864 __DMA_UNREACHABLE_DEFAULT(); |
2836 __DMA_UNREACHABLE_DEFAULT(); |
|
2837 } |
|
2838 |
|
2839 |
|
2840 void TDmaChannel::SetNullPtr(const DDmaRequest& aReq) |
|
2841 { |
|
2842 // iNullPtr points to iCurHdr for an empty queue |
|
2843 *iNullPtr = aReq.iFirstHdr; |
|
2844 iNullPtr = &(aReq.iLastHdr->iNext); |
|
2845 } |
|
2846 |
|
2847 |
|
2848 void TDmaChannel::ResetNullPtr() |
|
2849 { |
|
2850 iCurHdr = NULL; |
|
2851 iNullPtr = &iCurHdr; |
2865 } |
2852 } |
2866 |
2853 |
2867 |
2854 |
2868 /** PSL may override */ |
2855 /** PSL may override */ |
2869 void TDmaChannel::QueuedRequestCountChanged() |
2856 void TDmaChannel::QueuedRequestCountChanged() |
3036 |
3023 |
3037 |
3024 |
3038 ////////////////////////////////////////////////////////////////////////////// |
3025 ////////////////////////////////////////////////////////////////////////////// |
3039 // TDmaAsymSgChannel |
3026 // TDmaAsymSgChannel |
3040 |
3027 |
|
3028 TDmaAsymSgChannel::TDmaAsymSgChannel() |
|
3029 : iSrcCurHdr(NULL), |
|
3030 iSrcNullPtr(&iSrcCurHdr), |
|
3031 iDstCurHdr(NULL), |
|
3032 iDstNullPtr(&iDstCurHdr) |
|
3033 { |
|
3034 __DMA_INVARIANT(); |
|
3035 } |
|
3036 |
|
3037 |
|
3038 void TDmaAsymSgChannel::SetNullPtr(const DDmaRequest& aReq) |
|
3039 { |
|
3040 // i{Src|Dst}NullPtr points to i{Src|Dst}CurHdr for an empty queue |
|
3041 *iSrcNullPtr = aReq.iSrcFirstHdr; |
|
3042 *iDstNullPtr = aReq.iDstFirstHdr; |
|
3043 iSrcNullPtr = &(aReq.iSrcLastHdr->iNext); |
|
3044 iDstNullPtr = &(aReq.iDstLastHdr->iNext); |
|
3045 } |
|
3046 |
|
3047 |
|
3048 void TDmaAsymSgChannel::ResetNullPtr() |
|
3049 { |
|
3050 iSrcCurHdr = NULL; |
|
3051 iSrcNullPtr = &iSrcCurHdr; |
|
3052 iDstCurHdr = NULL; |
|
3053 iDstNullPtr = &iDstCurHdr; |
|
3054 } |
|
3055 |
|
3056 |
3041 void TDmaAsymSgChannel::DoQueue(const DDmaRequest& aReq) |
3057 void TDmaAsymSgChannel::DoQueue(const DDmaRequest& aReq) |
3042 { |
3058 { |
3043 if (iState == ETransferring) |
3059 if (iState == ETransferring) |
3044 { |
3060 { |
3045 __DMA_ASSERTD(!aReq.iLink.Alone()); |
3061 __DMA_ASSERTD(!aReq.iLink.Alone()); |
3080 // Must be either both NULL or none of them. |
3096 // Must be either both NULL or none of them. |
3081 __DMA_ASSERTD(!LOGICAL_XOR(iSrcCurHdr, iDstCurHdr)); |
3097 __DMA_ASSERTD(!LOGICAL_XOR(iSrcCurHdr, iDstCurHdr)); |
3082 iState = (iSrcCurHdr != NULL) ? ETransferring : EIdle; |
3098 iState = (iSrcCurHdr != NULL) ? ETransferring : EIdle; |
3083 } |
3099 } |
3084 |
3100 |
|
3101 |
|
3102 #ifdef _DEBUG |
|
3103 void TDmaAsymSgChannel::Invariant() |
|
3104 { |
|
3105 Wait(); |
|
3106 |
|
3107 __DMA_ASSERTD(iReqCount >= 0); |
|
3108 |
|
3109 __DMA_ASSERTD(iSrcCurHdr == NULL || iController->IsValidHdr(iSrcCurHdr)); |
|
3110 __DMA_ASSERTD(iDstCurHdr == NULL || iController->IsValidHdr(iDstCurHdr)); |
|
3111 |
|
3112 // should always point to NULL pointer ending fragment queue |
|
3113 __DMA_ASSERTD(*iSrcNullPtr == NULL); |
|
3114 __DMA_ASSERTD(*iDstNullPtr == NULL); |
|
3115 |
|
3116 __DMA_ASSERTD((0 <= iAvailDesCount) && (iAvailDesCount <= iMaxDesCount)); |
|
3117 |
|
3118 __DMA_ASSERTD((iSrcCurHdr && iDstCurHdr && !IsQueueEmpty()) || |
|
3119 (!iSrcCurHdr && !iDstCurHdr && IsQueueEmpty())); |
|
3120 if (iSrcCurHdr == NULL) |
|
3121 { |
|
3122 __DMA_ASSERTD(iSrcNullPtr == &iSrcCurHdr); |
|
3123 } |
|
3124 if (iDstCurHdr == NULL) |
|
3125 { |
|
3126 __DMA_ASSERTD(iDstNullPtr == &iDstCurHdr); |
|
3127 } |
|
3128 |
|
3129 Signal(); |
|
3130 } |
|
3131 #endif |