--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/dmav2/dma2_sim.cpp Tue Aug 31 16:34:26 2010 +0300
@@ -0,0 +1,760 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// os/kernelhwsrv/kerneltest/e32test/dmav2/dma2_sim.cpp
+// Partial simulation of DMA2 PSL
+//
+//
+
+
+#include <kernel/kern_priv.h>
+
+#include <drivers/dma.h>
+#include <drivers/dma_hai.h>
+
+#include "d_dma2.h"
+
+// Debug support
+static const char KDmaPanicCat[] = "DMA PSL - " __FILE__;
+
+static const TInt KMaxTransferLen = 0x1000; // max transfer length for this DMAC
+static const TInt KMemAlignMask = 0; // memory addresses passed to DMAC must be multiple of 8
+static const TInt KDesCount = 160; // Initial DMA descriptor count
+
+#define TEST_RETURN(X) if (!(X))\
+ {\
+ __KTRACE_OPT(KPANIC, Kern::Printf("Simulated Dma test failure: " __FILE__ " line %d", __LINE__));\
+ return KErrAbort;\
+ }
+
+class TDmaDesc
+//
+// Hardware DMA descriptor
+//
+ {
+public:
+ enum {KStopBitMask = 1};
+public:
+ TPhysAddr iDescAddr;
+ TPhysAddr iSrcAddr;
+ TPhysAddr iDestAddr;
+ TUint32 iCmd;
+ };
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Test Support
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+TO DO: Fill in to provide information to the V1 test harness (t_dma.exe)
+*/
+TDmaTestInfo TestInfo =
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL
+ };
+
+
+EXPORT_C const TDmaTestInfo& DmaTestInfo()
+//
+//
+//
+ {
+ return TestInfo;
+ }
+
+/**
+TO DO: Fill in to provide information to the V2 test harness (t_dma2.exe)
+*/
+TDmaV2TestInfo TestInfov2 =
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ {0},
+ 0,
+ {0},
+ 1,
+ {0}
+ };
+
+EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2()
+ {
+ return TestInfov2;
+ }
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Simulated channel
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+An interface class to add simulation specific functionallity to any DMA channel
+*/
+class MSimChannel
+ {
+public:
+ virtual TInt PreOpen() =0;
+ virtual TDmaChannel& Channel() =0;
+ };
+
+//////////////////////////////////////////////////////////////////////////////
+// Derived Channel (Scatter/Gather)
+//////////////////////////////////////////////////////////////////////////////
+
+const SDmacCaps KSimSgChanCaps =
+ {0, // TInt iChannelPriorities;
+ EFalse, // TBool iChannelPauseAndResume;
+ EFalse, // TBool iAddrAlignedToElementSize;
+ EFalse, // TBool i1DIndexAddressing;
+ EFalse, // TBool i2DIndexAddressing;
+ KDmaSyncAuto, // TUint iSynchronizationTypes;
+ KDmaBurstSizeAny, // TUint iBurstTransactions;
+ EFalse, // TBool iDescriptorInterrupt;
+ EFalse, // TBool iFrameInterrupt;
+ EFalse, // TBool iLinkedListPausedInterrupt;
+ EFalse, // TBool iEndiannessConversion;
+ KDmaGraphicsOpNone, // TUint iGraphicsOps;
+ EFalse, // TBool iRepeatingTransfers;
+ EFalse, // TBool iChannelLinking;
+ ETrue, // TBool iHwDescriptors;
+ EFalse, // TBool iSrcDstAsymmetry;
+ EFalse, // TBool iAsymHwDescriptors;
+ EFalse, // TBool iBalancedAsymSegments;
+ EFalse, // TBool iAsymCompletionInterrupt;
+ EFalse, // TBool iAsymDescriptorInterrupt;
+ EFalse, // TBool iAsymFrameInterrupt;
+ {0, 0, 0, 0, 0} // TUint32 iReserved[5];
+ };
+
+const SDmacCaps KSimSwChanCaps =
+ {0, // TInt iChannelPriorities;
+ EFalse, // TBool iChannelPauseAndResume;
+ EFalse, // TBool iAddrAlignedToElementSize;
+ EFalse, // TBool i1DIndexAddressing;
+ EFalse, // TBool i2DIndexAddressing;
+ KDmaSyncAuto, // TUint iSynchronizationTypes;
+ KDmaBurstSizeAny, // TUint iBurstTransactions;
+ EFalse, // TBool iDescriptorInterrupt;
+ EFalse, // TBool iFrameInterrupt;
+ EFalse, // TBool iLinkedListPausedInterrupt;
+ EFalse, // TBool iEndiannessConversion;
+ KDmaGraphicsOpNone, // TUint iGraphicsOps;
+ EFalse, // TBool iRepeatingTransfers;
+ EFalse, // TBool iChannelLinking;
+ EFalse, // TBool iHwDescriptors;
+ EFalse, // TBool iSrcDstAsymmetry;
+ EFalse, // TBool iAsymHwDescriptors;
+ EFalse, // TBool iBalancedAsymSegments;
+ EFalse, // TBool iAsymCompletionInterrupt;
+ EFalse, // TBool iAsymDescriptorInterrupt;
+ EFalse, // TBool iAsymFrameInterrupt;
+ {0, 0, 0, 0, 0} // TUint32 iReserved[5];
+ };
+
+class TEmptyChannel : public TDmaChannel, public MSimChannel
+ {
+public:
+ // Virtual from TDmaChannel
+ void DoCancelAll();
+
+ void CallDefaultVirtuals();
+ TInt CheckExtensionStubs();
+
+ // From MSimChannel
+ TInt PreOpen();
+ TDmaChannel& Channel() {return *this;}
+ };
+
+void TEmptyChannel::DoCancelAll()
+ {
+ __DMA_CANT_HAPPEN();
+ }
+
+void TEmptyChannel::CallDefaultVirtuals()
+ {
+ DMA_PSL_TRACE("Calling default virtual TDmaChannel functions");
+
+ const DDmaRequest* req = NULL;
+ SDmaDesHdr* hdr = NULL;
+
+ DoQueue(*req);
+ DoDfc(*req, hdr);
+ DoDfc(*req, hdr, hdr);
+
+ QueuedRequestCountChanged();
+ }
+
+TInt TEmptyChannel::CheckExtensionStubs()
+ {
+ DMA_PSL_TRACE("Calling extension stubs");
+
+ TInt r = Extension(0, NULL);
+ TEST_RETURN(r == KErrNotSupported)
+
+ r = StaticExtension(0, NULL);
+ TEST_RETURN(r == KErrNotSupported)
+
+ return KErrNone;
+ }
+
+TInt TEmptyChannel::PreOpen()
+ {
+ CallDefaultVirtuals();
+ return CheckExtensionStubs();
+ }
+
+//////////////////////////////////////////////////////////////////////////////
+// Derived SkelControllerSw Class
+//////////////////////////////////////////////////////////////////////////////
+
+class TSkelDmac : public TDmac
+ {
+public:
+ TSkelDmac(const SCreateInfo& aInfo);
+ TInt Create(const SCreateInfo& aInfo);
+private:
+ // from TDmac (PIL pure virtual)
+ virtual void StopTransfer(const TDmaChannel& aChannel);
+ virtual TBool IsIdle(const TDmaChannel& aChannel);
+ virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
+ TUint aDstFlags, TUint32 aPslInfo);
+ virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags,
+ TUint aDstFlags, TUint32 aPslInfo);
+
+ inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr);
+
+ void CallDefaultVirtuals();
+ TInt TestPool();
+
+public:
+ static const SCreateInfo KDmacInfoHw;
+ static const SCreateInfo KDmacInfoSw;
+
+ TEmptyChannel iChannel;
+ };
+
+
+const TDmac::SCreateInfo TSkelDmac::KDmacInfoHw =
+ {
+ ETrue, // iCapsHwDes
+ KDesCount, // iDesCount
+ sizeof(TDmaDesc), // iDesSize
+#ifndef __WINS__
+ EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs
+#endif
+ };
+
+const TDmac::SCreateInfo TSkelDmac::KDmacInfoSw =
+ {
+ EFalse, // iCapsHwDes
+ KDesCount, // iDesCount
+ sizeof(TDmaTransferArgs), // iDesSize
+#ifndef __WINS__
+ EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs
+#endif
+ };
+
+static TSkelDmac SkelControllerSw(TSkelDmac::KDmacInfoSw);
+static TSkelDmac SkelControllerHw(TSkelDmac::KDmacInfoHw);
+
+
+TSkelDmac::TSkelDmac(const SCreateInfo& aInfo)
+//
+// Constructor.
+//
+ : TDmac(aInfo)
+ {
+ TInt r = Create(aInfo);
+ __NK_ASSERT_ALWAYS(r == KErrNone);
+
+ CallDefaultVirtuals();
+ r = TestPool();
+ __NK_ASSERT_ALWAYS(r == KErrNone);
+ }
+
+
+TInt TSkelDmac::Create(const SCreateInfo& aInfo)
+//
+// Second phase construction.
+//
+ {
+ TInt r = TDmac::Create(aInfo); // Base class Create()
+ if (r == KErrNone)
+ {
+ __DMA_ASSERTA(ReserveSetOfDes(1) == KErrNone);
+ }
+ return r;
+ }
+
+
+void TSkelDmac::StopTransfer(const TDmaChannel& aChannel)
+//
+// Stops a running channel.
+//
+ {
+ const TUint8 i = static_cast<TUint8>(aChannel.PslId());
+
+ __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::StopTransfer channel=%d (unsupported)", i));
+
+ (void) i;
+
+ }
+
+
+TBool TSkelDmac::IsIdle(const TDmaChannel& aChannel)
+//
+// Returns the state of a given channel.
+//
+ {
+ const TUint8 i = static_cast<TUint8>(aChannel.PslId());
+
+ __KTRACE_OPT(KDMA, Kern::Printf(">TSkelDmac::IsIdle channel=%d (unsupported)", i));
+
+ // TO DO (for instance): Return the state of the RUN bit of the channel.
+ // The return value should reflect the actual state.
+ (void) i;
+
+ return ETrue;
+ }
+
+
+TUint TSkelDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
+ TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
+//
+// Returns the maximum transfer length in bytes for a given transfer.
+//
+ {
+ // TO DO: Determine the proper return value, based on the arguments.
+
+ // For instance:
+ return KMaxTransferLen;
+ }
+
+
+TUint TSkelDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
+ TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
+//
+// Returns the memory buffer alignment restrictions mask for a given transfer.
+//
+ {
+ // TO DO: Determine the proper return value, based on the arguments.
+
+ // For instance:
+ return KMemAlignMask;
+ }
+
+
+inline TDmaDesc* TSkelDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
+//
+// Changes return type of base class call.
+//
+ {
+ return static_cast<TDmaDesc*>(TDmac::HdrToHwDes(aHdr));
+ }
+
+/**
+Call the default virtual functions on the TDmac,
+that would never otherwise be called
+
+*/
+void TSkelDmac::CallDefaultVirtuals()
+ {
+ DMA_PSL_TRACE("Calling default virtual TDmac functions");
+
+ TDmaChannel* channel = NULL;
+ SDmaDesHdr* hdr = NULL;
+
+ Transfer(*channel, *hdr);
+ Transfer(*channel, *hdr, *hdr);
+
+ const TDmaTransferArgs args;
+ TInt r = KErrNone;
+
+ r = InitHwDes(*hdr, args);
+ __NK_ASSERT_ALWAYS(r == KErrGeneral);
+
+ r = InitSrcHwDes(*hdr, args);
+ __NK_ASSERT_ALWAYS(r == KErrGeneral);
+
+ r = InitDstHwDes(*hdr, args);
+ __NK_ASSERT_ALWAYS(r == KErrGeneral);
+
+ r = UpdateHwDes(*hdr, KPhysAddrInvalid, KPhysAddrInvalid, 0, 0);
+ __NK_ASSERT_ALWAYS(r == KErrGeneral);
+
+ r = UpdateSrcHwDes(*hdr, KPhysAddrInvalid, 0, 0);
+ __NK_ASSERT_ALWAYS(r == KErrGeneral);
+
+ r = UpdateDstHwDes(*hdr, KPhysAddrInvalid, 0, 0);
+ __NK_ASSERT_ALWAYS(r == KErrGeneral);
+
+ ChainHwDes(*hdr, *hdr);
+ AppendHwDes(*channel, *hdr, *hdr);
+ AppendHwDes(*channel, *hdr, *hdr, *hdr, *hdr);
+ UnlinkHwDes(*channel, *hdr);
+
+ TUint32 count = 0;
+
+ count = HwDesNumDstElementsTransferred(*hdr);
+ __NK_ASSERT_ALWAYS(count == 0);
+
+ count = HwDesNumSrcElementsTransferred(*hdr);
+ __NK_ASSERT_ALWAYS(count == 0);
+ }
+
+TInt TSkelDmac::TestPool()
+ {
+ DMA_PSL_TRACE("TSkelDmac::TestPool()");
+ TInt count = 0;
+ SDmaDesHdr* hdr = iFreeHdr;
+ TAny* des = iDesPool;
+
+ TInt r = KErrNone;
+ while(hdr->iNext)
+ {
+ TAny* receivedDes = NULL;
+ if(iCapsHwDes)
+ {
+ receivedDes = HdrToHwDes(*hdr);
+ }
+ else
+ {
+ TDmaTransferArgs& args = HdrToDes(*hdr);
+ receivedDes = &args;
+ }
+
+ if(receivedDes != des)
+ {
+ DMA_PSL_TRACE1("TSkelDmac::TestPool() failure: count=%d", count);
+ r = KErrGeneral;
+ break;
+ }
+
+ hdr = hdr->iNext;
+ des = (TAny*)((TUint)des + iDesSize);
+ count++;
+ }
+
+ if(count != (KDesCount - 1))
+ {
+ DMA_PSL_TRACE2("TSkelDmac::TestPool() failure: count = %d != (iMaxDesCount -1) = %d", count, KDesCount-1);
+ r = KErrUnknown;
+ }
+ return r;
+ }
+
+//////////////////////////////////////////////////////////////////////////////
+// Simulated Fragmentation Dmac
+//////////////////////////////////////////////////////////////////////////////
+
+
+const SDmacCaps KSimAsymmChanCaps =
+ {0, // TInt iChannelPriorities;
+ EFalse, // TBool iChannelPauseAndResume;
+ EFalse, // TBool iAddrAlignedToElementSize;
+ EFalse, // TBool i1DIndexAddressing;
+ EFalse, // TBool i2DIndexAddressing;
+ KDmaSyncAuto, // TUint iSynchronizationTypes;
+ KDmaBurstSizeAny, // TUint iBurstTransactions;
+ EFalse, // TBool iDescriptorInterrupt;
+ EFalse, // TBool iFrameInterrupt;
+ EFalse, // TBool iLinkedListPausedInterrupt;
+ EFalse, // TBool iEndiannessConversion;
+ KDmaGraphicsOpNone, // TUint iGraphicsOps;
+ EFalse, // TBool iRepeatingTransfers;
+ EFalse, // TBool iChannelLinking;
+ ETrue, // TBool iHwDescriptors;
+ EFalse, // TBool iSrcDstAsymmetry;
+ ETrue, // TBool iAsymHwDescriptors;
+ EFalse, // TBool iBalancedAsymSegments;
+ EFalse, // TBool iAsymCompletionInterrupt;
+ EFalse, // TBool iAsymDescriptorInterrupt;
+ EFalse, // TBool iAsymFrameInterrupt;
+ {0, 0, 0, 0, 0} // TUint32 iReserved[5];
+ };
+
+const SDmacCaps KSimAsymmBalancedChanCaps =
+ {0, // TInt iChannelPriorities;
+ EFalse, // TBool iChannelPauseAndResume;
+ EFalse, // TBool iAddrAlignedToElementSize;
+ EFalse, // TBool i1DIndexAddressing;
+ EFalse, // TBool i2DIndexAddressing;
+ KDmaSyncAuto, // TUint iSynchronizationTypes;
+ KDmaBurstSizeAny, // TUint iBurstTransactions;
+ EFalse, // TBool iDescriptorInterrupt;
+ EFalse, // TBool iFrameInterrupt;
+ EFalse, // TBool iLinkedListPausedInterrupt;
+ EFalse, // TBool iEndiannessConversion;
+ KDmaGraphicsOpNone, // TUint iGraphicsOps;
+ EFalse, // TBool iRepeatingTransfers;
+ EFalse, // TBool iChannelLinking;
+ ETrue, // TBool iHwDescriptors;
+ EFalse, // TBool iSrcDstAsymmetry;
+ ETrue, // TBool iAsymHwDescriptors;
+ ETrue, // TBool iBalancedAsymSegments;
+ EFalse, // TBool iAsymCompletionInterrupt;
+ EFalse, // TBool iAsymDescriptorInterrupt;
+ EFalse, // TBool iAsymFrameInterrupt;
+ {0, 0, 0, 0, 0} // TUint32 iReserved[5];
+ };
+
+
+class TAsymmDmac : public TDmac
+ {
+ struct THwDes
+ {
+ TUint iAddr;
+ TUint iLength;
+ TUint iCookie;
+ };
+public:
+ TAsymmDmac();
+ TInt Create();
+private:
+ // Work around for compiler which forbids this
+ // class from accessing the protected, nested TDmac::SCreateInfo
+ using TDmac::SCreateInfo;
+
+ // from TDmac (PIL pure virtual)
+ virtual void StopTransfer(const TDmaChannel& aChannel);
+ virtual TBool IsIdle(const TDmaChannel& aChannel);
+ virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
+ TUint aDstFlags, TUint32 aPslInfo);
+ virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags,
+ TUint aDstFlags, TUint32 aPslInfo);
+ // from TDmac (PIL virtual)
+ TInt InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/);
+ TInt InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/);
+
+ void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
+ void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
+
+ inline THwDes* HdrToHwDes(const SDmaDesHdr& aHdr);
+
+private:
+ static const SCreateInfo KInfo;
+public:
+ static const TInt iChannelCount;
+ TEmptyChannel iChannel;
+ };
+
+const TAsymmDmac::SCreateInfo TAsymmDmac::KInfo =
+ {
+ ETrue, // iCapsHwDes
+ KDesCount, // iDesCount
+ sizeof(THwDes), // iDesSize
+#ifndef __WINS__
+ EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs
+#endif
+ };
+
+const TInt TAsymmDmac::iChannelCount = 1;
+
+static TAsymmDmac AsymController;
+
+TAsymmDmac::TAsymmDmac()
+//
+// Constructor.
+//
+ : TDmac(KInfo)
+ {
+ TInt r = Create();
+ __NK_ASSERT_ALWAYS(r == KErrNone);
+ }
+
+
+TInt TAsymmDmac::Create()
+//
+// Second phase construction.
+//
+ {
+ TInt r = TDmac::Create(KInfo); // Base class Create()
+ if (r == KErrNone)
+ {
+ __DMA_ASSERTA(ReserveSetOfDes(iChannelCount) == KErrNone);
+ }
+ return r;
+ }
+
+
+void TAsymmDmac::StopTransfer(const TDmaChannel& /*aChannel*/)
+//
+// Stops a running channel.
+//
+ {
+ __DMA_CANT_HAPPEN();
+ }
+
+
+TBool TAsymmDmac::IsIdle(const TDmaChannel& /*aChannel*/)
+//
+// Returns the state of a given channel.
+//
+ {
+ __DMA_CANT_HAPPEN();
+ return ETrue;
+ }
+
+
+TUint TAsymmDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
+ TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
+//
+// Returns the maximum transfer length in bytes for a given transfer.
+//
+ {
+ // TO DO: Determine the proper return value, based on the arguments.
+
+ // For instance:
+ return KMaxTransferLen;
+ }
+
+
+TUint TAsymmDmac::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
+ TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
+//
+// Returns the memory buffer alignment restrictions mask for a given transfer.
+//
+ {
+ // TO DO: Determine the proper return value, based on the arguments.
+
+ // For instance:
+ return KMemAlignMask;
+ }
+
+
+inline TAsymmDmac::THwDes* TAsymmDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
+//
+// Changes return type of base class call.
+//
+ {
+ return static_cast<THwDes*>(TDmac::HdrToHwDes(aHdr));
+ }
+
+TInt TAsymmDmac::InitSrcHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/)
+ {
+ return KErrNone;
+ }
+
+TInt TAsymmDmac::InitDstHwDes(const SDmaDesHdr& /*aHdr*/, const TDmaTransferArgs& /*aTransferArgs*/)
+ {
+ return KErrNone;
+ }
+
+void TAsymmDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHdr*/)
+ {
+ }
+
+void TAsymmDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/)
+ {
+ }
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Channel Opening/Closing (Channel Allocator)
+//////////////////////////////////////////////////////////////////////////////
+
+struct TChanEntry
+ {
+ TChanEntry(TDmac& aController, MSimChannel& aChannel, const SDmacCaps& aCaps)
+ :
+ iController(aController),
+ iSimChannel(aChannel),
+ iCaps(aCaps)
+ {}
+
+ TDmac& iController;
+ MSimChannel& iSimChannel;
+ const SDmacCaps& iCaps;
+ };
+
+const TChanEntry ChannelTable[] =
+ {
+ TChanEntry(SkelControllerSw, SkelControllerSw.iChannel, KSimSwChanCaps),
+ TChanEntry(SkelControllerHw, SkelControllerHw.iChannel, KSimSgChanCaps),
+ TChanEntry(AsymController, AsymController.iChannel, KSimAsymmChanCaps),
+ TChanEntry(AsymController, AsymController.iChannel, KSimAsymmBalancedChanCaps)
+ };
+
+static const TInt KChannelCount = ARRAY_LENGTH(ChannelTable);
+
+TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/)
+//
+//
+//
+ {
+ __KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId));
+
+ __DMA_ASSERTA(aOpenId < static_cast<TUint32>(KChannelCount));
+
+ const TChanEntry& entry = ChannelTable[aOpenId];
+ TDmaChannel* pC = &entry.iSimChannel.Channel();
+ if (pC->IsOpened())
+ {
+ pC = NULL;
+ }
+ else
+ {
+ pC->iController = &entry.iController;
+ pC->iPslId = aOpenId;
+ pC->iDmacCaps = &entry.iCaps;
+
+ // It is safe to signal here,
+ // setting iController marks the channel
+ // as taken
+ Signal();
+
+ TInt r = entry.iSimChannel.PreOpen();
+
+ Wait();
+
+ // If there was an error
+ // Close channel after retaking mutex
+ if(r != KErrNone)
+ {
+ pC->iController = NULL;
+ pC = NULL;
+ }
+
+
+ }
+ return pC;
+ }
+
+
+void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/)
+//
+//
+//
+ {
+ // NOP
+ }
+
+
+TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/)
+//
+//
+//
+ {
+ return KErrNotSupported;
+ }