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