equal
deleted
inserted
replaced
11 // Contributors: |
11 // Contributors: |
12 // |
12 // |
13 // Description: |
13 // Description: |
14 // e32\drivers\dmapil.cpp |
14 // e32\drivers\dmapil.cpp |
15 // DMA Platform Independent Layer (PIL) |
15 // DMA Platform Independent Layer (PIL) |
16 // |
16 // |
17 // |
17 // |
18 |
18 |
19 #include <drivers/dma.h> |
19 #include <drivers/dma.h> |
20 #include <kernel/kern_priv.h> |
20 #include <kernel/kern_priv.h> |
21 |
21 |
475 |
475 |
476 // append request to queue and link new descriptor list to existing one. |
476 // append request to queue and link new descriptor list to existing one. |
477 iChannel.Wait(); |
477 iChannel.Wait(); |
478 |
478 |
479 TUint32 req_count = iChannel.iQueuedRequests++; |
479 TUint32 req_count = iChannel.iQueuedRequests++; |
480 if (iChannel.iCallQueuedRequestFn) |
480 if (req_count == 0) |
481 { |
481 { |
482 if (req_count == 0) |
482 iChannel.Signal(); |
483 { |
483 iChannel.QueuedRequestCountChanged(); |
484 iChannel.Signal(); |
484 iChannel.Wait(); |
485 iChannel.QueuedRequestCountChanged(); |
|
486 iChannel.Wait(); |
|
487 } |
|
488 } |
485 } |
489 |
486 |
490 if (!(iChannel.iIsrDfc & (TUint32)TDmaChannel::KCancelFlagMask)) |
487 if (!(iChannel.iIsrDfc & (TUint32)TDmaChannel::KCancelFlagMask)) |
491 { |
488 { |
492 iQueued = ETrue; |
489 iQueued = ETrue; |
501 { |
498 { |
502 // Someone is cancelling all requests... |
499 // Someone is cancelling all requests... |
503 req_count = --iChannel.iQueuedRequests; |
500 req_count = --iChannel.iQueuedRequests; |
504 __DMA_INVARIANT(); |
501 __DMA_INVARIANT(); |
505 iChannel.Signal(); |
502 iChannel.Signal(); |
506 if (iChannel.iCallQueuedRequestFn) |
503 if (req_count == 0) |
507 { |
504 { |
508 if (req_count == 0) |
505 iChannel.QueuedRequestCountChanged(); |
509 { |
|
510 iChannel.QueuedRequestCountChanged(); |
|
511 } |
|
512 } |
506 } |
513 } |
507 } |
514 } |
508 } |
515 |
509 |
516 EXPORT_C TInt DDmaRequest::ExpandDesList(TInt aCount) |
510 EXPORT_C TInt DDmaRequest::ExpandDesList(TInt aCount) |
632 iAvailDesCount(0), |
626 iAvailDesCount(0), |
633 iIsrDfc(0), |
627 iIsrDfc(0), |
634 iReqQ(), |
628 iReqQ(), |
635 iReqCount(0), |
629 iReqCount(0), |
636 iQueuedRequests(0), |
630 iQueuedRequests(0), |
637 iCallQueuedRequestFn(ETrue), |
|
638 iCancelInfo(NULL) |
631 iCancelInfo(NULL) |
639 { |
632 { |
640 __DMA_INVARIANT(); |
633 __DMA_INVARIANT(); |
641 } |
634 } |
642 |
635 |
765 NKern::FSWait(&c.iSem); |
758 NKern::FSWait(&c.iSem); |
766 NKern::ThreadLeaveCS(); |
759 NKern::ThreadLeaveCS(); |
767 |
760 |
768 // Only call PSL if there were requests queued when we entered AND there |
761 // Only call PSL if there were requests queued when we entered AND there |
769 // are now no requests left on the queue. |
762 // are now no requests left on the queue. |
770 if (iCallQueuedRequestFn) |
763 if ((req_count_before != 0) && (req_count_after == 0)) |
771 { |
764 { |
772 if ((req_count_before != 0) && (req_count_after == 0)) |
765 QueuedRequestCountChanged(); |
773 { |
|
774 QueuedRequestCountChanged(); |
|
775 } |
|
776 } |
766 } |
777 |
767 |
778 __DMA_INVARIANT(); |
768 __DMA_INVARIANT(); |
779 } |
769 } |
780 |
770 |
808 --count; |
798 --count; |
809 |
799 |
810 // If an error occurred it must have been reported on the last interrupt since transfers are |
800 // If an error occurred it must have been reported on the last interrupt since transfers are |
811 // suspended after an error. |
801 // suspended after an error. |
812 DDmaRequest::TResult res = (count==0 && error) ? DDmaRequest::EError : DDmaRequest::EOk; |
802 DDmaRequest::TResult res = (count==0 && error) ? DDmaRequest::EError : DDmaRequest::EOk; |
813 __DMA_ASSERTA(!iReqQ.IsEmpty()); |
803 __DMA_ASSERTD(!iReqQ.IsEmpty()); |
814 DDmaRequest* pCompletedReq = NULL; |
804 DDmaRequest* pCompletedReq = NULL; |
815 DDmaRequest* pCurReq = _LOFF(iReqQ.First(), DDmaRequest, iLink); |
805 DDmaRequest* pCurReq = _LOFF(iReqQ.First(), DDmaRequest, iLink); |
816 DDmaRequest::TCallback cb = 0; |
806 DDmaRequest::TCallback cb = 0; |
817 TAny* arg = 0; |
807 TAny* arg = 0; |
818 |
808 |
950 } |
940 } |
951 |
941 |
952 // Only call PSL if there were requests queued when we entered AND there |
942 // Only call PSL if there were requests queued when we entered AND there |
953 // are now no requests left on the queue (after also having executed all |
943 // are now no requests left on the queue (after also having executed all |
954 // client callbacks). |
944 // client callbacks). |
955 if (iCallQueuedRequestFn) |
945 if ((req_count_before != 0) && (req_count_after == 0)) |
956 { |
946 { |
957 if ((req_count_before != 0) && (req_count_after == 0)) |
947 QueuedRequestCountChanged(); |
958 { |
|
959 QueuedRequestCountChanged(); |
|
960 } |
|
961 } |
948 } |
962 |
949 |
963 __DMA_INVARIANT(); |
950 __DMA_INVARIANT(); |
964 } |
951 } |
965 |
952 |
983 |
970 |
984 |
971 |
985 /** PSL may override */ |
972 /** PSL may override */ |
986 void TDmaChannel::QueuedRequestCountChanged() |
973 void TDmaChannel::QueuedRequestCountChanged() |
987 { |
974 { |
988 __KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::QueuedRequestCountChanged(): " |
975 #ifdef _DEBUG |
989 "disabling further calls")); |
|
990 Wait(); |
976 Wait(); |
991 iCallQueuedRequestFn = EFalse; |
977 __KTRACE_OPT(KDMA, |
|
978 Kern::Printf("TDmaChannel::QueuedRequestCountChanged() %d", |
|
979 iQueuedRequests)); |
|
980 __DMA_ASSERTA(iQueuedRequests >= 0); |
992 Signal(); |
981 Signal(); |
|
982 #endif |
993 } |
983 } |
994 |
984 |
995 |
985 |
996 #ifdef _DEBUG |
986 #ifdef _DEBUG |
997 |
987 |