kerneltest/e32test/dmav2/dma2_sim.cpp
changeset 247 d8d70de2bd36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/dmav2/dma2_sim.cpp	Wed Aug 18 11:08:29 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;
+	}