20 #include <drivers/dma_hai.h> |
20 #include <drivers/dma_hai.h> |
21 |
21 |
22 #include <kernel/kern_priv.h> |
22 #include <kernel/kern_priv.h> |
23 |
23 |
24 |
24 |
25 // Symbian Min() & Max() are broken, so we have to define them ourselves |
25 // Symbian _Min() & _Max() are broken, so we have to define them ourselves |
26 inline TUint Min(TUint aLeft, TUint aRight) |
26 inline TUint _Min(TUint aLeft, TUint aRight) |
27 {return(aLeft < aRight ? aLeft : aRight);} |
27 {return(aLeft < aRight ? aLeft : aRight);} |
28 inline TUint Max(TUint aLeft, TUint aRight) |
28 inline TUint _Max(TUint aLeft, TUint aRight) |
29 {return(aLeft > aRight ? aLeft : aRight);} |
29 {return(aLeft > aRight ? aLeft : aRight);} |
30 |
30 |
31 |
31 |
32 // Uncomment the following #define only when freezing the DMA2 export library. |
32 // The following section is used only when freezing the DMA2 export library |
33 //#define __FREEZE_DMA2_LIB |
33 /* |
34 #ifdef __FREEZE_DMA2_LIB |
|
35 TInt DmaChannelMgr::StaticExtension(TInt, TAny*) {return 0;} |
34 TInt DmaChannelMgr::StaticExtension(TInt, TAny*) {return 0;} |
36 TDmaChannel* DmaChannelMgr::Open(TUint32, TBool, TUint) {return 0;} |
35 TDmaChannel* DmaChannelMgr::Open(TUint32, TBool, TUint) {return 0;} |
37 void DmaChannelMgr::Close(TDmaChannel*) {} |
36 void DmaChannelMgr::Close(TDmaChannel*) {} |
38 EXPORT_C const TDmaTestInfo& DmaTestInfo() {static TDmaTestInfo a; return a;} |
37 EXPORT_C const TDmaTestInfo& DmaTestInfo() {static TDmaTestInfo a; return a;} |
39 EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() {static TDmaV2TestInfo a; return a;} |
38 EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() {static TDmaV2TestInfo a; return a;} |
40 #endif // #ifdef __FREEZE_DMA2_LIB |
39 */ |
41 |
|
42 |
40 |
43 static const char KDmaPanicCat[] = "DMA " __FILE__; |
41 static const char KDmaPanicCat[] = "DMA " __FILE__; |
44 |
42 |
45 ////////////////////////////////////////////////////////////////////// |
43 ////////////////////////////////////////////////////////////////////// |
46 // DmaChannelMgr |
44 // DmaChannelMgr |
200 |
198 |
201 void TDmac::Transfer(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aHdr*/) |
199 void TDmac::Transfer(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aHdr*/) |
202 { |
200 { |
203 // TDmac needs to override this function if it has reported the channel |
201 // TDmac needs to override this function if it has reported the channel |
204 // type for which the PIL calls it. |
202 // type for which the PIL calls it. |
205 __DMA_CANT_HAPPEN(); |
203 __DMA_UNREACHABLE_DEFAULT(); |
206 } |
204 } |
207 |
205 |
208 |
206 |
209 void TDmac::Transfer(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aSrcHdr*/, |
207 void TDmac::Transfer(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aSrcHdr*/, |
210 const SDmaDesHdr& /*aDstHdr*/) |
208 const SDmaDesHdr& /*aDstHdr*/) |
211 { |
209 { |
212 // TDmac needs to override this function if it has reported the channel |
210 // TDmac needs to override this function if it has reported the channel |
213 // type for which the PIL calls it. |
211 // type for which the PIL calls it. |
214 __DMA_CANT_HAPPEN(); |
212 __DMA_UNREACHABLE_DEFAULT(); |
215 } |
213 } |
216 |
214 |
217 |
215 |
218 TInt TDmac::PauseTransfer(const TDmaChannel& /*aChannel*/) |
216 TInt TDmac::PauseTransfer(const TDmaChannel& /*aChannel*/) |
219 { |
217 { |
448 |
446 |
449 |
447 |
450 TInt TDmac::InitHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
448 TInt TDmac::InitHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
451 { |
449 { |
452 // concrete controller must override if SDmacCaps::iHwDescriptors set |
450 // concrete controller must override if SDmacCaps::iHwDescriptors set |
453 __DMA_CANT_HAPPEN(); |
451 __DMA_UNREACHABLE_DEFAULT(); |
454 return KErrGeneral; |
452 return KErrGeneral; |
455 } |
453 } |
456 |
454 |
457 |
455 |
458 TInt TDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
456 TInt TDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
459 { |
457 { |
460 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
458 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
461 __DMA_CANT_HAPPEN(); |
459 __DMA_UNREACHABLE_DEFAULT(); |
462 return KErrGeneral; |
460 return KErrGeneral; |
463 } |
461 } |
464 |
462 |
465 |
463 |
466 TInt TDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
464 TInt TDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/) |
467 { |
465 { |
468 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
466 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
469 __DMA_CANT_HAPPEN(); |
467 __DMA_UNREACHABLE_DEFAULT(); |
470 return KErrGeneral; |
468 return KErrGeneral; |
471 } |
469 } |
472 |
470 |
473 |
471 |
474 TInt TDmac::UpdateDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr, |
472 TInt TDmac::UpdateDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr, |
500 |
498 |
501 TInt TDmac::UpdateHwDes(const SDmaDesHdr& /*aHdr*/, TUint32 /*aSrcAddr*/, TUint32 /*aDstAddr*/, |
499 TInt TDmac::UpdateHwDes(const SDmaDesHdr& /*aHdr*/, TUint32 /*aSrcAddr*/, TUint32 /*aDstAddr*/, |
502 TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) |
500 TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) |
503 { |
501 { |
504 // concrete controller must override if SDmacCaps::iHwDescriptors set |
502 // concrete controller must override if SDmacCaps::iHwDescriptors set |
505 __DMA_CANT_HAPPEN(); |
503 __DMA_UNREACHABLE_DEFAULT(); |
506 return KErrGeneral; |
504 return KErrGeneral; |
507 } |
505 } |
508 |
506 |
509 |
507 |
510 TInt TDmac::UpdateSrcHwDes(const SDmaDesHdr& /*aHdr*/, TUint32 /*aSrcAddr*/, |
508 TInt TDmac::UpdateSrcHwDes(const SDmaDesHdr& /*aHdr*/, TUint32 /*aSrcAddr*/, |
511 TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) |
509 TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) |
512 { |
510 { |
513 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
511 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
514 __DMA_CANT_HAPPEN(); |
512 __DMA_UNREACHABLE_DEFAULT(); |
515 return KErrGeneral; |
513 return KErrGeneral; |
516 } |
514 } |
517 |
515 |
518 |
516 |
519 TInt TDmac::UpdateDstHwDes(const SDmaDesHdr& /*aHdr*/, TUint32 /*aDstAddr*/, |
517 TInt TDmac::UpdateDstHwDes(const SDmaDesHdr& /*aHdr*/, TUint32 /*aDstAddr*/, |
520 TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) |
518 TUint /*aTransferCount*/, TUint32 /*aPslRequestInfo*/) |
521 { |
519 { |
522 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
520 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
523 __DMA_CANT_HAPPEN(); |
521 __DMA_UNREACHABLE_DEFAULT(); |
524 return KErrGeneral; |
522 return KErrGeneral; |
525 } |
523 } |
526 |
524 |
527 |
525 |
528 void TDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/) |
526 void TDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/) |
529 { |
527 { |
530 // concrete controller must override if SDmacCaps::iHwDescriptors set |
528 // concrete controller must override if SDmacCaps::iHwDescriptors set |
531 __DMA_CANT_HAPPEN(); |
529 __DMA_UNREACHABLE_DEFAULT(); |
532 } |
530 } |
533 |
531 |
534 |
532 |
535 void TDmac::AppendHwDes(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aLastHdr*/, |
533 void TDmac::AppendHwDes(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aLastHdr*/, |
536 const SDmaDesHdr& /*aNewHdr*/) |
534 const SDmaDesHdr& /*aNewHdr*/) |
537 { |
535 { |
538 // concrete controller must override if SDmacCaps::iHwDescriptors set |
536 // concrete controller must override if SDmacCaps::iHwDescriptors set |
539 __DMA_CANT_HAPPEN(); |
537 __DMA_UNREACHABLE_DEFAULT(); |
540 } |
538 } |
541 |
539 |
542 |
540 |
543 void TDmac::AppendHwDes(const TDmaChannel& /*aChannel*/, |
541 void TDmac::AppendHwDes(const TDmaChannel& /*aChannel*/, |
544 const SDmaDesHdr& /*aSrcLastHdr*/, const SDmaDesHdr& /*aSrcNewHdr*/, |
542 const SDmaDesHdr& /*aSrcLastHdr*/, const SDmaDesHdr& /*aSrcNewHdr*/, |
545 const SDmaDesHdr& /*aDstLastHdr*/, const SDmaDesHdr& /*aDstNewHdr*/) |
543 const SDmaDesHdr& /*aDstLastHdr*/, const SDmaDesHdr& /*aDstNewHdr*/) |
546 { |
544 { |
547 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
545 // concrete controller must override if SDmacCaps::iAsymHwDescriptors set |
548 __DMA_CANT_HAPPEN(); |
546 __DMA_UNREACHABLE_DEFAULT(); |
549 } |
547 } |
550 |
548 |
551 |
549 |
552 void TDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) |
550 void TDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) |
553 { |
551 { |
554 // concrete controller must override if SDmacCaps::iHwDescriptors set |
552 // concrete controller must override if SDmacCaps::iHwDescriptors set |
555 __DMA_CANT_HAPPEN(); |
553 __DMA_UNREACHABLE_DEFAULT(); |
556 } |
554 } |
557 |
555 |
558 |
556 |
559 void TDmac::ClearHwDes(const SDmaDesHdr& /*aHdr*/) |
557 void TDmac::ClearHwDes(const SDmaDesHdr& /*aHdr*/) |
560 { |
558 { |
1099 |
1097 |
1100 // Set the channel cookie for the PSL |
1098 // Set the channel cookie for the PSL |
1101 aTransferArgs.iChannelCookie = iChannel.PslId(); |
1099 aTransferArgs.iChannelCookie = iChannel.PslId(); |
1102 |
1100 |
1103 // Client shouldn't specify contradictory or invalid things |
1101 // Client shouldn't specify contradictory or invalid things |
1104 TInt r = CheckMemFlags(aTransferArgs.iSrcConfig, count); |
1102 TInt r = CheckMemFlags(aTransferArgs.iSrcConfig); |
1105 if (r != KErrNone) |
1103 if (r != KErrNone) |
1106 { |
1104 { |
1107 __KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(src)")); |
1105 __KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(src)")); |
1108 return r; |
1106 return r; |
1109 } |
1107 } |
1110 r = CheckMemFlags(aTransferArgs.iDstConfig, count); |
1108 r = CheckMemFlags(aTransferArgs.iDstConfig); |
1111 if (r != KErrNone) |
1109 if (r != KErrNone) |
1112 { |
1110 { |
1113 __KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(dst)")); |
1111 __KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(dst)")); |
1114 return r; |
1112 return r; |
1115 } |
1113 } |
1158 __DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask_dst) == 0)); |
1156 __DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask_dst) == 0)); |
1159 |
1157 |
1160 // Max aligned length is used to make sure the beginnings of subtransfers |
1158 // Max aligned length is used to make sure the beginnings of subtransfers |
1161 // (i.e. fragments) are correctly aligned. |
1159 // (i.e. fragments) are correctly aligned. |
1162 const TUint max_aligned_len = (aMaxTransferLen & |
1160 const TUint max_aligned_len = (aMaxTransferLen & |
1163 ~(Max(align_mask_src, align_mask_dst))); |
1161 ~(_Max(align_mask_src, align_mask_dst))); |
1164 __KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len)); |
1162 __KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len)); |
1165 // Client and PSL sane? |
1163 // Client and PSL sane? |
1166 __DMA_ASSERTD(max_aligned_len > 0); |
1164 __DMA_ASSERTD(max_aligned_len > 0); |
1167 |
1165 |
1168 if (mem_src && mem_dst && |
1166 if (mem_src && mem_dst && |
1420 if (r != KErrNone) |
1418 if (r != KErrNone) |
1421 { |
1419 { |
1422 break; |
1420 break; |
1423 } |
1421 } |
1424 // Compute fragment size |
1422 // Compute fragment size |
1425 TUint c = Min(aMaxTransferLen, aCount); |
1423 TUint c = _Min(aMaxTransferLen, aCount); |
1426 __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); |
1424 __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); |
1427 |
1425 |
1428 if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) |
1426 if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) |
1429 { |
1427 { |
1430 c = MaxPhysSize(src.iAddr, c); |
1428 c = MaxPhysSize(src.iAddr, c); |
1431 __KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(src.iAddr, c) = %d", c)); |
1429 __KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(src.iAddr, c) = %d", c)); |
1534 if (r != KErrNone) |
1532 if (r != KErrNone) |
1535 { |
1533 { |
1536 break; |
1534 break; |
1537 } |
1535 } |
1538 // Compute fragment size |
1536 // Compute fragment size |
1539 TUint c = Min(aMaxTransferLen, aCount); |
1537 TUint c = _Min(aMaxTransferLen, aCount); |
1540 __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); |
1538 __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); |
1541 |
1539 |
1542 if (mem_dst && !(dst.iFlags & KDmaMemIsContiguous)) |
1540 if (mem_dst && !(dst.iFlags & KDmaMemIsContiguous)) |
1543 { |
1541 { |
1544 c = MaxPhysSize(dst.iAddr, c); |
1542 c = MaxPhysSize(dst.iAddr, c); |
1545 __KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(dst.iAddr, c) = %d", c)); |
1543 __KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(dst.iAddr, c) = %d", c)); |
1640 __DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask_dst) == 0)); |
1638 __DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask_dst) == 0)); |
1641 |
1639 |
1642 // Max aligned length is used to make sure the beginnings of subtransfers |
1640 // Max aligned length is used to make sure the beginnings of subtransfers |
1643 // (i.e. fragments) are correctly aligned. |
1641 // (i.e. fragments) are correctly aligned. |
1644 const TUint max_aligned_len = (aMaxTransferLen & |
1642 const TUint max_aligned_len = (aMaxTransferLen & |
1645 ~(Max(align_mask_src, align_mask_dst))); |
1643 ~(_Max(align_mask_src, align_mask_dst))); |
1646 __KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len)); |
1644 __KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len)); |
1647 // Client and PSL sane? |
1645 // Client and PSL sane? |
1648 __DMA_ASSERTD(max_aligned_len > 0); |
1646 __DMA_ASSERTD(max_aligned_len > 0); |
1649 |
1647 |
1650 if (mem_src && mem_dst && |
1648 if (mem_src && mem_dst && |
1722 { |
1720 { |
1723 break; |
1721 break; |
1724 } |
1722 } |
1725 __DMA_ASSERTD(iSrcDesCount == iDstDesCount); |
1723 __DMA_ASSERTD(iSrcDesCount == iDstDesCount); |
1726 // Compute fragment size |
1724 // Compute fragment size |
1727 TUint c = Min(aMaxTransferLen, aCount); |
1725 TUint c = _Min(aMaxTransferLen, aCount); |
1728 __KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c)); |
1726 __KTRACE_OPT(KDMA, Kern::Printf("c = _Min(aMaxTransferLen, aCount) = %d", c)); |
1729 |
1727 |
1730 // SRC |
1728 // SRC |
1731 if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) |
1729 if (mem_src && !(src.iFlags & KDmaMemIsContiguous)) |
1732 { |
1730 { |
1733 c = MaxPhysSize(src.iAddr, c); |
1731 c = MaxPhysSize(src.iAddr, c); |
2832 void TDmaChannel::DoDfc(const DDmaRequest& /*aCurReq*/, SDmaDesHdr*& /*aCompletedHdr*/) |
2830 void TDmaChannel::DoDfc(const DDmaRequest& /*aCurReq*/, SDmaDesHdr*& /*aCompletedHdr*/) |
2833 { |
2831 { |
2834 // To make sure this version of the function isn't called for channels for |
2832 // To make sure this version of the function isn't called for channels for |
2835 // which it isn't appropriate (and which therefore don't override it) we |
2833 // which it isn't appropriate (and which therefore don't override it) we |
2836 // put this check in here. |
2834 // put this check in here. |
2837 __DMA_CANT_HAPPEN(); |
2835 __DMA_UNREACHABLE_DEFAULT(); |
2838 } |
2836 } |
2839 |
2837 |
2840 |
2838 |
2841 void TDmaChannel::DoDfc(const DDmaRequest& /*aCurReq*/, SDmaDesHdr*& /*aSrcCompletedHdr*/, |
2839 void TDmaChannel::DoDfc(const DDmaRequest& /*aCurReq*/, SDmaDesHdr*& /*aSrcCompletedHdr*/, |
2842 SDmaDesHdr*& /*aDstCompletedHdr*/) |
2840 SDmaDesHdr*& /*aDstCompletedHdr*/) |
2843 { |
2841 { |
2844 // To make sure this version of the function isn't called for channels for |
2842 // To make sure this version of the function isn't called for channels for |
2845 // which it isn't appropriate (and which therefore don't override it) we |
2843 // which it isn't appropriate (and which therefore don't override it) we |
2846 // put this check in here. |
2844 // put this check in here. |
2847 __DMA_CANT_HAPPEN(); |
2845 __DMA_UNREACHABLE_DEFAULT(); |
2848 } |
2846 } |
2849 |
2847 |
2850 |
2848 |
2851 /** PSL may override */ |
2849 /** PSL may override */ |
2852 void TDmaChannel::QueuedRequestCountChanged() |
2850 void TDmaChannel::QueuedRequestCountChanged() |