201017_05
authorhgs
Tue, 04 May 2010 09:44:26 +0100
changeset 130 c30940f6d922
parent 129 a990138eda40
child 131 e880629062dd
201017_05
bsptemplate/asspandvariant/template_assp/dma.mmp
bsptemplate/asspandvariant/template_assp/dma_v2.mmp
bsptemplate/asspandvariant/template_assp/dmapsl.cpp
bsptemplate/asspandvariant/template_assp/dmapsl_v2.cpp
bsptemplate/asspandvariant/template_assp/template_assp.inf
bsptemplate/asspandvariant/template_variant/bld.inf
bsptemplate/asspandvariant/template_variant/rom/base_template.iby
bsptemplate/asspandvariant/template_variant/rom/kernel.iby
bsptemplate/asspandvariant/template_variant/soundsctemplate_v2.mmp
kernel/eka/drivers/dma/dma2_pil.cpp
kernel/eka/drivers/dma/dma2_shared.cpp
kernel/eka/drivers/dma/dmapil.cpp
kernel/eka/include/drivers/dma_compat.inl
kernel/eka/include/drivers/dma_hai.h
kernel/eka/include/drivers/dma_v1.h
kernel/eka/include/drivers/dma_v2.h
kernel/eka/include/drivers/dma_v2.inl
kernel/eka/include/drivers/dmadefs.h
kernel/eka/include/e32ver.h
kernel/eka/include/kernel/kernel.h
kernel/eka/release.txt
kerneltest/e32test/dmav2/d_dma2.cpp
kerneltest/e32test/dmav2/d_dma2.h
kerneltest/e32test/dmav2/d_dma2_cmn.cpp
kerneltest/e32test/dmav2/dma_api_tests.cpp
kerneltest/e32test/dmav2/self_test.cpp
kerneltest/e32test/dmav2/t_dma2.cpp
kerneltest/e32test/dmav2/t_dma2.h
kerneltest/e32test/dmav2/test_cases.cpp
kerneltest/e32test/dmav2/test_thread.cpp
kerneltest/e32test/dmav2/test_thread.h
kerneltest/e32test/group/t_dma2.mmp
--- a/bsptemplate/asspandvariant/template_assp/dma.mmp	Thu Apr 29 11:08:53 2010 +0100
+++ b/bsptemplate/asspandvariant/template_assp/dma.mmp	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-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"
@@ -27,19 +27,17 @@
 noexportlibrary
 
 sourcepath		../../../kernel/eka/drivers/dma
-source			dma2_pil.cpp dma2_shared.cpp
+source			dmapil.cpp
 
 sourcepath		.
 source			dmapsl.cpp
 
 library			VariantTarget(katemplate,lib)
 
-deffile			../../../kernel/eka/~/dma2.def
+deffile			../../../kernel/eka/~/dma.def
 
 epocallowdlldata
 
 capability		all
 
 VENDORID 0x70000001
-
-MACRO DMA_APIV2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bsptemplate/asspandvariant/template_assp/dma_v2.mmp	Tue May 04 09:44:26 2010 +0100
@@ -0,0 +1,46 @@
+// Copyright (c) 2004-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:
+// template/template_assp/dma_v2.mmp
+//
+//
+
+#include		<variant.mmh>
+#include		"kernel/kern_ext.mmh"
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SYMBIAN_BASE_SYSTEMINCLUDE(assp/template_assp)
+
+target			VariantTarget(dma_v2,dll)
+targettype		kext
+linkas			dma.dll
+noexportlibrary
+
+sourcepath		../../../kernel/eka/drivers/dma
+source			dma2_pil.cpp dma2_shared.cpp
+
+sourcepath		.
+source			dmapsl_v2.cpp
+
+library			VariantTarget(katemplate,lib)
+
+deffile			../../../kernel/eka/~/dma2.def
+
+epocallowdlldata
+
+capability		all
+
+VENDORID 0x70000001
+
+MACRO DMA_APIV2
--- a/bsptemplate/asspandvariant/template_assp/dmapsl.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/bsptemplate/asspandvariant/template_assp/dmapsl.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-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"
@@ -21,16 +21,15 @@
 #include <template_assp.h>									// /assp/template_assp/
 
 #include <drivers/dma.h>
-#include <drivers/dma_hai.h>
 
 
 // Debug support
 static const char KDmaPanicCat[] = "DMA PSL - " __FILE__;
 
-static const TInt KMaxTransferLen = 0x1FE0;	// max transfer length for this DMAC
-static const TInt KMemAlignMask = 7; // memory addresses passed to DMAC must be multiple of 8
-static const TInt KChannelCount = 16;			// we got 16 channels
-static const TInt KDesCount = 160;				// Initial DMA descriptor count
+static const TInt KMaxTransferLen = 0x1FE0;					// max transfer length for this DMAC
+static const TInt KMemAlignMask = 7;				  // memory addresses passed to DMAC must be multiple of 8
+static const TInt KChannelCount = 16;						// we got 16 channels
+static const TInt KDesCount = 1024;							// DMA descriptor count
 
 
 class TDmaDesc
@@ -77,26 +76,6 @@
 	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},
-	0,
-	{0}
-	};
-
-EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2()
-	{
-	return TestInfov2;
-	}
 
 //////////////////////////////////////////////////////////////////////////////
 // Helper Functions
@@ -111,14 +90,14 @@
 	}
 
 
-static TUint32 DmaCmdReg(TUint aCount, TUint aFlags, TUint32 aSrcPslInfo, TUint32 aDstPslInfo)
+static TUint32 DcmdReg(TInt aCount, TUint aFlags, TUint32 aPslInfo)
 //
 // Returns value to set in DMA command register or in descriptor command field.
 //
 	{
 	// TO DO: Construct CMD word from input values.
 	// The return value should reflect the actual control word.
-	return (aCount | aFlags | aSrcPslInfo | aDstPslInfo);
+	return (aCount | aFlags | aPslInfo);
 	}
 
 
@@ -145,15 +124,14 @@
 	TInt Create();
 private:
 	// from TDmac (PIL pure virtual)
+	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
 	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);
+	virtual TInt MaxTransferSize(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo);
+	virtual TUint MemAlignMask(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo);
 	// from TDmac (PIL virtual)
-	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
-	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
+	virtual void InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
+ 						   TUint aFlags, TUint32 aPslInfo, TUint32 aCookie);
 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
 							 const SDmaDesHdr& aNewHdr);
@@ -173,10 +151,11 @@
 
 const TDmac::SCreateInfo TTemplateDmac::KInfo =
 	{
-	ETrue,													// iCapsHwDes
-	KDesCount,												// iDesCount
-	sizeof(TDmaDesc),										// iDesSize
-	EMapAttrSupRw | EMapAttrFullyBlocking					// iDesChunkAttribs
+	KChannelCount,
+	KDesCount,
+	TDmac::KCapsBitHwDes,
+	sizeof(TDmaDesc),
+	EMapAttrSupRw | EMapAttrFullyBlocking
 	};
 
 
@@ -201,7 +180,7 @@
 			{
 			TDmaDesc* pD = HdrToHwDes(*iFreeHdr);
 			iChannels[i].iTmpDes = pD;
-			iChannels[i].iTmpDesPhysAddr = HwDesLinToPhys(pD);
+			iChannels[i].iTmpDesPhysAddr = DesLinToPhys(pD);
 			iFreeHdr = iFreeHdr->iNext;
 			}
 		r = Interrupt::Bind(EAsspIntIdDma, Isr, this);
@@ -265,10 +244,9 @@
 	}
 
 
-TUint TTemplateDmac::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/,
-									   TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
+TInt TTemplateDmac::MaxTransferSize(TDmaChannel& /*aChannel*/, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
 //
-// Returns the maximum transfer length in bytes for a given transfer.
+// Returns the maximum transfer size for a given transfer.
 //
 	{
 	// TO DO: Determine the proper return value, based on the arguments.
@@ -278,8 +256,7 @@
 	}
 
 
-TUint TTemplateDmac::AddressAlignMask(TDmaChannel& aChannel, TUint /*aSrcFlags*/,
-									  TUint /*aDstFlags*/, TUint32 /*aPslInfo*/)
+TUint TTemplateDmac::MemAlignMask(TDmaChannel& /*aChannel*/, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
 //
 // Returns the memory buffer alignment restrictions mask for a given transfer.
 //
@@ -291,7 +268,8 @@
 	}
 
 
-TInt TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs)
+void TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
+							  TUint aFlags, TUint32 aPslInfo, TUint32 /*aCookie*/)
 //
 // Sets up (from a passed in request) the descriptor with that fragment's
 // source and destination address, the fragment size, and the (driver/DMA
@@ -306,15 +284,12 @@
 	// Unaligned descriptor? Bug in generic layer!
 	__DMA_ASSERTD(IsHwDesAligned(pD));
 
-	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
-	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
-	pD->iSrcAddr  = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr);
-	pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr);
-	pD->iCmd = DmaCmdReg(aTransferArgs.iTransferCount, aTransferArgs.iFlags,
-					   src.iPslTargetInfo, dst.iPslTargetInfo);
+	pD->iSrcAddr = (aFlags & KDmaPhysAddrSrc) ? aSrc : Epoc::LinearToPhysical(aSrc);
+	__DMA_ASSERTD(pD->iSrcAddr != KPhysAddrInvalid);
+	pD->iDestAddr = (aFlags & KDmaPhysAddrDest) ? aDest : Epoc::LinearToPhysical(aDest);
+	__DMA_ASSERTD(pD->iDestAddr != KPhysAddrInvalid);
+	pD->iCmd = DcmdReg(aCount, aFlags, aPslInfo);
 	pD->iDescAddr = TDmaDesc::KStopBitMask;
-
-	return KErrNone;
 	}
 
 
@@ -334,7 +309,7 @@
 
 	// TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer.
 
-	pD->iDescAddr = HwDesLinToPhys(pN);
+	pD->iDescAddr = DesLinToPhys(pN);
 	}
 
 
@@ -354,7 +329,7 @@
 	// Unaligned descriptor? Bug in generic layer!
 	__DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN));
 
-	TPhysAddr newPhys = HwDesLinToPhys(pN);
+	TPhysAddr newPhys = DesLinToPhys(pN);
 
 	const TInt irq = NKern::DisableAllInterrupts();
 	StopTransfer(aChannel);
@@ -398,7 +373,7 @@
 
 	// TO DO: Implement the behaviour described above, call HandleIsr().
 
-	HandleIsr(me.iChannels[5], EDmaCallbackRequestCompletion, ETrue); // Example
+	HandleIsr(me.iChannels[5], 0);							// Example
 
 	}
 
@@ -416,7 +391,7 @@
 // Channel Opening/Closing (Channel Allocator)
 //////////////////////////////////////////////////////////////////////////////
 
-TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool /*aDynChannel*/, TUint /*aPriority*/)
+TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId)
 //
 //
 //
@@ -469,10 +444,5 @@
 	{
 	__KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension"));
 
-	const TInt r = DmaChannelMgr::Initialise();
-	if (r != KErrNone)
-		{
-		return r;
-		}
 	return Controller.Create();
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bsptemplate/asspandvariant/template_assp/dmapsl_v2.cpp	Tue May 04 09:44:26 2010 +0100
@@ -0,0 +1,480 @@
+// Copyright (c) 2004-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:
+// bsptemplate/asspvariant/template_assp/dmapsl_v2.cpp
+// Template DMA Platform Specific Layer (PSL).
+//
+//
+
+
+#include <kernel/kern_priv.h>
+#include <template_assp.h>									// /assp/template_assp/
+
+#include <drivers/dma.h>
+#include <drivers/dma_hai.h>
+
+
+// Debug support
+static const char KDmaPanicCat[] = "DMA PSL - " __FILE__;
+
+static const TInt KMaxTransferLen = 0x1FE0;	// max transfer length for this DMAC
+static const TInt KMemAlignMask = 7; // memory addresses passed to DMAC must be multiple of 8
+static const TInt KChannelCount = 16;			// we got 16 channels
+static const TInt KDesCount = 160;				// Initial DMA descriptor count
+
+
+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},
+	0,
+	{0}
+	};
+
+EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2()
+	{
+	return TestInfov2;
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+// Helper Functions
+//////////////////////////////////////////////////////////////////////////////
+
+inline TBool IsHwDesAligned(TAny* aDes)
+//
+// Checks whether given hardware descriptor is 16-bytes aligned.
+//
+	{
+	return ((TLinAddr)aDes & 0xF) == 0;
+	}
+
+
+static TUint32 DmaCmdReg(TUint aCount, TUint aFlags, TUint32 aSrcPslInfo, TUint32 aDstPslInfo)
+//
+// Returns value to set in DMA command register or in descriptor command field.
+//
+	{
+	// TO DO: Construct CMD word from input values.
+	// The return value should reflect the actual control word.
+	return (aCount | aFlags | aSrcPslInfo | aDstPslInfo);
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Derived Channel (Scatter/Gather)
+//////////////////////////////////////////////////////////////////////////////
+
+class TTemplateSgChannel : public TDmaSgChannel
+	{
+public:
+	TDmaDesc* iTmpDes;
+	TPhysAddr iTmpDesPhysAddr;
+	};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Derived Controller Class
+//////////////////////////////////////////////////////////////////////////////
+
+class TTemplateDmac : public TDmac
+	{
+public:
+	TTemplateDmac();
+	TInt Create();
+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);
+	// from TDmac (PIL virtual)
+	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
+	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
+	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
+	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
+							 const SDmaDesHdr& aNewHdr);
+	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
+	// other
+	static void Isr(TAny* aThis);
+	inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr);
+private:
+	static const SCreateInfo KInfo;
+public:
+	TTemplateSgChannel iChannels[KChannelCount];
+	};
+
+
+static TTemplateDmac Controller;
+
+
+const TDmac::SCreateInfo TTemplateDmac::KInfo =
+	{
+	ETrue,													// iCapsHwDes
+	KDesCount,												// iDesCount
+	sizeof(TDmaDesc),										// iDesSize
+	EMapAttrSupRw | EMapAttrFullyBlocking					// iDesChunkAttribs
+	};
+
+
+TTemplateDmac::TTemplateDmac()
+//
+// Constructor.
+//
+	: TDmac(KInfo)
+	{}
+
+
+TInt TTemplateDmac::Create()
+//
+// Second phase construction.
+//
+	{
+	TInt r = TDmac::Create(KInfo);							// Base class Create()
+	if (r == KErrNone)
+		{
+		__DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone);
+		for (TInt i=0; i < KChannelCount; ++i)
+			{
+			TDmaDesc* pD = HdrToHwDes(*iFreeHdr);
+			iChannels[i].iTmpDes = pD;
+			iChannels[i].iTmpDesPhysAddr = HwDesLinToPhys(pD);
+			iFreeHdr = iFreeHdr->iNext;
+			}
+		r = Interrupt::Bind(EAsspIntIdDma, Isr, this);
+		if (r == KErrNone)
+			{
+			// TO DO: Map DMA clients (requests) to DMA channels here.
+
+			r = Interrupt::Enable(EAsspIntIdDma);
+			}
+		}
+	return r;
+	}
+
+
+void TTemplateDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr)
+//
+// Initiates a (previously constructed) request on a specific channel.
+//
+	{
+	const TUint8 i = static_cast<TUint8>(aChannel.PslId());
+	TDmaDesc* pD = HdrToHwDes(aHdr);
+
+	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::Transfer channel=%d des=0x%08X", i, pD));
+
+	// TO DO (for instance): Load the first descriptor address into the DMAC and start it
+	// by setting the RUN bit.
+	(void) *pD, (void) i;
+
+	}
+
+
+void TTemplateDmac::StopTransfer(const TDmaChannel& aChannel)
+//
+// Stops a running channel.
+//
+	{
+	const TUint8 i = static_cast<TUint8>(aChannel.PslId());
+
+	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::StopTransfer channel=%d", i));
+
+	// TO DO (for instance): Clear the RUN bit of the channel.
+	(void) i;
+
+	}
+
+
+TBool TTemplateDmac::IsIdle(const TDmaChannel& aChannel)
+//
+// Returns the state of a given channel.
+//
+	{
+	const TUint8 i = static_cast<TUint8>(aChannel.PslId());
+
+	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::IsIdle channel=%d", 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 TTemplateDmac::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 TTemplateDmac::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;
+	}
+
+
+TInt TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs)
+//
+// Sets up (from a passed in request) the descriptor with that fragment's
+// source and destination address, the fragment size, and the (driver/DMA
+// controller) specific transfer parameters (mem/peripheral, burst size,
+// transfer width).
+//
+	{
+	TDmaDesc* pD = HdrToHwDes(aHdr);
+
+	__KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD));
+
+	// Unaligned descriptor? Bug in generic layer!
+	__DMA_ASSERTD(IsHwDesAligned(pD));
+
+	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
+	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
+	pD->iSrcAddr  = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr);
+	__DMA_ASSERTD(pD->iSrcAddr != KPhysAddrInvalid);
+	pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr);
+	__DMA_ASSERTD(pD->iDestAddr != KPhysAddrInvalid);
+	pD->iCmd = DmaCmdReg(aTransferArgs.iTransferCount, aTransferArgs.iFlags,
+					   src.iPslTargetInfo, dst.iPslTargetInfo);
+	pD->iDescAddr = TDmaDesc::KStopBitMask;
+
+	return KErrNone;
+	}
+
+
+void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr)
+//
+// Chains hardware descriptors together by setting the next pointer of the original descriptor
+// to the physical address of the descriptor to be chained.
+//
+	{
+	TDmaDesc* pD = HdrToHwDes(aHdr);
+	TDmaDesc* pN = HdrToHwDes(aNextHdr);
+
+	__KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::ChainHwDes des=0x%08X next des=0x%08X", pD, pN));
+
+	// Unaligned descriptor? Bug in generic layer!
+	__DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN));
+
+	// TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer.
+
+	pD->iDescAddr = HwDesLinToPhys(pN);
+	}
+
+
+void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
+								const SDmaDesHdr& aNewHdr)
+//
+// Appends a descriptor to the chain while the channel is running.
+//
+	{
+	const TUint8 i = static_cast<TUint8>(aChannel.PslId());
+
+	TDmaDesc* pL = HdrToHwDes(aLastHdr);
+	TDmaDesc* pN = HdrToHwDes(aNewHdr);
+
+	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X",
+									i, pL, pN));
+	// Unaligned descriptor? Bug in generic layer!
+	__DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN));
+
+	TPhysAddr newPhys = HwDesLinToPhys(pN);
+
+	const TInt irq = NKern::DisableAllInterrupts();
+	StopTransfer(aChannel);
+
+	pL->iDescAddr = newPhys;
+	const TTemplateSgChannel& channel = static_cast<const TTemplateSgChannel&>(aChannel);
+	TDmaDesc* pD = channel.iTmpDes;
+
+	// TO DO: Implement the appropriate algorithm for appending a descriptor here.
+	(void) *pD, (void) i;
+
+	NKern::RestoreInterrupts(irq);
+
+	__KTRACE_OPT(KDMA, Kern::Printf("<TTemplateDmac::AppendHwDes"));
+	}
+
+
+void TTemplateDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& aHdr)
+//
+// Unlink the last item in the h/w descriptor chain from a subsequent chain that it was
+// possibly linked to.
+//
+	{
+ 	__KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::UnlinkHwDes"));
+  	TDmaDesc* pD = HdrToHwDes(aHdr);
+  	pD->iDescAddr = TDmaDesc::KStopBitMask;
+
+	// TO DO: Modify pD->iCmd so that an end-of-transfer interrupt will get raised.
+
+	}
+
+
+void TTemplateDmac::Isr(TAny* aThis)
+//
+// This ISR reads the interrupt identification and calls back into the base class
+// interrupt service handler with the channel identifier and an indication whether the
+// transfer completed correctly or with an error.
+//
+	{
+	TTemplateDmac& me = *static_cast<TTemplateDmac*>(aThis);
+
+	// TO DO: Implement the behaviour described above, call HandleIsr().
+
+	HandleIsr(me.iChannels[5], EDmaCallbackRequestCompletion, ETrue); // Example
+
+	}
+
+
+inline TDmaDesc* TTemplateDmac::HdrToHwDes(const SDmaDesHdr& aHdr)
+//
+// Changes return type of base class call.
+//
+	{
+	return static_cast<TDmaDesc*>(TDmac::HdrToHwDes(aHdr));
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Channel Opening/Closing (Channel Allocator)
+//////////////////////////////////////////////////////////////////////////////
+
+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));
+
+	TDmaChannel* pC = Controller.iChannels + aOpenId;
+	if (pC->IsOpened())
+		{
+		pC = NULL;
+		}
+	else
+		{
+		pC->iController = &Controller;
+		pC->iPslId = aOpenId;
+		}
+
+	return pC;
+	}
+
+
+void DmaChannelMgr::Close(TDmaChannel* /*aChannel*/)
+//
+//
+//
+	{
+	// NOP
+	}
+
+
+TInt DmaChannelMgr::StaticExtension(TInt /*aCmd*/, TAny* /*aArg*/)
+//
+//
+//
+	{
+	return KErrNotSupported;
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// DLL Exported Function
+//////////////////////////////////////////////////////////////////////////////
+
+DECLARE_STANDARD_EXTENSION()
+//
+// Creates and initializes a new DMA controller object on the kernel heap.
+//
+	{
+	__KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension"));
+
+	const TInt r = DmaChannelMgr::Initialise();
+	if (r != KErrNone)
+		{
+		return r;
+		}
+	return Controller.Create();
+	}
--- a/bsptemplate/asspandvariant/template_assp/template_assp.inf	Thu Apr 29 11:08:53 2010 +0100
+++ b/bsptemplate/asspandvariant/template_assp/template_assp.inf	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1998-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"
@@ -38,5 +38,6 @@
 
 katemplate
 dma
+dma_v2
 usbcc
 gpio
--- a/bsptemplate/asspandvariant/template_variant/bld.inf	Thu Apr 29 11:08:53 2010 +0100
+++ b/bsptemplate/asspandvariant/template_variant/bld.inf	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1998-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"
@@ -81,6 +81,7 @@
 cakdtemplate
 medlffstemplate
 soundsctemplate
+soundsctemplate_v2
 camerasctemplate
 exi2s
 //epbus
--- a/bsptemplate/asspandvariant/template_variant/rom/base_template.iby	Thu Apr 29 11:08:53 2010 +0100
+++ b/bsptemplate/asspandvariant/template_variant/rom/base_template.iby	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1998-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"
@@ -39,7 +39,11 @@
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_exmoncommon.dll			\sys\bin\exmoncommon.dll
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_exmondebug.dll			\sys\bin\exmondebug.dll
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_power.dll				\sys\bin\power.dll
+#ifdef SYMBIAN_USE_DMA_V2
+extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_dma_v2.dll			\sys\bin\dma.dll
+#else
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_dma.dll					\sys\bin\dma.dll
+#endif
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_lcd.dll					\sys\bin\lcd.dll
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_ekeyb.dll				\sys\bin\ekeyb.dll
 extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_exyin.dll				\sys\bin\exyin.dll
--- a/bsptemplate/asspandvariant/template_variant/rom/kernel.iby	Thu Apr 29 11:08:53 2010 +0100
+++ b/bsptemplate/asspandvariant/template_variant/rom/kernel.iby	Tue May 04 09:44:26 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2009-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"
@@ -30,7 +30,11 @@
 extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EXMONCOMMON.DLL \sys\bin\exmoncommon.dll
 extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EXMONDEBUG.DLL \sys\bin\exmondebug.dll
 extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_POWER.DLL		\sys\bin\power.dll
-extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_DMA.DLL		\sys\bin\DMA.DLL
+#ifdef SYMBIAN_USE_DMA_V2
+extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_DMA_V2.DLL		\sys\bin\dma.dll
+#else
+extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_DMA.DLL		\sys\bin\dma.dll
+#endif
 //
 // TO DO: (mandatory)
 //
@@ -46,7 +50,11 @@
 extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EXYIN.DLL		\sys\bin\exyin.dll
 device[VARID]=		\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EUART.PDD		\sys\bin\euart.pdd
 // SYM_BRANCH: Delete old sound driver
+#ifdef SYMBIAN_USE_DMA_V2
+device[VARID]= 		\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_SOUNDSC_V2.PDD		\sys\bin\soundsc.pdd
+#else
 device[VARID]= 		\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_SOUNDSC.PDD    	\sys\bin\soundsc.pdd
+#endif
 extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\ELOCD.LDD					\sys\bin\elocd.ldd
 extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_MEDINT.PDD		\sys\bin\medint.pdd
 //extension[VARID]=	\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUS.DLL		\sys\bin\epbus.dll
@@ -84,10 +92,15 @@
 // Include optional test drivers for e32test
 
 // Include if platform supports the standard Symbian DMA framework
-//device[VARID]=		\epoc32\release\##KMAIN##\##BUILD##\d_dma.ldd					\sys\bin\d_dma.ldd
+#ifdef SYMBIAN_USE_DMA_V2
+device[VARID]=		\epoc32\release\##KMAIN##\##BUILD##\d_dma2.ldd					\sys\bin\d_dma2.ldd
+device[VARID]=		\epoc32\release\##KMAIN##\##BUILD##\d_dma_compat.ldd			\sys\bin\d_dma_compat.ldd
+#else
+device[VARID]=		\epoc32\release\##KMAIN##\##BUILD##\d_dma.ldd					\sys\bin\d_dma.ldd
+device[VARID]=		\epoc32\release\##KMAIN##\##BUILD##\d_dma2_compat.ldd			\sys\bin\d_dma2_compat.ldd
+#endif
 
 // Include if platform supports MMC
 //device[VARID]=		\epoc32\release\##KMAIN##\##BUILD##\d_medch.ldd					\sys\bin\d_medch.ldd
 
 #endif
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bsptemplate/asspandvariant/template_variant/soundsctemplate_v2.mmp	Tue May 04 09:44:26 2010 +0100
@@ -0,0 +1,52 @@
+// Copyright (c) 2006-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:
+// template/template_variant/soundsctemplate.mmp
+// soundsc.pdd Template shared chunk sound PDD
+// 
+//
+
+/**
+ @file
+*/
+#define __USING_ASSP_REGISTER_API__
+#define __USING_ASSP_INTERRUPT_API__
+
+#include		<variant.mmh>
+#include		"kernel/kern_ext.mmh"
+
+target          	VariantTarget(soundsc_v2,pdd)
+targettype      	pdd
+romtarget		soundsc.pdd
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+SYMBIAN_BASE_SYSTEMINCLUDE(assp/template_assp)
+SYMBIAN_BASE_SYSTEMINCLUDE(template)
+SYMBIAN_BASE_SYSTEMINCLUDE(template/specific)
+USERINCLUDE		inc
+
+sourcepath		specific
+source          	soundsc_tx.cpp
+source          	soundsc_rx.cpp
+
+library         	dma2.lib
+library			VariantTarget(ecust,lib)
+
+uid             	0x100039d0 0x1000015c
+
+VENDORID 0x70000001
+
+capability		all
+EPOCALLOWDLLDATA
+
+MACRO DMA_APIV2
--- a/kernel/eka/drivers/dma/dma2_pil.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/drivers/dma/dma2_pil.cpp	Tue May 04 09:44:26 2010 +0100
@@ -118,11 +118,12 @@
 // Return minimum of aMaxSize and size of largest physically contiguous block
 // starting at aLinAddr.
 //
-static TInt MaxPhysSize(TLinAddr aLinAddr, const TInt aMaxSize)
+static TUint MaxPhysSize(TLinAddr aLinAddr, const TUint aMaxSize)
 	{
 	const TPhysAddr physBase = LinToPhys(aLinAddr);
+	__DMA_ASSERTD(physBase != KPhysAddrInvalid);
 	TLinAddr lin = aLinAddr;
-	TInt size = 0;
+	TUint size = 0;
 	for (;;)
 		{
 		// Round up the linear address to the next MMU page boundary
@@ -152,6 +153,7 @@
 	  iCapsHwDes(aInfo.iCapsHwDes),
 	  iFreeHdr(NULL)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmac::TDmac"));
 	__DMA_ASSERTD(iMaxDesCount > 0);
 	__DMA_ASSERTD(iDesSize > 0);
 	}
@@ -162,6 +164,7 @@
 //
 TInt TDmac::Create(const SCreateInfo& aInfo)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmac::Create"));
 	iHdrPool = new SDmaDesHdr[iMaxDesCount];
 	if (iHdrPool == NULL)
 		{
@@ -187,6 +190,7 @@
 
 TDmac::~TDmac()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmac::~TDmac"));
 	__DMA_INVARIANT();
 
 	FreeDesPool();
@@ -229,6 +233,7 @@
 
 TInt TDmac::AllocDesPool(TUint aAttribs)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmac::AllocDesPool"));
 	// Calling thread must be in CS
 	__ASSERT_CRITICAL;
 	TInt r;
@@ -269,6 +274,7 @@
 
 void TDmac::FreeDesPool()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmac::FreeDesPool"));
 	// Calling thread must be in CS
 	__ASSERT_CRITICAL;
 	if (iCapsHwDes)
@@ -317,6 +323,7 @@
 //
 void TDmac::ReleaseSetOfDes(TInt aCount)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmac::ReleaseSetOfDes count=%d", aCount));
 	__DMA_ASSERTD(aCount >= 0);
 	Wait();
 	iAvailDesCount += aCount;
@@ -386,6 +393,12 @@
 			// complete the request via the DFC in the usual way.
 			}
 		}
+	else
+		{
+		// The PIL doesn't support yet any completion types other than
+		// EDmaCallbackRequestCompletion.
+		__DMA_CANT_HAPPEN();
+		}
 
 	// Now queue a DFC if necessary. The possible scenarios are:
 	// a) DFC not queued (orig == 0)              -> update iIsrDfc + queue DFC
@@ -607,7 +620,7 @@
 	{
 	Wait();
 	__DMA_ASSERTD(0 <= iAvailDesCount && iAvailDesCount <= iMaxDesCount);
-	__DMA_ASSERTD(! iFreeHdr || IsValidHdr(iFreeHdr));
+	__DMA_ASSERTD(!iFreeHdr || IsValidHdr(iFreeHdr));
 	for (TInt i = 0; i < iMaxDesCount; i++)
 		__DMA_ASSERTD(iHdrPool[i].iNext == NULL || IsValidHdr(iHdrPool[i].iNext));
 	Signal();
@@ -622,8 +635,6 @@
 #endif
 
 
-
-
 //
 // Internal compat version, used by legacy Fragment()
 //
@@ -644,10 +655,13 @@
 	  iDelta(~0u),
 	  iReserved(0)
 	{
+	__KTRACE_OPT(KDMA,
+				 Kern::Printf("TDmaTransferConfig::TDmaTransferConfig "
+							  "aAddr=0x%08X aFlags=0x%08X aAddrInc=%d",
+							  aAddr, aFlags, aAddrInc));
 	}
 
 
-
 //
 // Internal compat version, used by legacy Fragment()
 //
@@ -661,11 +675,16 @@
 	  iFlags(0),
 	  iChannelPriority(KDmaPriorityNone),
 	  iPslRequestInfo(aPslInfo),
+	  iChannelCookie(0),
 	  iDelta(~0u),
 	  iReserved1(0),
-	  iChannelCookie(0),
 	  iReserved2(0)
 	{
+	__KTRACE_OPT(KDMA,
+				 Kern::Printf("TDmaTransferArgs::TDmaTransferArgs"));
+	__KTRACE_OPT(KDMA,
+				 Kern::Printf("  aSrc=0x%08X aDest=0x%08X aCount=%d aFlags=0x%08X aPslInfo=0x%08X",
+							  aSrc, aDest, aCount, aFlags, aPslInfo));
 	}
 
 
@@ -695,6 +714,7 @@
 	  iTotalNumSrcElementsTransferred(0),
 	  iTotalNumDstElementsTransferred(0)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::DDmaRequest =0x%08X (old style)", this));
 	iChannel.iReqCount++;
 	__DMA_ASSERTD(0 <= aMaxTransferSize);
 	__DMA_INVARIANT();
@@ -727,6 +747,7 @@
 	  iTotalNumSrcElementsTransferred(0),
 	  iTotalNumDstElementsTransferred(0)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::DDmaRequest =0x%08X (new style)", this));
 	__e32_atomic_add_ord32(&iChannel.iReqCount, 1);
 	__DMA_INVARIANT();
 	}
@@ -734,9 +755,18 @@
 
 EXPORT_C DDmaRequest::~DDmaRequest()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::~DDmaRequest"));
 	__DMA_ASSERTD(!iQueued);
 	__DMA_INVARIANT();
-	FreeDesList();
+	if (iChannel.iDmacCaps->iAsymHwDescriptors)
+		{
+		FreeSrcDesList();
+		FreeDstDesList();
+		}
+	else
+		{
+		FreeDesList();
+		}
 	__e32_atomic_add_ord32(&iChannel.iReqCount, TUint32(-1));
 	}
 
@@ -744,9 +774,9 @@
 EXPORT_C TInt DDmaRequest::Fragment(TUint32 aSrc, TUint32 aDest, TInt aCount,
 									TUint aFlags, TUint32 aPslInfo)
 	{
-	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::Fragment thread %O "
-									"src=0x%08X dest=0x%08X count=%d flags=0x%X psl=0x%08X",
-									&Kern::CurrentThread(), aSrc, aDest, aCount, aFlags, aPslInfo));
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::Fragment thread %O (old style)",
+									&Kern::CurrentThread()));
+
 	__DMA_ASSERTD(aCount > 0);
 
 	TDmaTransferArgs args(aSrc, aDest, aCount, aFlags, aPslInfo);
@@ -757,7 +787,8 @@
 
 EXPORT_C TInt DDmaRequest::Fragment(const TDmaTransferArgs& aTransferArgs)
 	{
-	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::Fragment thread %O", &Kern::CurrentThread()));
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::Fragment thread %O (new style)",
+									&Kern::CurrentThread()));
 
 	// Writable temporary working copy of the transfer arguments.
 	// We need this because we may have to modify some fields before passing it
@@ -769,10 +800,170 @@
 	}
 
 
-TUint DDmaRequest::GetTransferCount(const TDmaTransferArgs& aTransferArgs)
+TInt DDmaRequest::CheckTransferConfig(const TDmaTransferConfig& aTarget, TUint aCount) const
+	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::CheckTransferConfig"));
+
+	if (aTarget.iElementSize != 0)
+		{
+		if ((aCount % aTarget.iElementSize) != 0)
+			{
+			// 2, 7 (These strange numbers refer to some test cases documented
+			// elsewhere - they will be removed eventually.)
+			__KTRACE_OPT(KPANIC,
+						 Kern::Printf("Error: ((aCount %% iElementSize) != 0)"));
+			return KErrArgument;
+			}
+		if (aTarget.iElementsPerFrame != 0)
+			{
+			if ((aTarget.iElementSize * aTarget.iElementsPerFrame *
+				 aTarget.iFramesPerTransfer) != aCount)
+				{
+				// 3, 8
+				__KTRACE_OPT(KPANIC,
+							 Kern::Printf("Error: ((iElementSize * "
+										  "iElementsPerFrame * "
+										  "iFramesPerTransfer) != aCount)"));
+				return KErrArgument;
+				}
+			}
+		}
+	else
+		{
+		if (aTarget.iElementsPerFrame != 0)
+			{
+			// 4, 9
+			__KTRACE_OPT(KPANIC,
+						 Kern::Printf("Error: (iElementsPerFrame != 0)"));
+			return KErrArgument;
+			}
+		if (aTarget.iFramesPerTransfer != 0)
+			{
+			// 5, 10
+			__KTRACE_OPT(KPANIC,
+						 Kern::Printf("Error: (iFramesPerTransfer != 0)"));
+			return KErrArgument;
+			}
+		if (aTarget.iElementsPerPacket != 0)
+			{
+			// 6, 11
+			__KTRACE_OPT(KPANIC,
+						 Kern::Printf("Error: (iElementsPerPacket != 0)"));
+			return KErrArgument;
+			}
+		}
+	return KErrNone;
+	}
+
+
+TInt DDmaRequest::CheckMemFlags(const TDmaTransferConfig& aTarget, TUint aCount) const
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::CheckMemFlags"));
+
+	const TBool mem_target = (aTarget.iFlags & KDmaMemAddr);
+
+	if (mem_target && (aTarget.iFlags & KDmaPhysAddr) && !(aTarget.iFlags & KDmaMemIsContiguous))
+		{
+		// Physical memory address implies contiguous range
+		// 13, 15
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: mem_target && KDmaPhysAddr && !KDmaMemIsContiguous"));
+		return KErrArgument;
+		}
+	else if ((aTarget.iFlags & KDmaMemIsContiguous) && !mem_target)
+		{
+		// Contiguous range implies memory address
+		// 14, 16
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: KDmaMemIsContiguous && !mem_target"));
+		return KErrArgument;
+		}
+	return KErrNone;
+	}
+
+
+// Makes sure an element or frame never straddles two DMA subtransfer
+// fragments. This would be a fragmentation error by the PIL.
+//
+TInt DDmaRequest::AdjustFragmentSize(TUint& aFragSize, TUint aElementSize,
+									 TUint aFrameSize)
+	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::AdjustFragmentSize FragSize=%d ES=%d FS=%d",
+									aFragSize, aElementSize, aFrameSize));
+
+	TUint rem = 0;
+	TInt r = KErrNone;
+
+	while (1)
+		{
+		// If an element size is defined, make sure the fragment size is
+		// greater or equal.
+		if (aElementSize)
+			{
+			if (aFragSize < aElementSize)
+				{
+				__KTRACE_OPT(KPANIC, Kern::Printf("Error: aFragSize < aElementSize"));
+				r = KErrArgument;
+				break;
+				}
+			}
+		// If a frame size is defined, make sure the fragment size is greater
+		// or equal.
+		if (aFrameSize)
+			{
+			if (aFragSize < aFrameSize)
+				{
+				__KTRACE_OPT(KPANIC, Kern::Printf("Error: aFragSize < aFrameSize"));
+				r = KErrArgument;
+				break;
+				}
+			}
+		// If a frame size is defined, make sure the fragment ends on a frame
+		// boundary.
+		if (aFrameSize)
+			{
+			rem = aFragSize % aFrameSize;
+			if (rem != 0)
+				{
+				aFragSize -= rem;
+				// 20, 22
+				__KTRACE_OPT(KDMA, Kern::Printf("aFragSize %% aFrameSize != 0 --> aFragSize = %d",
+												aFragSize));
+				// aFragSize has changed, so we have to do all the checks
+				// again.
+				continue;
+				}
+			}
+		// If an element size is defined, make sure the fragment ends on an
+		// element boundary.
+		if (aElementSize)
+			{
+			rem = aFragSize % aElementSize;
+			if (rem != 0)
+				{
+				aFragSize -= rem;
+				// 21, 23
+				__KTRACE_OPT(KDMA, Kern::Printf("aFragSize %% aElementSize != 0 --> aFragSize = %d",
+												aFragSize));
+				// aFragSize has changed, so we have to do all the checks
+				// again.
+				continue;
+				}
+			}
+		// Done - all checks passed. Let's get out.
+		break;
+		}
+
+	return r;
+	}
+
+
+TUint DDmaRequest::GetTransferCount(const TDmaTransferArgs& aTransferArgs) const
+	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::GetTransferCount"));
+
 	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
+#ifdef _DEBUG
 	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
+#endif	// #ifdef _DEBUG
 
 	TUint count = aTransferArgs.iTransferCount;
 	if (count == 0)
@@ -780,137 +971,117 @@
 		__KTRACE_OPT(KDMA, Kern::Printf("iTransferCount == 0"));
 		count = src.iElementSize * src.iElementsPerFrame *
 			src.iFramesPerTransfer;
+#ifdef _DEBUG
 		const TUint dst_cnt = dst.iElementSize * dst.iElementsPerFrame *
 			dst.iFramesPerTransfer;
 		if (count != dst_cnt)
 			{
+			// 1
 			__KTRACE_OPT(KPANIC, Kern::Printf("Error: (count != dst_cnt)"));
 			return 0;
 			}
+#endif	// #ifdef _DEBUG
 		}
 	else
 		{
 		__KTRACE_OPT(KDMA, Kern::Printf("iTransferCount == %d", count));
+#ifdef _DEBUG
 		// Client shouldn't specify contradictory or incomplete things
-		if (src.iElementSize != 0)
+		if (CheckTransferConfig(src, count) != KErrNone)
 			{
-			if ((count % src.iElementSize) != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: ((count %% src.iElementSize) != 0)"));
-				return 0;
-				}
-			if (src.iElementsPerFrame != 0)
-				{
-				if ((src.iElementSize * src.iElementsPerFrame * src.iFramesPerTransfer) != count)
-					{
-					__KTRACE_OPT(KPANIC,
-								 Kern::Printf("Error: ((src.iElementSize * "
-											  "src.iElementsPerFrame * "
-											  "src.iFramesPerTransfer) != count)"));
-					return 0;
-					}
-				}
-			}
-		else
-			{
-			if (src.iElementsPerFrame != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: (src.iElementsPerFrame != 0)"));
-				return 0;
-				}
-			if (src.iFramesPerTransfer != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: (src.iFramesPerTransfer != 0)"));
-				return 0;
-				}
-			if (src.iElementsPerPacket != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: (src.iElementsPerPacket != 0)"));
-				return 0;
-				}
+			__KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckTransferConfig(src)"));
+			return 0;
 			}
-		if (dst.iElementSize != 0)
+		if (CheckTransferConfig(dst, count) != KErrNone)
 			{
-			if ((count % dst.iElementSize) != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: ((count %% dst.iElementSize) != 0)"));
-				return 0;
-				}
-			if (dst.iElementsPerFrame != 0)
-				{
-				if ((dst.iElementSize * dst.iElementsPerFrame * dst.iFramesPerTransfer) != count)
-					{
-					__KTRACE_OPT(KPANIC,
-								 Kern::Printf("Error: ((dst.iElementSize * "
-											  "dst.iElementsPerFrame * "
-											  "dst.iFramesPerTransfer) != count)"));
-					return 0;
-					}
-				}
+			__KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckTransferConfig(dst)"));
+			return 0;
 			}
-		else
-			{
-			if (dst.iElementsPerFrame != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: (dst.iElementsPerFrame != 0)"));
-				return 0;
-				}
-			if (dst.iFramesPerTransfer != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: (dst.iFramesPerTransfer != 0)"));
-				return 0;
-				}
-			if (dst.iElementsPerPacket != 0)
-				{
-				__KTRACE_OPT(KPANIC,
-							 Kern::Printf("Error: (dst.iElementsPerPacket != 0)"));
-				return 0;
-				}
-			}
+#endif	// #ifdef _DEBUG
 		}
 	return count;
 	}
 
 
+TUint DDmaRequest::GetMaxTransferlength(const TDmaTransferArgs& aTransferArgs, TUint aCount) const
+	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::GetMaxTransferlength"));
+
+	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
+	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
+
+	// Ask the PSL what the maximum length is for a single transfer
+	TUint max_xfer_len = iChannel.MaxTransferLength(src.iFlags, dst.iFlags,
+													aTransferArgs.iPslRequestInfo);
+	if (iMaxTransferSize)
+		{
+		// (User has set a transfer size cap)
+		__KTRACE_OPT(KDMA, Kern::Printf("iMaxTransferSize: %d", iMaxTransferSize));
+		if ((max_xfer_len != 0) && (iMaxTransferSize > max_xfer_len))
+			{
+			// Not really an error, but still...
+			__KTRACE_OPT(KPANIC, Kern::Printf("Warning: iMaxTransferSize > max_xfer_len"));
+			}
+		max_xfer_len = iMaxTransferSize;
+		}
+	else
+		{
+		// (User doesn't care about max transfer size)
+		if (max_xfer_len == 0)
+			{
+			// '0' = no maximum imposed by controller
+			max_xfer_len = aCount;
+			}
+		}
+	__KTRACE_OPT(KDMA, Kern::Printf("max_xfer_len: %d", max_xfer_len));
+
+	// Some sanity checks
+#ifdef _DEBUG
+	if ((max_xfer_len < src.iElementSize) || (max_xfer_len < dst.iElementSize))
+		{
+		// 18
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: max_xfer_len < iElementSize"));
+		return 0;
+		}
+	if ((max_xfer_len < (src.iElementSize * src.iElementsPerFrame)) ||
+		(max_xfer_len < (dst.iElementSize * dst.iElementsPerFrame)))
+		{
+		// 19
+		__KTRACE_OPT(KPANIC,
+					 Kern::Printf("Error: max_xfer_len < (iElementSize * iElementsPerFrame)"));
+		return 0;
+		}
+#endif	// #ifdef _DEBUG
+
+	return max_xfer_len;
+	}
+
+
+// Unified internal fragmentation routine, called by both the old and new
+// exported Fragment() functions.
+//
+// Depending on whether the DMAC uses a single or two separate descriptor
+// chains, this function branches into either FragSym() or FragAsym(), and the
+// latter function further into either FragAsymSrc()/FragAsymDst() or
+// FragBalancedAsym().
+//
 TInt DDmaRequest::Frag(TDmaTransferArgs& aTransferArgs)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::Frag"));
 	__DMA_ASSERTD(!iQueued);
 
-	// Transfer count checks
+	// Transfer count + checks
 	const TUint count = GetTransferCount(aTransferArgs);
 	if (count == 0)
 		{
 		return KErrArgument;
 		}
 
-	const TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
-	const TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
-
-	// Ask the PSL what the maximum length possible for this transfer is
-	TUint max_xfer_len = iChannel.MaxTransferLength(src.iFlags, dst.iFlags,
-													aTransferArgs.iPslRequestInfo);
-	if (iMaxTransferSize)
+	// Max transfer length + checks
+	const TUint max_xfer_len = GetMaxTransferlength(aTransferArgs, count);
+	if (max_xfer_len == 0)
 		{
-		// User has set a size cap
-		__KTRACE_OPT(KDMA, Kern::Printf("iMaxTransferSize != 0"));
-		__DMA_ASSERTA((iMaxTransferSize <= max_xfer_len) || (max_xfer_len == 0));
-		max_xfer_len = iMaxTransferSize;
-		}
-	else
-		{
-		// User doesn't care about max size
-		if (max_xfer_len == 0)
-			{
-			// No maximum imposed by controller
-			max_xfer_len = count;
-			}
+		return KErrArgument;
 		}
 
 	// ISR callback requested?
@@ -920,6 +1091,8 @@
 		// Requesting an ISR callback w/o supplying one?
 		if (!iDmaCb)
 			{
+			// 12
+			__KTRACE_OPT(KPANIC, Kern::Printf("Error: !iDmaCb"));
 			return KErrArgument;
 			}
 		}
@@ -927,8 +1100,21 @@
 	// Set the channel cookie for the PSL
 	aTransferArgs.iChannelCookie = iChannel.PslId();
 
+	// Client shouldn't specify contradictory or invalid things
+	TInt r = CheckMemFlags(aTransferArgs.iSrcConfig, count);
+	if (r != KErrNone)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(src)"));
+		return r;
+		}
+	r =  CheckMemFlags(aTransferArgs.iDstConfig, count);
+	if (r != KErrNone)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: CheckMemFlags(dst)"));
+		return r;
+		}
+
 	// Now the actual fragmentation
-	TInt r;
 	if (iChannel.iDmacCaps->iAsymHwDescriptors)
 		{
 		r = FragAsym(aTransferArgs, count, max_xfer_len);
@@ -951,64 +1137,193 @@
 TInt DDmaRequest::FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount,
 						  TUint aMaxTransferLen)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragSym"));
+
 	TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
 	TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
-
 	const TBool mem_src = (src.iFlags & KDmaMemAddr);
 	const TBool mem_dst = (dst.iFlags & KDmaMemAddr);
 
 	const TUint align_mask_src = iChannel.AddressAlignMask(src.iFlags,
 														   src.iElementSize,
 														   aTransferArgs.iPslRequestInfo);
+	__KTRACE_OPT(KDMA, Kern::Printf("align_mask_src: 0x%x", align_mask_src));
 	const TUint align_mask_dst = iChannel.AddressAlignMask(dst.iFlags,
 														   dst.iElementSize,
 														   aTransferArgs.iPslRequestInfo);
+	__KTRACE_OPT(KDMA, Kern::Printf("align_mask_dst: 0x%x", align_mask_dst));
+
 	// Memory buffers must satisfy alignment constraint
 	__DMA_ASSERTD(!mem_src || ((src.iAddr & align_mask_src) == 0));
 	__DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask_dst) == 0));
 
+	// Max aligned length is used to make sure the beginnings of subtransfers
+	// (i.e. fragments) are correctly aligned.
 	const TUint max_aligned_len = (aMaxTransferLen &
 								   ~(Max(align_mask_src, align_mask_dst)));
+	__KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len));
 	// Client and PSL sane?
 	__DMA_ASSERTD(max_aligned_len > 0);
 
-	FreeDesList();			   // revert any previous fragmentation attempt
+	if (mem_src && mem_dst &&
+		align_mask_src && align_mask_dst &&
+		(align_mask_src != align_mask_dst) &&
+		(!(src.iFlags & KDmaMemIsContiguous) || !(dst.iFlags & KDmaMemIsContiguous)))
+		{
+		// We don't support transfers which satisfy ALL of the following conditions:
+		// 1) from memory to memory,
+		// 2) both sides have address alignment requirements,
+		// 3) those alignment requirements are not the same,
+		// 4) the memory is non-contiguous on at least one end.
+		//
+		// [A 5th condition is that the channel doesn't support fully
+		// asymmetric h/w descriptor lists,
+		// i.e. TDmaChannel::DmacCaps::iAsymHwDescriptors is reported as EFalse
+		// or iBalancedAsymSegments as ETrue. Hence this check is done in
+		// FragSym() and FragBalancedAsym() but not in FragAsym().]
+		//
+		// The reason for this is that fragmentation could be impossible. The
+		// memory layout (page break) on the side with the less stringent
+		// alignment requirement can result in a misaligned target address on
+		// the other side.
+		//
+		// Here is an example:
+		//
+		// src.iAddr =  3964 (0x0F7C), non-contiguous,
+		// align_mask_src = 1 (alignment = 2 bytes)
+		// dst.iAddr = 16384 (0x4000), contiguous,
+		// align_mask_dst = 7 (alignment = 8 bytes)
+		// count = max_xfer_len = 135 bytes
+		// => max_aligned_len = 128 bytes
+		//
+		// Now, suppose MaxPhysSize() returns 132 bytes because src has 132
+		// contiguous bytes to the end of its current mem page.
+		// Trying to fragment this leads to:
+		//
+		// frag_1 = 128 bytes: src reads from 3964 (0x0F7C),
+		//                     dst writes to 16384 (0x4000).
+		// (Fragment 1 uses the max_aligned_len instead of 132 bytes because
+		// otherwise the next fragment would start for the destination at
+		// dst.iAddr + 132 = 16516 (0x4084), which is not 8-byte aligned.)
+		//
+		// frag_2 = 4 bytes: src reads from 4092 (0x0FFC),
+		//                   dst writes to 16512 (0x4080).
+		// (Fragment 2 uses just 4 bytes instead of the remaining 7 bytes
+		// because there is a memory page break on the source side after 4 bytes.)
+		//
+		// frag_3 = 3 bytes: src reads from 4096 (0x1000),
+		//                   dst writes to 16516 (0x4084).
+		//
+		// And there's the problem: the start address of frag_3 is going to be
+		// misaligned for the destination side - it's not 8-byte aligned!
+		//
+		// 17
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: Different alignments for src & dst"
+										  " + non-contiguous target(s)"));
+		return KErrArgument;
+		}
+
 	TInt r;
+	// Revert any previous fragmentation attempt
+	FreeDesList();
 	do
 		{
 		// Allocate fragment
 		r = ExpandDesList(/*1*/);
 		if (r != KErrNone)
 			{
-			FreeDesList();
 			break;
 			}
 		// Compute fragment size
 		TUint c = Min(aMaxTransferLen, aCount);
-		if (mem_src && !(src.iFlags & KDmaPhysAddr))
+		__KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c));
+
+		// SRC
+		if (mem_src && !(src.iFlags & KDmaMemIsContiguous))
 			{
-			__KTRACE_OPT(KDMA, Kern::Printf("mem_src && !(src.iFlags & KDmaPhysAddr)"));
-			// @@@ Should also take into account (src.iFlags & KDmaMemIsContiguous)!
 			c = MaxPhysSize(src.iAddr, c);
+			__KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(src.iAddr, c) = %d", c));
 			}
-		if (mem_dst && !(dst.iFlags & KDmaPhysAddr))
+
+		// DST
+		if (mem_dst && !(dst.iFlags & KDmaMemIsContiguous))
 			{
-			__KTRACE_OPT(KDMA, Kern::Printf("mem_dst && !(dst.iFlags & KDmaPhysAddr)"));
-			// @@@ Should also take into account (dst.iFlags & KDmaMemIsContiguous)!
 			c = MaxPhysSize(dst.iAddr, c);
+			__KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(dst.iAddr, c) = %d", c));
 			}
+
+		// SRC & DST
 		if ((mem_src || mem_dst) && (c < aCount) && (c > max_aligned_len))
 			{
 			// This is not the last fragment of a transfer to/from memory.
 			// We must round down the fragment size so the next one is
 			// correctly aligned.
-			__KTRACE_OPT(KDMA, Kern::Printf("(mem_src || mem_dst) && (c < aCount) && (c > max_aligned_len)"));
 			c = max_aligned_len;
+			__KTRACE_OPT(KDMA, Kern::Printf("c = max_aligned_len = %d", c));
+			//
+			// But can this condition actually occur if src and dst are
+			// properly aligned to start with?
+			//
+			// If we disallow unequal alignment requirements in connection with
+			// non-contiguous memory buffers (see the long comment above in
+			// this function for why) and if both target addresses are
+			// correctly aligned at the beginning of the transfer then it
+			// doesn't seem possible to end up with a fragment which is not
+			// quite the total remaining size (c < aCount) but still larger
+			// than the greatest aligned length (c > max_aligned_len).
+			//
+			// That's because address alignment values are always a power of
+			// two (at least that's what we assume - otherwise
+			// AddressAlignMask() doesn't work), and memory page sizes are also
+			// always a power of two and hence a multiple of the alignment
+			// value (as long as the alignment is not greater than the page
+			// size, which seems a reasonable assumption regardless of the
+			// actual page size). So if we start properly aligned anywhere in a
+			// memory page then the number of bytes to the end of that page is
+			// always a multiple of the aligment value - there's no remainder.
+			//
+			// So let's see if we ever hit this assertion:
+			Kern::Printf("Unexpected: (mem_src || mem_dst) && (c < aCount) && (c > max_aligned_len)");
+			__DMA_ASSERTA(EFalse);
 			}
 
-		// TODO: Make sure an element or frame on neither src or dst side
-		// (which can be of different sizes) never straddles a DMA subtransfer.
-		// (This would be a fragmentation error by the PIL.)
+		// If this is not the last fragment...
+		if (c < aCount)
+			{
+			const TUint es_src = src.iElementSize;
+			const TUint es_dst = dst.iElementSize;
+			const TUint fs_src = es_src * src.iElementsPerFrame;
+			const TUint fs_dst = es_dst * dst.iElementsPerFrame;
+			TUint c_prev;
+			do
+				{
+				c_prev = c;
+				// If fs_src is !0 then es_src must be !0 as well (see
+				// CheckTransferConfig).
+				if (es_src)
+					{
+					r = AdjustFragmentSize(c, es_src, fs_src);
+					if (r != KErrNone)
+						{
+						break;							// while (c != c_prev);
+						}
+					}
+				// If fs_dst is !0 then es_dst must be !0 as well (see
+				// CheckTransferConfig).
+				if (es_dst)
+					{
+					r = AdjustFragmentSize(c, es_dst, fs_dst);
+					if (r != KErrNone)
+						{
+						break;							// while (c != c_prev);
+						}
+					}
+				} while (c != c_prev);
+			if (r != KErrNone)
+				{
+				break;									 // while (aCount > 0);
+				}
+			}
 
 		// Set transfer count for the PSL
 		aTransferArgs.iTransferCount = c;
@@ -1018,18 +1333,24 @@
 		r = iChannel.iController->InitDes(*iLastHdr, aTransferArgs);
 		if (r != KErrNone)
 			{
-			FreeDesList();
 			break;
 			}
 		// Update for next iteration
 		aCount -= c;
 		if (mem_src)
+			{
 			src.iAddr += c;
+			}
 		if (mem_dst)
+			{
 			dst.iAddr += c;
+			}
+		} while (aCount > 0);
+
+	if (r != KErrNone)
+		{
+		FreeDesList();
 		}
-	while (aCount > 0);
-
 	return r;
 	}
 
@@ -1037,7 +1358,20 @@
 TInt DDmaRequest::FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount,
 						   TUint aMaxTransferLen)
 	{
-	TInt r = FragAsymSrc(aTransferArgs, aCount, aMaxTransferLen);
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragAsym"));
+
+	TInt r;
+	if (iChannel.iDmacCaps->iBalancedAsymSegments)
+		{
+		r = FragBalancedAsym(aTransferArgs, aCount, aMaxTransferLen);
+		if (r != KErrNone)
+			{
+			FreeSrcDesList();
+			FreeDstDesList();
+			}
+		return r;
+		}
+	r = FragAsymSrc(aTransferArgs, aCount, aMaxTransferLen);
 	if (r != KErrNone)
 		{
 		FreeSrcDesList();
@@ -1056,21 +1390,29 @@
 TInt DDmaRequest::FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount,
 							  TUint aMaxTransferLen)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragAsymSrc"));
+
 	TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
-
 	const TBool mem_src = (src.iFlags & KDmaMemAddr);
 
 	const TUint align_mask = iChannel.AddressAlignMask(src.iFlags,
 													   src.iElementSize,
 													   aTransferArgs.iPslRequestInfo);
+	__KTRACE_OPT(KDMA, Kern::Printf("align_mask: 0x%x", align_mask));
+
 	// Memory buffers must satisfy alignment constraint
 	__DMA_ASSERTD(!mem_src || ((src.iAddr & align_mask) == 0));
 
+	// Max aligned length is used to make sure the beginnings of subtransfers
+	// (i.e. fragments) are correctly aligned.
 	const TUint max_aligned_len = (aMaxTransferLen & ~align_mask);
-	__DMA_ASSERTD(max_aligned_len > 0);				  // bug in PSL if not true
-
+	__KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len));
+	// Client and PSL sane?
+	__DMA_ASSERTD(max_aligned_len > 0);
+
+	TInt r;
+	// Revert any previous fragmentation attempt
 	FreeSrcDesList();
-	TInt r;
 	do
 		{
 		// Allocate fragment
@@ -1081,19 +1423,62 @@
 			}
 		// Compute fragment size
 		TUint c = Min(aMaxTransferLen, aCount);
-		if (mem_src && !(src.iFlags & KDmaPhysAddr))
+		__KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c));
+
+		if (mem_src && !(src.iFlags & KDmaMemIsContiguous))
 			{
-			__KTRACE_OPT(KDMA, Kern::Printf("mem_src && !(src.iFlags & KDmaPhysAddr)"));
 			c = MaxPhysSize(src.iAddr, c);
+			__KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(src.iAddr, c) = %d", c));
 			}
+
 		if (mem_src && (c < aCount) && (c > max_aligned_len))
 			{
 			// This is not the last fragment of a transfer from memory.
 			// We must round down the fragment size so the next one is
 			// correctly aligned.
-			__KTRACE_OPT(KDMA, Kern::Printf("mem_src && (c < aCount) && (c > max_aligned_len)"));
-			c = max_aligned_len;
+			__KTRACE_OPT(KDMA, Kern::Printf("c = max_aligned_len = %d", c));
+			//
+			// But can this condition actually occur if src is properly aligned
+			// to start with?
+			//
+			// If the target address is correctly aligned at the beginning of
+			// the transfer then it doesn't seem possible to end up with a
+			// fragment which is not quite the total remaining size (c <
+			// aCount) but still larger than the greatest aligned length (c >
+			// max_aligned_len).
+			//
+			// That's because address alignment values are always a power of
+			// two (at least that's what we assume - otherwise
+			// AddressAlignMask() doesn't work), and memory page sizes are also
+			// always a power of two and hence a multiple of the alignment
+			// value (as long as the alignment is not greater than the page
+			// size, which seems a reasonable assumption regardless of the
+			// actual page size). So if we start properly aligned anywhere in a
+			// memory page then the number of bytes to the end of that page is
+			// always a multiple of the aligment value - there's no remainder.
+			//
+			// So let's see if we ever hit this assertion:
+			Kern::Printf("Unexpected: mem_src && (c < aCount) && (c > max_aligned_len)");
+			__DMA_ASSERTA(EFalse);
 			}
+
+		// If this is not the last fragment...
+		if (c < aCount)
+			{
+			const TUint es = src.iElementSize;
+			const TUint fs = es * src.iElementsPerFrame;
+			// If fs is !0 then es must be !0 as well (see
+			// CheckTransferConfig).
+			if (es)
+				{
+				r = AdjustFragmentSize(c, es, fs);
+				if (r != KErrNone)
+					{
+					break;								 // while (aCount > 0);
+					}
+				}
+			}
+
 		// Set transfer count for the PSL
 		aTransferArgs.iTransferCount = c;
 		__KTRACE_OPT(KDMA, Kern::Printf("this fragm.: %d (0x%x) total remain.: %d (0x%x)",
@@ -1107,9 +1492,10 @@
 		// Update for next iteration
 		aCount -= c;
 		if (mem_src)
+			{
 			src.iAddr += c;
-		}
-	while (aCount > 0);
+			}
+		} while (aCount > 0);
 
 	return r;
 	}
@@ -1118,21 +1504,29 @@
 TInt DDmaRequest::FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount,
 							  TUint aMaxTransferLen)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragAsymDst"));
+
 	TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
-
 	const TBool mem_dst = (dst.iFlags & KDmaMemAddr);
 
 	const TUint align_mask = iChannel.AddressAlignMask(dst.iFlags,
 													   dst.iElementSize,
 													   aTransferArgs.iPslRequestInfo);
+	__KTRACE_OPT(KDMA, Kern::Printf("align_mask: 0x%x", align_mask));
+
 	// Memory buffers must satisfy alignment constraint
 	__DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask) == 0));
 
+	// Max aligned length is used to make sure the beginnings of subtransfers
+	// (i.e. fragments) are correctly aligned.
 	const TUint max_aligned_len = (aMaxTransferLen & ~align_mask);
-	__DMA_ASSERTD(max_aligned_len > 0);				  // bug in PSL if not true
-
+	__KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len));
+	// Client and PSL sane?
+	__DMA_ASSERTD(max_aligned_len > 0);
+
+	TInt r;
+	// Revert any previous fragmentation attempt
 	FreeDstDesList();
-	TInt r;
 	do
 		{
 		// Allocate fragment
@@ -1143,19 +1537,62 @@
 			}
 		// Compute fragment size
 		TUint c = Min(aMaxTransferLen, aCount);
-		if (mem_dst && !(dst.iFlags & KDmaPhysAddr))
+		__KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c));
+
+		if (mem_dst && !(dst.iFlags & KDmaMemIsContiguous))
 			{
-			__KTRACE_OPT(KDMA, Kern::Printf("mem_dst && !(dst.iFlags & KDmaPhysAddr)"));
 			c = MaxPhysSize(dst.iAddr, c);
+			__KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(dst.iAddr, c) = %d", c));
 			}
+
 		if (mem_dst && (c < aCount) && (c > max_aligned_len))
 			{
 			// This is not the last fragment of a transfer to memory.
 			// We must round down the fragment size so the next one is
 			// correctly aligned.
-			__KTRACE_OPT(KDMA, Kern::Printf("mem_dst && (c < aCount) && (c > max_aligned_len)"));
-			c = max_aligned_len;
+			__KTRACE_OPT(KDMA, Kern::Printf("c = max_aligned_len = %d", c));
+			//
+			// But can this condition actually occur if dst is properly aligned
+			// to start with?
+			//
+			// If the target address is correctly aligned at the beginning of
+			// the transfer then it doesn't seem possible to end up with a
+			// fragment which is not quite the total remaining size (c <
+			// aCount) but still larger than the greatest aligned length (c >
+			// max_aligned_len).
+			//
+			// That's because address alignment values are always a power of
+			// two (at least that's what we assume - otherwise
+			// AddressAlignMask() doesn't work), and memory page sizes are also
+			// always a power of two and hence a multiple of the alignment
+			// value (as long as the alignment is not greater than the page
+			// size, which seems a reasonable assumption regardless of the
+			// actual page size). So if we start properly aligned anywhere in a
+			// memory page then the number of bytes to the end of that page is
+			// always a multiple of the aligment value - there's no remainder.
+			//
+			// So let's see if we ever hit this assertion:
+			Kern::Printf("Unexpected: mem_dst && (c < aCount) && (c > max_aligned_len)");
+			__DMA_ASSERTA(EFalse);
 			}
+
+		// If this is not the last fragment...
+		if (c < aCount)
+			{
+			const TUint es = dst.iElementSize;
+			const TUint fs = es * dst.iElementsPerFrame;
+			// If fs is !0 then es must be !0 as well (see
+			// CheckTransferConfig).
+			if (es)
+				{
+				r = AdjustFragmentSize(c, es, fs);
+				if (r != KErrNone)
+					{
+					break;								 // while (aCount > 0);
+					}
+				}
+			}
+
 		// Set transfer count for the PSL
 		aTransferArgs.iTransferCount = c;
 		__KTRACE_OPT(KDMA, Kern::Printf("this fragm.: %d (0x%x) total remain.: %d (0x%x)",
@@ -1169,7 +1606,238 @@
 		// Update for next iteration
 		aCount -= c;
 		if (mem_dst)
+			{
 			dst.iAddr += c;
+			}
+		}
+	while (aCount > 0);
+
+	return r;
+	}
+
+
+TInt DDmaRequest::FragBalancedAsym(TDmaTransferArgs& aTransferArgs, TUint aCount,
+								   TUint aMaxTransferLen)
+	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragBalancedAsym"));
+
+	TDmaTransferConfig& src = aTransferArgs.iSrcConfig;
+	TDmaTransferConfig& dst = aTransferArgs.iDstConfig;
+	const TBool mem_src = (src.iFlags & KDmaMemAddr);
+	const TBool mem_dst = (dst.iFlags & KDmaMemAddr);
+
+	const TUint align_mask_src = iChannel.AddressAlignMask(src.iFlags,
+														   src.iElementSize,
+														   aTransferArgs.iPslRequestInfo);
+	__KTRACE_OPT(KDMA, Kern::Printf("align_mask_src: 0x%x", align_mask_src));
+	const TUint align_mask_dst = iChannel.AddressAlignMask(dst.iFlags,
+														   dst.iElementSize,
+														   aTransferArgs.iPslRequestInfo);
+	__KTRACE_OPT(KDMA, Kern::Printf("align_mask_dst: 0x%x", align_mask_dst));
+
+	// Memory buffers must satisfy alignment constraint
+	__DMA_ASSERTD(!mem_src || ((src.iAddr & align_mask_src) == 0));
+	__DMA_ASSERTD(!mem_dst || ((dst.iAddr & align_mask_dst) == 0));
+
+	// Max aligned length is used to make sure the beginnings of subtransfers
+	// (i.e. fragments) are correctly aligned.
+	const TUint max_aligned_len = (aMaxTransferLen &
+								   ~(Max(align_mask_src, align_mask_dst)));
+	__KTRACE_OPT(KDMA, Kern::Printf("max_aligned_len: %d", max_aligned_len));
+	// Client and PSL sane?
+	__DMA_ASSERTD(max_aligned_len > 0);
+
+	if (mem_src && mem_dst &&
+		align_mask_src && align_mask_dst &&
+		(align_mask_src != align_mask_dst) &&
+		(!(src.iFlags & KDmaMemIsContiguous) || !(dst.iFlags & KDmaMemIsContiguous)))
+		{
+		// We don't support transfers which satisfy ALL of the following conditions:
+		// 1) from memory to memory,
+		// 2) both sides have address alignment requirements,
+		// 3) those alignment requirements are not the same,
+		// 4) the memory is non-contiguous on at least one end.
+		//
+		// [A 5th condition is that the channel doesn't support fully
+		// asymmetric h/w descriptor lists,
+		// i.e. TDmaChannel::DmacCaps::iAsymHwDescriptors is reported as EFalse
+		// or iBalancedAsymSegments as ETrue. Hence this check is done in
+		// FragSym() and FragBalancedAsym() but not in FragAsym().]
+		//
+		// The reason for this is that fragmentation could be impossible. The
+		// memory layout (page break) on the side with the less stringent
+		// alignment requirement can result in a misaligned target address on
+		// the other side.
+		//
+		// Here is an example:
+		//
+		// src.iAddr =  3964 (0x0F7C), non-contiguous,
+		// align_mask_src = 1 (alignment = 2 bytes)
+		// dst.iAddr = 16384 (0x4000), contiguous,
+		// align_mask_dst = 7 (alignment = 8 bytes)
+		// count = max_xfer_len = 135 bytes
+		// => max_aligned_len = 128 bytes
+		//
+		// Now, suppose MaxPhysSize() returns 132 bytes because src has 132
+		// contiguous bytes to the end of its current mem page.
+		// Trying to fragment this leads to:
+		//
+		// frag_1 = 128 bytes: src reads from 3964 (0x0F7C),
+		//                     dst writes to 16384 (0x4000).
+		// (Fragment 1 uses the max_aligned_len instead of 132 bytes because
+		// otherwise the next fragment would start for the destination at
+		// dst.iAddr + 132 = 16516 (0x4084), which is not 8-byte aligned.)
+		//
+		// frag_2 = 4 bytes: src reads from 4092 (0x0FFC),
+		//                   dst writes to 16512 (0x4080).
+		// (Fragment 2 uses just 4 bytes instead of the remaining 7 bytes
+		// because there is a memory page break on the source side after 4 bytes.)
+		//
+		// frag_3 = 3 bytes: src reads from 4096 (0x1000),
+		//                   dst writes to 16516 (0x4084).
+		//
+		// And there's the problem: the start address of frag_3 is going to be
+		// misaligned for the destination side - it's not 8-byte aligned!
+		//
+		__KTRACE_OPT(KPANIC, Kern::Printf("Error: Different alignments for src & dst"
+										  " + non-contiguous target(s)"));
+		return KErrArgument;
+		}
+
+	TInt r;
+	// Revert any previous fragmentation attempt
+	FreeSrcDesList();
+	FreeDstDesList();
+	do
+		{
+		// Allocate fragment
+		r = ExpandSrcDesList(/*1*/);
+		if (r != KErrNone)
+			{
+			break;
+			}
+		r = ExpandDstDesList(/*1*/);
+		if (r != KErrNone)
+			{
+			break;
+			}
+		// Compute fragment size
+		TUint c = Min(aMaxTransferLen, aCount);
+		__KTRACE_OPT(KDMA, Kern::Printf("c = Min(aMaxTransferLen, aCount) = %d", c));
+
+		// SRC
+		if (mem_src && !(src.iFlags & KDmaMemIsContiguous))
+			{
+			c = MaxPhysSize(src.iAddr, c);
+			__KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(src.iAddr, c) = %d", c));
+			}
+
+		// DST
+		if (mem_dst && !(dst.iFlags & KDmaMemIsContiguous))
+			{
+			c = MaxPhysSize(dst.iAddr, c);
+			__KTRACE_OPT(KDMA, Kern::Printf("c = MaxPhysSize(dst.iAddr, c) = %d", c));
+			}
+
+		// SRC & DST
+		if ((mem_src || mem_dst) && (c < aCount) && (c > max_aligned_len))
+			{
+			// This is not the last fragment of a transfer to/from memory.
+			// We must round down the fragment size so the next one is
+			// correctly aligned.
+			c = max_aligned_len;
+			__KTRACE_OPT(KDMA, Kern::Printf("c = max_aligned_len = %d", c));
+			//
+			// But can this condition actually occur if src and dst are
+			// properly aligned to start with?
+			//
+			// If we disallow unequal alignment requirements in connection with
+			// non-contiguous memory buffers (see the long comment above in
+			// this function for why) and if both target addresses are
+			// correctly aligned at the beginning of the transfer then it
+			// doesn't seem possible to end up with a fragment which is not
+			// quite the total remaining size (c < aCount) but still larger
+			// than the greatest aligned length (c > max_aligned_len).
+			//
+			// That's because address alignment values are always a power of
+			// two (at least that's what we assume - otherwise
+			// AddressAlignMask() doesn't work), and memory page sizes are also
+			// always a power of two and hence a multiple of the alignment
+			// value (as long as the alignment is not greater than the page
+			// size, which seems a reasonable assumption regardless of the
+			// actual page size). So if we start properly aligned anywhere in a
+			// memory page then the number of bytes to the end of that page is
+			// always a multiple of the aligment value - there's no remainder.
+			//
+			// So let's see if we ever hit this assertion:
+			Kern::Printf("Unexpected: (mem_src || mem_dst) && (c < aCount) && (c > max_aligned_len)");
+			__DMA_ASSERTA(EFalse);
+			}
+
+		// If this is not the last fragment...
+		if (c < aCount)
+			{
+			const TUint es_src = src.iElementSize;
+			const TUint es_dst = dst.iElementSize;
+			const TUint fs_src = es_src * src.iElementsPerFrame;
+			const TUint fs_dst = es_dst * dst.iElementsPerFrame;
+			TUint c_prev;
+			do
+				{
+				c_prev = c;
+				// If fs_src is !0 then es_src must be !0 as well (see
+				// CheckTransferConfig).
+				if (es_src)
+					{
+					r = AdjustFragmentSize(c, es_src, fs_src);
+					if (r != KErrNone)
+						{
+						break;							// while (c != c_prev);
+						}
+					}
+				// If fs_dst is !0 then es_dst must be !0 as well (see
+				// CheckTransferConfig).
+				if (es_dst)
+					{
+					r = AdjustFragmentSize(c, es_dst, fs_dst);
+					if (r != KErrNone)
+						{
+						break;							// while (c != c_prev);
+						}
+					}
+				} while (c != c_prev);
+			if (r != KErrNone)
+				{
+				break;									 // while (aCount > 0);
+				}
+			}
+
+		// Set transfer count for the PSL
+		aTransferArgs.iTransferCount = c;
+		__KTRACE_OPT(KDMA, Kern::Printf("this fragm.: %d (0x%x) total remain.: %d (0x%x)",
+										c, c, aCount, aCount));
+		// Initialise SRC fragment
+		r = iChannel.iController->InitSrcHwDes(*iSrcLastHdr, aTransferArgs);
+		if (r != KErrNone)
+			{
+			break;
+			}
+		// Initialise DST fragment
+		r = iChannel.iController->InitDstHwDes(*iDstLastHdr, aTransferArgs);
+		if (r != KErrNone)
+			{
+			break;
+			}
+		// Update for next iteration
+		aCount -= c;
+		if (mem_src)
+			{
+			src.iAddr += c;
+			}
+		if (mem_dst)
+			{
+			dst.iAddr += c;
+			}
 		}
 	while (aCount > 0);
 
@@ -1180,7 +1848,15 @@
 EXPORT_C TInt DDmaRequest::Queue()
 	{
 	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::Queue thread %O", &Kern::CurrentThread()));
-	__DMA_ASSERTD(iDesCount > 0);	// Not configured? Call Fragment() first!
+	// Not configured? Call Fragment() first!
+	if (iChannel.iDmacCaps->iAsymHwDescriptors)
+		{
+		__DMA_ASSERTD((iSrcDesCount < 0) && (iDstDesCount < 0));
+		}
+	else
+		{
+		__DMA_ASSERTD(iDesCount > 0);
+		}
 	__DMA_ASSERTD(!iQueued);
 
 	// Append request to queue and link new descriptor list to existing one.
@@ -1270,18 +1946,21 @@
 
 EXPORT_C TInt DDmaRequest::ExpandDesList(TInt aCount)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::ExpandDesList aCount=%d", aCount));
 	return ExpandDesList(aCount, iDesCount, iFirstHdr, iLastHdr);
 	}
 
 
 EXPORT_C TInt DDmaRequest::ExpandSrcDesList(TInt aCount)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::ExpandSrcDesList"));
 	return ExpandDesList(aCount, iSrcDesCount, iSrcFirstHdr, iSrcLastHdr);
 	}
 
 
 EXPORT_C TInt DDmaRequest::ExpandDstDesList(TInt aCount)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::ExpandDstDesList"));
 	return ExpandDesList(aCount, iDstDesCount, iDstFirstHdr, iDstLastHdr);
 	}
 
@@ -1290,6 +1969,7 @@
 								SDmaDesHdr*& aFirstHdr,
 								SDmaDesHdr*& aLastHdr)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::ExpandDesList"));
 	__DMA_ASSERTD(!iQueued);
 	__DMA_ASSERTD(aCount > 0);
 
@@ -1340,24 +2020,28 @@
 
 EXPORT_C void DDmaRequest::FreeDesList()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FreeDesList"));
 	FreeDesList(iDesCount, iFirstHdr, iLastHdr);
 	}
 
 
 EXPORT_C void DDmaRequest::FreeSrcDesList()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FreeSrcDesList"));
 	FreeDesList(iSrcDesCount, iSrcFirstHdr, iSrcLastHdr);
 	}
 
 
 EXPORT_C void DDmaRequest::FreeDstDesList()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FreeDstDesList"));
 	FreeDesList(iDstDesCount, iDstFirstHdr, iDstLastHdr);
 	}
 
 
 void DDmaRequest::FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FreeDesList count=%d", aDesCount));
 	__DMA_ASSERTD(!iQueued);
 
 	if (aDesCount > 0)
@@ -1367,13 +2051,20 @@
 		const SDmaDesHdr* hdr = aFirstHdr;
 		while (hdr)
 			{
+			__DMA_ASSERTD(c.IsValidHdr(hdr));
+
+			// This (potential) PSL call doesn't follow the "overhead
+			// principle", and something should be done about this.
 			c.ClearHwDes(*hdr);
 			hdr = hdr->iNext;
 			};
+
 		c.Wait();
+		__DMA_ASSERTD(c.IsValidHdr(c.iFreeHdr));
 		aLastHdr->iNext = c.iFreeHdr;
 		c.iFreeHdr = aFirstHdr;
 		c.Signal();
+
 		aFirstHdr = aLastHdr = NULL;
 		aDesCount = 0;
 		}
@@ -1382,6 +2073,8 @@
 
 EXPORT_C void DDmaRequest::EnableSrcElementCounting(TBool /*aResetElementCount*/)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::EnableSrcElementCounting"));
+
 	// Not yet implemented.
 	return;
 	}
@@ -1389,6 +2082,8 @@
 
 EXPORT_C void DDmaRequest::EnableDstElementCounting(TBool /*aResetElementCount*/)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::EnableDstElementCounting"));
+
 	// Not yet implemented.
 	return;
 	}
@@ -1396,6 +2091,8 @@
 
 EXPORT_C void DDmaRequest::DisableSrcElementCounting()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::DisableSrcElementCounting"));
+
 	// Not yet implemented.
 	return;
 	}
@@ -1403,6 +2100,8 @@
 
 EXPORT_C void DDmaRequest::DisableDstElementCounting()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::DisableDstElementCounting"));
+
 	// Not yet implemented.
 	return;
 	}
@@ -1410,6 +2109,8 @@
 
 EXPORT_C TUint32 DDmaRequest::TotalNumSrcElementsTransferred()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::TotalNumSrcElementsTransferred"));
+
 	// Not yet implemented.
 
 	// So far largely bogus code (just to touch some symbols)...
@@ -1432,6 +2133,8 @@
 
 EXPORT_C TUint32 DDmaRequest::TotalNumDstElementsTransferred()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::TotalNumDstElementsTransferred"));
+
 	// Not yet implemented.
 	return iTotalNumDstElementsTransferred;
 	}
@@ -1439,24 +2142,28 @@
 
 EXPORT_C TInt DDmaRequest::FragmentCount()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragmentCount"));
 	return FragmentCount(iFirstHdr);
 	}
 
 
 EXPORT_C TInt DDmaRequest::SrcFragmentCount()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::SrcFragmentCount"));
 	return FragmentCount(iSrcFirstHdr);
 	}
 
 
 EXPORT_C TInt DDmaRequest::DstFragmentCount()
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::DstFragmentCount"));
 	return FragmentCount(iDstFirstHdr);
 	}
 
 
 TInt DDmaRequest::FragmentCount(const SDmaDesHdr* aHdr)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::FragmentCount aHdr=0x%08x", aHdr));
 	TInt count = 0;
 	for (const SDmaDesHdr* pH = aHdr; pH != NULL; pH = pH->iNext)
 		{
@@ -1472,8 +2179,18 @@
 inline void DDmaRequest::OnDeque()
 	{
 	iQueued = EFalse;
-	iLastHdr->iNext = NULL;
-	iChannel.DoUnlink(*iLastHdr);
+	if (iChannel.iDmacCaps->iAsymHwDescriptors)
+		{
+		iSrcLastHdr->iNext = NULL;
+		iDstLastHdr->iNext = NULL;
+		iChannel.DoUnlink(*iSrcLastHdr);
+		iChannel.DoUnlink(*iDstLastHdr);
+		}
+	else
+		{
+		iLastHdr->iNext = NULL;
+		iChannel.DoUnlink(*iLastHdr);
+		}
 	}
 
 
@@ -1508,6 +2225,10 @@
 			__DMA_ASSERTD(iChannel.iController->IsValidHdr(iDstFirstHdr));
 			__DMA_ASSERTD(iChannel.iController->IsValidHdr(iDstLastHdr));
 			}
+		if (iChannel.iDmacCaps->iBalancedAsymSegments)
+			{
+			__DMA_ASSERTD(iSrcDesCount == iDstDesCount);
+			}
 		}
 	else
 		{
@@ -1554,7 +2275,7 @@
 	  iRedoRequest(EFalse),
 	  iIsrCbRequest(EFalse)
 	{
-	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::TDmaChannel"));
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::TDmaChannel =0x%08X", this));
 	__DMA_INVARIANT();
 	}
 
@@ -1566,7 +2287,12 @@
 	{
 	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Open thread %O", &Kern::CurrentThread()));
 
-	__DMA_ASSERTD(aInfo.iDesCount >= 1);
+	if (aInfo.iDesCount < 1)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("DMA channel failed to open: iDescount<1"));
+		return KErrArgument;
+		}
+
 	__DMA_ASSERTD(aInfo.iPriority <= KDmaPriority8);
 	__DMA_ASSERTD(aInfo.iDfcQ != NULL);
 	__DMA_ASSERTD(aInfo.iDfcPriority < KNumDfcPriorities);
@@ -1760,11 +2486,10 @@
 										  TUint32 aPslRequestInfo,
 										  TBool aIsrCb)
 	{
-	__KTRACE_OPT(KDMA,
-				 Kern::Printf("TDmaChannel::IsrRedoRequest src=0x%08x, "
-							  "dst=0x%08x, count=%d, pslInfo=0x%08x, isrCb=%d",
-							  aSrcAddr, aDstAddr, aTransferCount, aPslRequestInfo,
-							  aIsrCb));
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::IsrRedoRequest src=0x%08X, "
+									"dst=0x%08X, count=%d, pslInfo=0x%08X, isrCb=%d",
+									aSrcAddr, aDstAddr, aTransferCount, aPslRequestInfo,
+									aIsrCb));
 	// Function needs to be called in ISR context.
 	__DMA_ASSERTD(NKern::CurrentContext() == NKern::EInterrupt);
 
@@ -1775,7 +2500,7 @@
 	if ((aSrcAddr != KPhysAddrInvalid) && (aSrcAddr == aDstAddr))
 		{
 		__KTRACE_OPT(KPANIC,
-					 Kern::Printf("Error: Updating src & dst to same address: 0x%08x",
+					 Kern::Printf("Error: Updating src & dst to same address: 0x%08X",
 								  aSrcAddr));
 		return KErrArgument;
 		}
@@ -1791,8 +2516,12 @@
 
 	if (iDmacCaps->iAsymHwDescriptors)
 		{
-		// We don't allow multiple-descriptor chains to be updated here
+		// We don't allow multiple-descriptor chains to be updated here.
+		// That we just panic (instead of returning an error), and also only in
+		// the UDEB case (instead of always) is not ideal, but done here in the
+		// interest of performance.
 		__DMA_ASSERTD((pCurReq->iSrcDesCount == 1) && (pCurReq->iDstDesCount == 1));
+
 		// Adjust parameters if necessary (asymmetrical s/g variety)
 		const SDmaDesHdr* const pSrcFirstHdr = pCurReq->iSrcFirstHdr;
 		if ((aSrcAddr != KPhysAddrInvalid) || aTransferCount || aPslRequestInfo)
@@ -1821,8 +2550,12 @@
 		}
 	else
 		{
-		// We don't allow multiple-descriptor chains to be updated here
+		// We don't allow a multiple-descriptor chain to be updated here.
+		// That we just panic (instead of returning an error), and also only in
+		// the UDEB case (instead of always) is not ideal, but done here in the
+		// interest of performance.
 		__DMA_ASSERTD(pCurReq->iDesCount == 1);
+
 		// Adjust parameters if necessary (symmetrical s/g and non-s/g variety)
 		const SDmaDesHdr* const pFirstHdr = pCurReq->iFirstHdr;
 		if ((aSrcAddr != KPhysAddrInvalid) || (aDstAddr != KPhysAddrInvalid) ||
@@ -1853,18 +2586,21 @@
 
 EXPORT_C TInt TDmaChannel::FailNext(TInt /*aFragmentCount*/)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::FailNext"));
 	return iController->FailNext(*this);
 	}
 
 
 EXPORT_C TInt TDmaChannel::MissNextInterrupts(TInt aInterruptCount)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::MissNextInterrupts"));
 	return iController->MissNextInterrupts(*this, aInterruptCount);
 	}
 
 
 EXPORT_C TInt TDmaChannel::Extension(TInt aCmd, TAny* aArg)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Extension"));
 	return iController->Extension(*this, aCmd, aArg);
 	}
 
@@ -1874,6 +2610,7 @@
 //
 EXPORT_C TInt TDmaChannel::StaticExtension(TInt aCmd, TAny* aArg)
 	{
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::StaticExtension"));
 	return DmaChannelMgr::StaticExtension(aCmd, aArg);
 	}
 
@@ -1932,7 +2669,7 @@
 		{
 		--count;
 
-		__DMA_ASSERTD(!iReqQ.IsEmpty());
+		__DMA_ASSERTA(!iReqQ.IsEmpty());
 
 		// If an error occurred it must have been reported on the last
 		// interrupt since transfers are suspended after an error.
@@ -1945,12 +2682,30 @@
 			{
 			// Update state machine, current fragment, completed fragment and
 			// tell the DMAC to transfer the next fragment if necessary.
-			SDmaDesHdr* pCompletedHdr = NULL;
-			DoDfc(const_cast<const DDmaRequest&>(*pCurReq), pCompletedHdr);
-
+			TBool complete;
+			if (iDmacCaps->iAsymHwDescriptors)
+				{
+				SDmaDesHdr* pCompletedSrcHdr = NULL;
+				SDmaDesHdr* pCompletedDstHdr = NULL;
+				DoDfc(const_cast<const DDmaRequest&>(*pCurReq),
+					  pCompletedSrcHdr, pCompletedDstHdr);
+				// We don't support asymmetrical ISR notifications and request
+				// completions yet, hence we can do the following assert test
+				// here; also 'complete' is determined equally by either the
+				// SRC or DST side.
+				__DMA_ASSERTD(!LOGICAL_XOR((pCompletedSrcHdr == pCurReq->iSrcLastHdr),
+										   (pCompletedDstHdr == pCurReq->iDstLastHdr)));
+				complete = (pCompletedDstHdr == pCurReq->iDstLastHdr);
+				}
+			else
+				{
+				SDmaDesHdr* pCompletedHdr = NULL;
+				DoDfc(const_cast<const DDmaRequest&>(*pCurReq), pCompletedHdr);
+				complete = (pCompletedHdr == pCurReq->iLastHdr);
+				}
 			// If just completed last fragment from current request, switch to
 			// next request (if any).
-			if (pCompletedHdr == pCurReq->iLastHdr)
+			if (complete)
 				{
 				pCompletedReq = pCurReq;
 				pCurReq->iLink.Deque();
--- a/kernel/eka/drivers/dma/dma2_shared.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/drivers/dma/dma2_shared.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -137,9 +137,9 @@
 	  iFlags(0),
 	  iChannelPriority(KDmaPriorityNone),
 	  iPslRequestInfo(0),
+	  iChannelCookie(0),
 	  iDelta(~0u),
 	  iReserved1(0),
-	  iChannelCookie(0),
 	  iReserved2(0)
 	{
 	}
@@ -202,9 +202,9 @@
 	  iFlags(aFlags),
 	  iChannelPriority(aChannelPriority),
 	  iPslRequestInfo(aPslRequestInfo),
+	  iChannelCookie(0),
 	  iDelta(~0u),
 	  iReserved1(0),
-	  iChannelCookie(0),
 	  iReserved2(0)
 	{
 	}
--- a/kernel/eka/drivers/dma/dmapil.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/drivers/dma/dmapil.cpp	Tue May 04 09:44:26 2010 +0100
@@ -800,7 +800,7 @@
 		// If an error occurred it must have been reported on the last interrupt since transfers are
 		// suspended after an error.
 		DDmaRequest::TResult res = (count==0 && error) ? DDmaRequest::EError : DDmaRequest::EOk;
-		__DMA_ASSERTD(!iReqQ.IsEmpty());
+		__DMA_ASSERTA(!iReqQ.IsEmpty());
 		DDmaRequest* pCompletedReq = NULL;
 		DDmaRequest* pCurReq = _LOFF(iReqQ.First(), DDmaRequest, iLink);
 		DDmaRequest::TCallback cb = 0;
--- a/kernel/eka/include/drivers/dma_compat.inl	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dma_compat.inl	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -34,6 +34,8 @@
 	{
 	TUint32 flags = (aFlags & KDmaMemSrc) ? KDmaMemAddr : 0;
 	flags |= (aFlags & KDmaPhysAddrSrc) ? KDmaPhysAddr : 0;
+	if ((flags & KDmaMemAddr) && (flags & KDmaPhysAddr))
+		flags |= KDmaMemIsContiguous;
 	return flags;
 	}
 
@@ -41,6 +43,8 @@
 	{
 	TUint32 flags = (aFlags & KDmaMemDest) ? KDmaMemAddr : 0;
 	flags |= (aFlags & KDmaPhysAddrDest) ? KDmaPhysAddr : 0;
+	if ((flags & KDmaMemAddr) && (flags & KDmaPhysAddr))
+		flags |= KDmaMemIsContiguous;
 	return flags;
 	}
 
--- a/kernel/eka/include/drivers/dma_hai.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dma_hai.h	Tue May 04 09:44:26 2010 +0100
@@ -16,6 +16,11 @@
 //
 //
 
+/** @file
+	@publishedPartner
+	@released
+*/
+
 #ifndef __DMA_HAI_H__
 #define __DMA_HAI_H__
 
@@ -29,12 +34,10 @@
 /** Interface used by PIL to open and close DMA channels.
 
 	Must be implemented by the PSL.
-
-	@publishedPartner
-	@released
 */
 class DmaChannelMgr
 	{
+
 public:
 	/** Opens a channel using a client-provided identifier.
 
@@ -94,6 +97,7 @@
 	*/
 	static TDmaChannel* Open(TUint32 aOpenId, TBool aDynChannel, TUint aPriority);
 
+
 	/** Performs platform-specific operations when a channel is closed.
 
 		If aChannel was opened as a dynamic channel then this call is a sign
@@ -110,6 +114,7 @@
 	*/
 	static void Close(TDmaChannel* aChannel);
 
+
 	/** Function allowing PSL to extend DMA API with new channel-independent
 		operations.
 
@@ -122,14 +127,16 @@
 
 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
 		otherwise.
-	 */
+	*/
 	static TInt StaticExtension(TInt aCmd, TAny* aArg);
 
+
 	/** Acquires the channel manager lock. Called by the PIL before opening and
 		closing a channel.
 	*/
 	static void Wait();
 
+
 	/** Releases the channel manager lock. Called by the PIL after opening and
 		closing a channel.
 	*/
@@ -139,7 +146,7 @@
 	/** Declared, defined, and called by PSL's DECLARE_STANDARD_EXTENSION(). */
 	friend TInt InitExtension();
 
-	/** Must be called in the DMA DLL entry point. */
+	/** Must be called in the PSL's DECLARE_STANDARD_EXTENSION(). */
 	static TInt Initialise();
 
 	static NFastMutex Lock;
@@ -160,22 +167,26 @@
 
 	These functions are the main interfaces between the PIL
 	(platform-independent layer) and PSL.
-
-	@publishedPartner
-	@released
 */
 class TDmac
 	{
-	friend class DmaChannelMgr;
+friend class DmaChannelMgr;
+
+// The following two friend declarations will become obsolete once that
+// functionality is owned and provided by the controller class instead of the
+// request class. (TDmac::iFreeHdr could then also be made private.)
+friend TInt DDmaRequest::ExpandDesList(TInt, TInt&, SDmaDesHdr*&, SDmaDesHdr*&);
+friend void DDmaRequest::FreeDesList(TInt&, SDmaDesHdr*&, SDmaDesHdr*&);
 
 protected:
-	/** Data required for creating a new instance */
+	/** Data required for creating a new instance. */
 	struct SCreateInfo
 		{
 		/** True if DMAC uses hardware descriptors (i.e. supports
 			scatter/gather mode).
 		*/
 		TBool iCapsHwDes;
+
 		/** Initial maximum number of descriptors and headers (shared by all
 			channels) to be allocated by the PIL. If at run time more
 			descriptors are needed then they will be dynamically allocated and
@@ -186,14 +197,22 @@
 			the maximum transfer size per descriptor and also likely usage
 			scenarios for the platform or device (number of drivers using DMA,
 			their traffic patterns, simultaneity of operations, etc.).
+
+			(NB: Dynamic growing of the descriptor pool is not yet implemented
+			in the PIL, so this value is currently also the final maximum
+			number of descriptors.)
 		*/
 		TInt iDesCount;
-		/** Size of individual descriptors. Use sizeof(TDmaTransferArgs) for
-		 	single-buffer and double-buffer (i.e. non-s/g) controllers.
+
+		/** Size of an individual descriptor.
+
+			Use sizeof(TDmaTransferArgs) for single-buffer and double-buffer
+		 	(i.e. non-s/g) controllers.
 		*/
 		TInt iDesSize;
+
 		/** Bitmask used when creating the memory chunk storing the descriptor
-			pool. Used only for hardware descriptors.
+			pool in the PIL. Used only for hardware descriptors.
 
 			The access part must be EMapAttrSupRw. If the chunk is cached
 			and/or buffered, the PSL must flush the data cache and/or drain the
@@ -207,65 +226,65 @@
 		TUint iDesChunkAttribs;
 		};
 
-	/** Base class constructor. */
+	/** Base class constructor.
+	 */
 	TDmac(const SCreateInfo& aInfo);
 
-	/** Base class 2nd-phase constructor. */
+	/** Base class 2nd-phase constructor.
+	 */
 	TInt Create(const SCreateInfo& aInfo);
 
 public:
-	/** Base class virtual destructor. */
+	/** Base class virtual destructor.
+	 */
 	virtual ~TDmac();
 
+
 	/** Allocates a number of headers (and hence also descriptors) from the
 		header/descriptor pools. Called by the PIL but may also be used by the
 		PSL.
 	*/
 	TInt ReserveSetOfDes(TInt aCount);
 
+
 	/** Returns previously allocated headers (and hence also descriptors) to
 		the header/descriptor pools. Called by the PIL but may also be used by
 		the PSL.
 	*/
 	void ReleaseSetOfDes(TInt aCount);
 
+
 	/** Called by the PIL during request fragmentation to fill a descriptor or
 		pseudo descriptor with transfer arguments.
 	*/
 	TInt InitDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
 
+
 	/** Called by the PIL in TDmaChannel::IsrRedoRequest() if any of the
 		latter's arguments is non-zero.
 	*/
 	TInt UpdateDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
 				   TUint aTransferCount, TUint32 aPslRequestInfo);
 
+
 	/** Returns a reference to the associated pseudo descriptor for a given
 		descriptor header. For use by PIL and PSL.
 	*/
 	inline TDmaTransferArgs& HdrToDes(const SDmaDesHdr& aHdr) const;
 
+
 	/** Returns a reference to the associated hardware descriptor for a given
 		descriptor header. For use by PIL and PSL.
 	*/
 	inline TAny* HdrToHwDes(const SDmaDesHdr& aHdr) const;
 
+
 	/** Returns the physical address of the hardware descriptor
 		pointed to by aDes. For use by PIL and PSL.
 	*/
 	inline TUint32 HwDesLinToPhys(TAny* aDes) const;
 
-	/** Called by the PIL to acquire the controller lock which protects the
-		header and descriptor pools.
-	*/
-	inline void Wait();
 
-	/** Called by the PIL to release the controller lock which protects the
-		header and descriptor pools.
-	*/
-	inline void Signal();
-
-public:
 	/** Called by PIL when one fragment (single-buffer and double-buffer DMACs)
 		or list of fragments (scatter/gather DMAC) is to be transferred.
 
@@ -283,6 +302,7 @@
 	*/
 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr);
 
+
 	/** Called by PIL when two lists of fragments (scatter/gather DMAC with
 		asymmetrical linked-list capability) are to be transferred.
 
@@ -302,6 +322,7 @@
 	virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aSrcHdr,
 						  const SDmaDesHdr& aDstHdr);
 
+
 	/** Called by PIL to stop a transfer on a given channel.
 
 		The stopping must occur synchronously as the PIL assumes the channel
@@ -316,6 +337,7 @@
 	*/
 	virtual void StopTransfer(const TDmaChannel& aChannel) = 0;
 
+
 	/** Called by PIL to pause (suspend) a transfer on a given channel.
 
 		A paused channel transfer must be able to be resumed by calling
@@ -330,9 +352,10 @@
 
 		@post No interrupt will occur from this channel until it is
 		resumed.
-	 */
+	*/
 	virtual TInt PauseTransfer(const TDmaChannel& aChannel);
 
+
 	/** Called by PIL to resume a paused (suspended) transfer on a given
 		channel.
 
@@ -341,14 +364,16 @@
 		Pause bit in a H/W descriptor.
 
 		The function must be implemented by the PSL if
-		SDmacCaps::iChannelPauseAndResume is reported as true.
+		SDmacCaps::iChannelPauseAndResume or
+		SDmacCaps::iLinkedListPausedInterrupt is reported as true.
 
 		@return KErrNone if the transfer has been resumed successfully,
 		KErrCompletion if there was no paused transfer, KErrGeneral
 		if a general error occurred preventing a successful outcome.
-	 */
+	*/
 	virtual TInt ResumeTransfer(const TDmaChannel& aChannel);
 
+
 	/** Called by PIL to check whether a DMA channel is idle.
 
 		'Idle' here means that the channel is ultimately stopped, for example
@@ -363,6 +388,7 @@
 	*/
 	virtual TBool IsIdle(const TDmaChannel& aChannel) = 0;
 
+
 	/** Called by PIL to retrieve from the PSL the maximum transfer length
 		based on the parameters passed.
 
@@ -380,6 +406,7 @@
 	virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags,
 									TUint aDstFlags, TUint32 aPslInfo) = 0;
 
+
 	/** Called by PIL to retrieve from the PSL the memory alignment mask based
 		on the parameters passed. Some DMA controllers impose alignment
 		constraints on the base address of memory buffers. This mask is AND'ed
@@ -412,6 +439,7 @@
 	virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aTargetFlags,
 								   TUint aElementSize, TUint32 aPslInfo) = 0;
 
+
 	/** Called by PIL during fragmentation to initialise a hardware descriptor.
 
 		The PSL must assume the descriptor is the last in the chain and so set
@@ -433,6 +461,7 @@
 	*/
 	virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
 
+
 	/** Called by PIL during fragmentation to initialise a hardware descriptor
 		on the source side of an asymmetric linked list.
 
@@ -452,6 +481,7 @@
 	*/
 	virtual TInt InitSrcHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
 
+
 	/** Called by PIL during fragmentation to initialise a hardware descriptor
 		on the destination side of an asymmetric linked list.
 
@@ -471,6 +501,7 @@
 	*/
 	virtual TInt InitDstHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs);
 
+
 	/** Called by the PIL in ISR context to change specific fields in a
 		hardware descriptor.
 
@@ -497,6 +528,7 @@
 	virtual TInt UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr,
 							 TUint aTransferCount, TUint32 aPslRequestInfo);
 
+
 	/** Called by the PIL in ISR context to change specific fields in a
 		hardware descriptor.
 
@@ -521,6 +553,7 @@
 	virtual TInt UpdateSrcHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr,
 								TUint aTransferCount, TUint32 aPslRequestInfo);
 
+
 	/** Called by the PIL in ISR context to change specific fields in a
 		hardware descriptor.
 
@@ -545,6 +578,7 @@
 	virtual TInt UpdateDstHwDes(const SDmaDesHdr& aHdr, TUint32 aDstAddr,
 								TUint aTransferCount, TUint32 aPslRequestInfo);
 
+
 	/** Called by PIL, when fragmenting a request, to append a new hardware
 		descriptor to an existing descriptor chain. May also be called by
 		clients who wish to create their own descriptor chains.
@@ -559,6 +593,7 @@
 	*/
 	virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr);
 
+
 	/** Called by PIL when queuing a new request while the channel is running.
 
 		Must append the first hardware descriptor of the new request to the
@@ -576,6 +611,7 @@
 	virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr,
 							 const SDmaDesHdr& aNewHdr);
 
+
 	/** Called by PIL when queuing a new request while the channel is running.
 
 		Must append the first hardware descriptor of the new request to the
@@ -598,6 +634,7 @@
 							 const SDmaDesHdr& aSrcLastHdr, const SDmaDesHdr& aSrcNewHdr,
 							 const SDmaDesHdr& aDstLastHdr, const SDmaDesHdr& aDstNewHdr);
 
+
 	/** Called by PIL when completing or cancelling a request to cause the PSL
 		to unlink the last item in the h/w descriptor chain from a subsequent
 		chain that it was possibly linked to.
@@ -612,6 +649,7 @@
 	*/
 	virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr);
 
+
 	/** Called by PIL when freeing descriptors back to the shared pool in
 		FreeDesList(). The PSL inside ClearHwDes() can clear the contents of
 		the h/w descriptor.
@@ -624,9 +662,10 @@
 		hardware descriptors.
 
 		@param aHdr Header associated with the h/w descriptor being freed.
-	 */
+	*/
 	virtual void ClearHwDes(const SDmaDesHdr& aHdr);
 
+
 	/** Called by PIL to logically link two physical channels.
 
 		The function must be implemented by the PSL if the DMAC supports
@@ -642,9 +681,10 @@
 		KErrArgument if a1stChannel was already linked to a different channel,
 		KErrGeneral if a general error occurred preventing a successful
 		outcome. The default PIL implementation returns KErrNotSupported.
-	 */
+	*/
 	virtual TInt LinkChannels(TDmaChannel& a1stChannel, TDmaChannel& a2ndChannel);
 
+
 	/** Called by PIL to logically unlink a physical channel from its linked-to
 		successor.
 
@@ -659,9 +699,10 @@
 		KErrCompletion if the channel was not linked to another channel,
 		KErrGeneral if a general error occurred preventing a successful
 		outcome. The default PIL implementation returns KErrNotSupported.
-	 */
+	*/
 	virtual TInt UnlinkChannel(TDmaChannel& aChannel);
 
+
 	/** Called by a test harness to force an error when the next fragment is
 		transferred.
 
@@ -674,6 +715,7 @@
 	*/
 	virtual TInt FailNext(const TDmaChannel& aChannel);
 
+
 	/** Called by a test harness to force the DMA controller to miss one or
 		more interrupts.
 
@@ -687,6 +729,7 @@
 	*/
 	virtual TInt MissNextInterrupts(const TDmaChannel& aChannel, TInt aInterruptCount);
 
+
 	/** Function allowing platform-specific layer to extend channel API with
 		new channel-specific operations.
 
@@ -702,6 +745,7 @@
 	*/
 	virtual TInt Extension(TDmaChannel& aChannel, TInt aCmd, TAny* aArg);
 
+
 	/** Called by the PIL to query the number of elements that have so far been
 		transferred by the hardware descriptor associated with aHdr at the
 		source port.
@@ -721,6 +765,7 @@
 	*/
 	virtual TUint32 HwDesNumSrcElementsTransferred(const SDmaDesHdr& aHdr);
 
+
 	/** Called by the PIL to query the number of elements that have so far been
 		transferred by the hardware descriptor associated with aHdr at the
 		destination port.
@@ -746,7 +791,7 @@
 		@param aChannel The channel the ISR relates to
 		@param aEventMask Bitmask of one or more TDmaCallbackType values
 		@param aIsComplete Set to ETrue if no error was encountered
-	 */
+	*/
 	static void HandleIsr(TDmaChannel& aChannel, TUint aEventMask, TBool aIsComplete);
 
 private:
@@ -756,6 +801,16 @@
 	/** Called in ~TDmac() */
 	void FreeDesPool();
 
+	/** Called by the PIL to acquire the controller lock which protects the
+		header and descriptor pools.
+	*/
+	inline void Wait();
+
+	/** Called by the PIL to release the controller lock which protects the
+		header and descriptor pools.
+	*/
+	inline void Signal();
+
 private:
 	NFastMutex iLock;			 // protect descriptor reservation and allocation
 	const TInt iMaxDesCount;	 // initial number of descriptors and headers
@@ -785,9 +840,6 @@
 /** Single-buffer DMA channel.
 
 	Can be instantiated or further derived by the PSL.
-
-	@publishedPartner
-	@released
 */
 class TDmaSbChannel : public TDmaChannel
 	{
@@ -795,6 +847,7 @@
 	virtual void DoQueue(const DDmaRequest& aReq);
 	virtual void DoCancelAll();
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
+
 private:
 	enum {EIdle = 0, ETransferring} iState;
 	};
@@ -803,9 +856,6 @@
 /** Double-buffer DMA channel.
 
 	Can be instantiated or further derived by the PSL.
-
-	@publishedPartner
-	@released
 */
 class TDmaDbChannel : public TDmaChannel
 	{
@@ -813,6 +863,7 @@
 	virtual void DoQueue(const DDmaRequest& aReq);
 	virtual void DoCancelAll();
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
+
 private:
 	enum {EIdle = 0, ETransferring, ETransferringLast} iState;
 	};
@@ -821,9 +872,6 @@
 /** Scatter-gather DMA channel.
 
 	Can be instantiated or further derived by the PSL.
-
-	@publishedPartner
-	@released
 */
 class TDmaSgChannel : public TDmaChannel
 	{
@@ -832,6 +880,7 @@
 	virtual void DoCancelAll();
 	virtual void DoUnlink(SDmaDesHdr& aHdr);
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
+
 private:
 	enum {EIdle = 0, ETransferring} iState;
 	};
@@ -841,8 +890,7 @@
 
 	Can be instantiated or further derived by the PSL.
 
-	@publishedPartner
-	@released
+	@prototype
 */
 class TDmaAsymSgChannel : public TDmaChannel
 	{
@@ -852,8 +900,9 @@
 	virtual void DoUnlink(SDmaDesHdr& aHdr);
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
 					   SDmaDesHdr*& aDstCompletedHdr);
+
 private:
-	SDmaDesHdr* iSrcCurHdr;		   // source fragment being transferred or NULL
+	SDmaDesHdr* iSrcCurHdr;	  // source fragment being transferred or NULL
 	SDmaDesHdr** iSrcNullPtr; // Pointer to NULL pointer following last source fragment
 	SDmaDesHdr* iDstCurHdr;	  // destination fragment being transferred or NULL
 	SDmaDesHdr** iDstNullPtr; // Pointer to NULL pointer following last destination fragment
--- a/kernel/eka/include/drivers/dma_v1.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dma_v1.h	Tue May 04 09:44:26 2010 +0100
@@ -158,6 +158,15 @@
     The request can be uninitialised or may have been fragmented previously.  The
     previous configuration if any is lost whether or not the function succeeds.
 
+    The client must ensure that any memory buffers involved in the transfer
+    have been suitably prepared for DMA. For memory allocated on the kernel
+    side or in a shared chunk this amounts to ensuring cache consistency
+    before Queue() is called. However for memory that was allocated on the
+    user side the client must also ensure that the memory is protected from
+    both data paging and RAM defragmentation before Fragment() is called
+    @see Kern::MapAndPinMemory(). Note however, that this function is only
+    available if the flexible memory model (FMM) is in use.
+
     @param aSrc     Source memory buffer linear address or peripheral magic cookie.
     @param aDest    Destination memory buffer linear address or peripheral magic cookie.
     @param aCount   Number of bytes to transfer.
--- a/kernel/eka/include/drivers/dma_v2.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dma_v2.h	Tue May 04 09:44:26 2010 +0100
@@ -18,6 +18,10 @@
 // generic header file <drivers/dma.h>.
 //
 
+/** @file
+	@publishedPartner
+*/
+
 #ifndef __DMA_H__
 #error "dma_v2.h must'n be included directly - use <drivers/dma.h> instead"
 #endif	// #ifndef __DMA_H__
@@ -67,14 +71,14 @@
 	Some peripherals may require a post-increment address mode.
 
 	@see DDmaRequest::Fragment
-	@publishedPartner
-	@released
+
+	Note: This enum is only required for backwards compatibility with the old
+	DMA framework, it can be removed once this is no longer needed.
+
+	@deprecated
 */
 enum TDmaRequestFlags
 	{
-	// Note: This enum is only required for backwards compatibility with the
-	// old DMA framework, it can be removed once this is no longer needed.
-
 	/** Source is address of memory buffer */
 	KDmaMemSrc       = 0x01,
 	/** Destination is address of memory buffer */
@@ -96,7 +100,6 @@
 	are needed because hardware descriptors can not easily be extended to store
 	additional information.
 
-	@publishedPartner
 	@released
 */
 struct SDmaDesHdr
@@ -104,18 +107,23 @@
 	SDmaDesHdr* iNext;
 	};
 
+
 /** Pointer to signature of the new extended callback function.
 
-	TUint - bitmask of one or more TDmaCallbackType values
-	TDmaResult - just that
-	TAny* - was provided by client in DDmaRequest constructor
+	TUint       - bitmask of one or more TDmaCallbackType values
+	TDmaResult  - just that
+	TAny*       - was provided by client in DDmaRequest constructor
 	SDmaDesHdr* - points to header (and thus descriptor) which caused a
-	'descriptor completed' or 'descriptor paused' event.
+	'descriptor completed' or 'descriptor paused' event
+
+	@released
  */
 typedef void (*TDmaCallback)(TUint, TDmaResult, TAny*, SDmaDesHdr*);
 
+
 class TDmaChannel;
 
+
 /** A DMA request is a list of fragments small enough to be transferred in one go
 	by the DMAC.
 
@@ -132,10 +140,7 @@
 	Mutexes are used internally to protect data structures accessed both by the
 	client thread and the DFC thread. Therefore no fast mutex can be held when
 	calling a request function.
-
-	@publishedPartner
-	@released
- */
+*/
 class DDmaRequest : public DBase
 	{
 	friend class TDmaChannel;
@@ -143,14 +148,17 @@
 public:
 	/** The outcome of the transfer
 
+		@see TDmaResult
+
 		@deprecated
-		@see TDmaResult
 	*/
 	enum TResult {EBadResult=0, EOk, EError};
+
 	/** The signature of the completion/failure callback function
 
+		@see TDmaCallback
+
 		@deprecated
-		@see TDmaCallback
 	*/
 	typedef void (*TCallback)(TResult, TAny*);
 
@@ -183,15 +191,19 @@
 		@param aMaxTransferSize Maximum fragment size. If not specified,
 		defaults to the maximum size supported by the DMA controller for the
 		type of transfer that is later scheduled.
+
+		@released
 	*/
-	IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb, TAny* aCbArg=NULL,
-						 TUint aMaxTransferSize=0);
+	IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb,
+						 TAny* aCbArg=NULL, TUint aMaxTransferSize=0);
 
 
 	/** Destructor.
 
 		Assume the request is not being transferred or pending.
-    */
+
+		@released
+	*/
 	IMPORT_C ~DDmaRequest();
 
 
@@ -212,6 +224,15 @@
 		previously. The previous configuration if any is lost whether or not
 		the function succeeds.
 
+		The client must ensure that any memory buffers involved in the transfer
+		have been suitably prepared for DMA. For memory allocated on the kernel
+		side or in a shared chunk this amounts to ensuring cache consistency
+		before Queue() is called. However for memory that was allocated on the
+		user side the client must also ensure that the memory is protected from
+		both data paging and RAM defragmentation before Fragment() is called
+		@see Kern::MapAndPinMemory(). Note however, that this function is only
+		available if the flexible memory model (FMM) is in use.
+
 		@param aSrc Source memory buffer linear address or peripheral magic
 		cookie.
 		@param aDest Destination memory buffer linear address or peripheral
@@ -237,6 +258,38 @@
 
 	/** New version of the DMA request fragment function, to be used with the
 		TDmaTransferArgs structure.
+
+		Split request into a list of fragments small enough to be fed to the
+		DMAC.
+
+		The size of each fragment is smaller than or equal to the maximum
+		transfer size supported by the DMAC. If the source and/or destination
+		is memory, each fragment points to memory which is physically
+		contiguous.
+
+		The request can be uninitialised or may have been fragmented
+		previously. Any previous configuration is lost whether or not the
+		function succeeds.
+
+		The client must ensure that any memory buffers involved in the transfer
+		have been suitably prepared for DMA. For memory allocated on the kernel
+		side or in a shared chunk this amounts to ensuring cache consistency
+		before Queue() is called. However for memory that was allocated on the
+		user side the client must also ensure that the memory is protected from
+		both data paging and RAM defragmentation before Fragment() is called
+		@see Kern::MapAndPinMemory(). Note however, that this function is only
+		available if the flexible memory model (FMM) is in use.
+
+		@param aTransferArgs Describes the transfer to be performed.
+
+		@return KErrNone if success. KErrArgument if certain arguments are
+		invalid. May also fail if running out of descriptors.
+
+		@pre The request is not being transferred or pending.
+		@pre The various parameters must be valid. The PIL or PSL will fault
+		the kernel if not.
+
+		@released
 	*/
 	IMPORT_C TInt Fragment(const TDmaTransferArgs& aTransferArgs);
 
@@ -250,11 +303,13 @@
 		after the transfer if necessary.
 
 		@return KErrNone if success, KErrGeneral otherwise.
-    */
+
+		@released
+	*/
 	IMPORT_C TInt Queue();
 
 
-    /** Append new descriptor(s) to existing list.
+	/** Append new descriptor(s) to existing list.
 
 		Clients needing to build a custom descriptor list should call this
 		function to allocate the list and access the resulting list through
@@ -270,11 +325,13 @@
 		@param aCount Number of descriptors to append.
 
 		@return KErrNone or standard error code.
-    */
+
+		@released
+	*/
 	IMPORT_C TInt ExpandDesList(TInt aCount=1);
 
 
-    /** Append new descriptor(s) to existing list. This function variant
+	/** Append new descriptor(s) to existing list. This function variant
 		operates on the source port descriptor chain.
 
 		Works like ExpandDesList except that it uses the iSrcFirstHdr and
@@ -288,11 +345,13 @@
 		@param aCount Number of descriptors to append.
 
 		@return KErrNone or standard error code.
-    */
+
+		@prototype
+	*/
 	IMPORT_C TInt ExpandSrcDesList(TInt aCount=1);
 
 
-    /** Append new descriptor(s) to existing list. This function variant
+	/** Append new descriptor(s) to existing list. This function variant
 		operates on the destination port descriptor chain.
 
 		Works like ExpandDesList except that it uses the iDstFirstHdr and
@@ -306,14 +365,18 @@
 		@param aCount Number of descriptors to append.
 
 		@return KErrNone or standard error code.
-    */
+
+		@prototype
+	*/
 	IMPORT_C TInt ExpandDstDesList(TInt aCount=1);
 
 
 	/** Free resources associated with this request.
 
 		Assume the request is not being transferred or pending.
-    */
+
+		@released
+	*/
 	IMPORT_C void FreeDesList();
 
 
@@ -324,7 +387,9 @@
 
 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
 		true, otherwise it will do nothing.
-    */
+
+		@prototype
+	*/
 	IMPORT_C void FreeSrcDesList();
 
 
@@ -335,7 +400,9 @@
 
 		This function can only be used if SDmacCaps::iAsymHwDescriptors is
 		true, otherwise it will do nothing.
-    */
+
+		@prototype
+	*/
 	IMPORT_C void FreeDstDesList();
 
 
@@ -367,6 +434,8 @@
 
 		@see Queue()
 		@see TotalNumSrcElementsTransferred()
+
+		@prototype
 	*/
 	IMPORT_C void EnableSrcElementCounting(TBool aResetElementCount=ETrue);
 
@@ -399,6 +468,8 @@
 
 		@see Queue()
 		@see TotalNumDstElementsTransferred()
+
+		@prototype
 	*/
 	IMPORT_C void EnableDstElementCounting(TBool aResetElementCount=ETrue);
 
@@ -427,6 +498,8 @@
 
 		@see Queue()
 		@see TotalNumSrcElementsTransferred()
+
+		@prototype
 	*/
 	IMPORT_C void DisableSrcElementCounting();
 
@@ -455,6 +528,8 @@
 
 		@see Queue()
 		@see TotalNumDstElementsTransferred()
+
+		@prototype
 	*/
 	IMPORT_C void DisableDstElementCounting();
 
@@ -475,6 +550,8 @@
 
 		@return The number of elements that have been transferred by this
 		transfer request at the source port.
+
+		@prototype
 	*/
 	IMPORT_C TUint32 TotalNumSrcElementsTransferred();
 
@@ -495,6 +572,8 @@
 
 		@return The number of elements that have been transferred by this
 		transfer request at the destination port.
+
+		@prototype
 	*/
 	IMPORT_C TUint32 TotalNumDstElementsTransferred();
 
@@ -512,9 +591,12 @@
 
 		@return The number of fragments (descriptors / pseudo descriptors) that
 		this transfer request has been split into.
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt FragmentCount();
 
+
 	/** Returns the number of source port fragments that this transfer request
 		has been split into.
 
@@ -527,7 +609,9 @@
 
 		@return The number of source port fragments (descriptors) that this
 		transfer request has been split into.
-	 */
+
+		@prototype
+	*/
 	IMPORT_C TInt SrcFragmentCount();
 
 
@@ -543,17 +627,24 @@
 
 		@return The number of destination port fragments (descriptors) that
 		this transfer request has been split into.
-	 */
+
+		@prototype
+	*/
 	IMPORT_C TInt DstFragmentCount();
 
 private:
 	inline void OnDeque();
-	TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs);
+	TInt CheckTransferConfig(const TDmaTransferConfig& aTarget, TUint aCount) const;
+	TInt CheckMemFlags(const TDmaTransferConfig& aTarget, TUint aCount) const;
+	TInt AdjustFragmentSize(TUint& aFragSize, TUint aElementSize, TUint aFrameSize);
+	TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs) const;
+	TUint GetMaxTransferlength(const TDmaTransferArgs& aTransferArgs, TUint aCount) const;
 	TInt Frag(TDmaTransferArgs& aTransferArgs);
 	TInt FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
 	TInt FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
 	TInt FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
 	TInt FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
+	TInt FragBalancedAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
 	TInt ExpandDesList(TInt aCount, TInt& aDesCount, SDmaDesHdr*& aFirstHdr,
 					   SDmaDesHdr*& aLastHdr);
 	void FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr);
@@ -561,7 +652,7 @@
 
 public:
 	// WARNING: The following attributes are accessed both in client and DFC
-	// context and so accesses must be protected with the channel lock.
+	// thread context, so accesses must be protected with the channel lock.
 	TDmaChannel& iChannel;		/**< The channel this request is bound to */
 	TCallback iCb;			 /**< Called on completion/failure (can be NULL) */
 	TAny* iCbArg;			 /**< Callback argument */
@@ -608,18 +699,15 @@
 	Mutexes are used internally to protect data structures accessed both by the
 	client thread and the DFC one. Therefore no fast mutex can be held when
 	calling a channel function.
-
-	@publishedPartner
-	@released
- */
+*/
 class TDmaChannel
 	{
 	friend class DDmaRequest;
 	friend class TDmac;
 	friend class DmaChannelMgr;
+
 public:
-
-	/** Information passed by client when opening a channel */
+	/** Information passed by client when opening a channel. */
 	struct SCreateInfo
 		{
 		/** Default constructor. Initializes all fields with meaningful default
@@ -628,20 +716,23 @@
 			Must be inline (for now) because exporting it would break existing
 			custom DMA libs as their clients would need the export which would
 			be missing from the custom .def files.
+
+			@released
 		*/
 		SCreateInfo() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {};
 
-		/** Identifier used by PSL to select channel to open */
-		TUint32 iCookie;
-		/** Number of descriptors this channel can use.
+		/** Identifier used by PSL to select channel to open.
 
-			This number is not used in the upgraded version of the DMA
-			framework and is kept there only for source compatibility. If the
-			client is certain that it will only ever use that version, then the
-			value passed here doesn't matter - the framework will ignore it.
+			@released
+		*/
+		TUint32 iCookie;
+		/** Number of descriptors this channel can maximally use.
 
-			@deprecated
-		 */
+			This value will not be used in the fully implemented new version of
+			the DMA framework. Until then it is still required.
+
+			@released
+		*/
 		TInt iDesCount;
 		/** DFC queue used to service DMA interrupts.
 
@@ -649,15 +740,22 @@
 			priority to avoid a situation where a transfer completes while
 			being cancelled and another transfer is started before the DFC
 			thread gets a chance to run. This would lead to a stray DFC.
+
+			@released
 		*/
 		TDfcQue* iDfcQ;
-		/** DFC priority */
+		/** DFC priority.
+
+			@released
+		*/
 		TUint8 iDfcPriority;
 		/** Used by PSL to configure a channel priority (if possible).
 
 			The default is KDmaPriorityNone (the don't care value).
 
-		    @see TDmaPriority
+			@see TDmaPriority
+
+			@prototype
 		*/
 		TUint iPriority;
 		/** Request a dynamic DMA channel.
@@ -668,12 +766,14 @@
 			that case.
 
 			The default value is EFalse.
+
+			@prototype
 		 */
 		TBool iDynChannel;
 		};
 
 public:
-    /** Opens the DMA channel.
+	/** Opens the DMA channel.
 
 		Channel selection is done by the hardware-specific layer using a cookie
 		passed in via aInfo.
@@ -689,7 +789,9 @@
 		otherwise.
 
 		@return KErrNone or standard error code.
- 	*/
+
+		@released
+	*/
 	IMPORT_C static TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel);
 
 
@@ -701,6 +803,8 @@
 		released, and the pointer/reference to it mustn't therefore be accessed
 		any longer after the function has returned. The channel pointer should
 		be set to NULL by the client.
+
+		@released
  	*/
 	IMPORT_C void Close();
 
@@ -733,9 +837,12 @@
 		support channel linking, KErrArgument if this channel was already
 		linked to a different channel, KErrGeneral if a general error occurred
 		preventing a successful outcome.
-	 */
+
+		@prototype
+	*/
 	IMPORT_C TInt LinkToChannel(TDmaChannel* aChannel);
 
+
 	/** Pauses an active transfer on this channel.
 
 		A paused channel transfer can be resumed by calling Resume() or it can
@@ -751,7 +858,9 @@
 		KErrCompletion if a transfer was already paused, KErrNotSupported if
 		the DMAC doesn't support channel transfer pausing/resuming, KErrGeneral
 		if a general error occurred preventing a successful outcome.
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt Pause();
 
 
@@ -767,17 +876,22 @@
 		Function can only be used if the DMAC supports this functionality.
 
 		@see SDmacCaps::iChannelPauseAndResume
+		@see SDmacCaps::iLinkedListPausedInterrupt
 
 		@return KErrNone if a paused transfer has been resumed successfully,
 		KErrCompletion if there was no paused transfer, KErrNotSupported if the
 		DMAC doesn't support channel transfer pausing/resuming, KErrGeneral if
 		a general error occurred preventing a successful outcome.
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt Resume();
 
 
 	/** Cancels the current request and all the pending ones.
-	 */
+
+		@released
+	*/
 	IMPORT_C void CancelAll();
 
 
@@ -795,6 +909,8 @@
 
 		@return 0 if transfer length is not limited, the maximum transfer
 		length in bytes otherwise.
+
+		@released
  	*/
 	IMPORT_C TUint MaxTransferLength(TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo);
 
@@ -819,7 +935,9 @@
 
 		@return A value representing the alignment mask (e.g. 3 if buffer must
 		be 4-byte aligned)
-	 */
+
+		@released
+	*/
 	IMPORT_C TUint AddressAlignMask(TUint aTargetFlags, TUint aElementSize,
 									TUint32 aPslInfo);
 
@@ -829,7 +947,9 @@
 
 		@return A reference to a structure containing the capabilities and
 		features of the DMA controller associated with this channel.
-	 */
+
+		@released
+	*/
 	IMPORT_C const SDmacCaps& DmacCaps();
 
 
@@ -876,7 +996,9 @@
 		@see TDmaPILFlags::KDmaRequestCallbackFromIsr
 
 		@return KErrGeneral if there was an error, KErrNone otherwise.
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid,
 								 TUint32 aDstAddr=KPhysAddrInvalid,
 								 TUint aTransferCount=0,
@@ -891,18 +1013,20 @@
 		NB: This API should not be used any longer.
 
 		After calling TDmaChannel::Open() successfully the channel is
-		guaranteed to be open. Therefore there seems no good reason for this
-		API to exist.
+		guaranteed to be open, hence there seems no good reason for this API to
+		exist.
 
 		@deprecated
-	 */
+	*/
 	inline TBool IsOpened() const;
 
 
 	/** Tests whether the channel's request queue is currently empty.
 
 		@return ETrue if request queue is currently empty, EFalse otherwise.
-	 */
+
+		@released
+	*/
 	inline TBool IsQueueEmpty() const;
 
 
@@ -910,7 +1034,9 @@
 		it is used for debug tracing by the PIL.
 
 		@return PSL-specific value which uniquely identifies this channel.
-	 */
+
+		@released
+	*/
 	inline TUint32 PslId() const;
 
 
@@ -918,7 +1044,9 @@
 		transferred.
 
 		@param aFragmentCount The number of consecutive fragments to fail
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt FailNext(TInt aFragmentCount);
 
 
@@ -926,53 +1054,65 @@
 		more interrupts.
 
 		@param aInterruptCount The number of consecutive interrupts to miss
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt MissNextInterrupts(TInt aInterruptCount);
 
 
 	/** Function allowing platform-specific layer to extend channel API with
 		new channel-specific operations.
 
-		@param aCmd Command identifier. Negative values are reserved for use by
-		Nokia.
+		@param aCmd Command identifier.
 		@param aArg PSL-specific argument
 
 		@return KErrNotSupported if aCmd is not supported. PSL-specific value
 		otherwise.
-	 */
+
+		@released
+	*/
 	IMPORT_C TInt Extension(TInt aCmd, TAny* aArg);
 
 
 	/** This is a function that allows the Platform Specific Layer (PSL) to
 		extend the DMA API with new channel-independent operations.
 
-		@param aCmd Command identifier. Negative values are reserved for
-		Symbian use.
+		@param aCmd Command identifier.
 		@param aArg PSL-specific.
 
 		@return KErrNotSupported if aCmd is not supported; a PSL specific value
 		otherwise.
+
+		@released
  	*/
 	IMPORT_C TInt StaticExtension(TInt aCmd, TAny* aArg);
 
 
-	/** @deprecated
-		@see DmacCaps()
-	 */
+	/** @see DmacCaps()
+
+		@deprecated
+	*/
 	inline const TDmac* Controller() const;
 
-	/** @deprecated
-		@see MaxTransferLength()
-	 */
+	/** @see MaxTransferLength()
+
+		@deprecated
+	*/
 	inline TInt MaxTransferSize(TUint aFlags, TUint32 aPslInfo);
 
-	/** @deprecated
-		@see AddressAlignMask()
-	 */
+	/** @see AddressAlignMask()
+
+		@deprecated
+	*/
 	inline TUint MemAlignMask(TUint aFlags, TUint32 aPslInfo);
 
 protected:
 	// Interface with state machines
+
+	/** Constructor.
+
+		@released
+	*/
 	TDmaChannel();
 
 	/** Called by the PIL when adding a new request to the channel's queue.
@@ -980,11 +1120,15 @@
 		and begin transfer of aReq if possible.
 
 		@param aReq The request which has been added to the queue
+
+		@released
 	*/
 	virtual void DoQueue(const DDmaRequest& aReq);
 
 	/** Called by the PIL in response to a CancelAll call. It should update
 		the channel state appropriately.
+
+		@released
 	*/
 	virtual void DoCancelAll() = 0;
 
@@ -999,6 +1143,8 @@
 
 		@param aHdr The header for a descriptor, which must be unlinked
 		from its next descriptor (if there is one)
+
+		@released
 	*/
 	virtual void DoUnlink(SDmaDesHdr& aHdr);
 
@@ -1012,6 +1158,8 @@
 		@param aCurReq The current request.
 		@param aCompletedHdr Must be set by the implementation to the header
 		of the last transfer to complete.
+
+		@released
 	*/
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
 
@@ -1032,6 +1180,8 @@
 
 		@param aDstCompletedHdr Must be set by the implementation to
 		the header of the last destination descriptor to complete.
+
+		@prototype
 	*/
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
 					   SDmaDesHdr*& aDstCompletedHdr);
@@ -1080,20 +1230,21 @@
 	NFastMutex iLock;		 // for data accessed in both client & DFC context
 	SDmaDesHdr* iCurHdr;	 // fragment being transferred or NULL
 	SDmaDesHdr** iNullPtr;	 // Pointer to NULL pointer following last fragment
-	TDfc iDfc;				  // transfer completion/failure DFC
-	TInt iMaxDesCount;		  // maximum number of allocable descriptors
-	TInt iAvailDesCount;	  // available number of descriptors
+	TDfc iDfc;				 // transfer completion/failure DFC
+	TInt iMaxDesCount;		 // maximum number of allocable descriptors
+	TInt iAvailDesCount;	 // available number of descriptors
 	volatile TUint32 iIsrDfc; // Interface between ISR and DFC:
 	enum {KErrorFlagMask = 0x80000000};	   // bit 31 - error flag
 	enum {KCancelFlagMask = 0x40000000};   // bit 30 - cancel flag
 	enum {KDfcCountMask = 0x3FFFFFFF};	   // bits 0-29 - number of queued DFCs
-	SDblQue iReqQ;				 // being/about to be transferred request queue
-	TInt iReqCount;				 // number of requests attached to this channel
-	TInt iQueuedRequests; // number of requests currently queued on this channel
+	SDblQue iReqQ;			// being/about to be transferred request queue
+	TInt iReqCount;			// number of requests attached to this channel
+	TInt iQueuedRequests; 	// number of requests currently queued on this channel
+
 private:
 	TDmaCancelInfo* iCancelInfo; // ...
-	TBool iRedoRequest;			 // client ISR callback wants a redo of request
-	TBool iIsrCbRequest;		 // request on queue using ISR callback
+	TBool iRedoRequest;		// client ISR callback wants a redo of request
+	TBool iIsrCbRequest;	// request on queue using ISR callback
 
 	__DMA_DECLARE_INVARIANT
 	};
@@ -1103,54 +1254,24 @@
 // INTERFACE WITH TEST HARNESS
 //////////////////////////////////////////////////////////////////////////////
 
-/** Set of information used by test harness.
+/** Provides access to test information structure stored in the PSL.
 
-	@publishedPartner
-	@released
+	Must be implemented by the PSL (v1).
+
+	@deprecated
 */
-struct TDmaTestInfo
-	{
-	/** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/
-	TUint iMaxTransferSize;
-	/** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
-	TUint iMemAlignMask;
-	/** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/
-	TUint32 iMemMemPslInfo;
-	/** Number of test single-buffer channels */
-	TInt iMaxSbChannels;
-	/** Pointer to array containing single-buffer test channel ids */
-	TUint32* iSbChannels;
-	/** Number of test double-buffer channels */
-	TInt iMaxDbChannels;
-	/** Pointer to array containing double-buffer test channel ids */
-	TUint32* iDbChannels;
-	/** Number of test scatter-gather channels */
-	TInt iMaxSgChannels;
-	/** Pointer to array containing scatter-gather test channel ids */
-	TUint32* iSgChannels;
-	};
+IMPORT_C const TDmaTestInfo& DmaTestInfo();
 
 
 /** Provides access to test information structure stored in the PSL.
 
-	Must be implemented by the PSL.
+	Must be implemented by the PSL (v2).
 
-	@publishedPartner
-	@released
-*/
-IMPORT_C const TDmaTestInfo& DmaTestInfo();
-
-/** Provides access to test information structure stored in the PSL.
-
-	Must be implemented by the PSL.
-
-	@publishedPartner
 	@released
 */
 IMPORT_C const TDmaV2TestInfo& DmaTestInfoV2();
 
 
-
 //////////////////////////////////////////////////////////////////////////////
 
 
--- a/kernel/eka/include/drivers/dma_v2.inl	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dma_v2.inl	Tue May 04 09:44:26 2010 +0100
@@ -26,28 +26,17 @@
 
 inline void TDmaChannel::Wait()
 	{
-	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Wait thread %O channel - %d",
-									&Kern::CurrentThread(), iPslId));
 	NKern::FMWait(&iLock);
-	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Wait thread %O channel - %d Acq",
-									&Kern::CurrentThread(), iPslId));
 	}
 
 inline void TDmaChannel::Signal()
 	{
-	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Signal thread %O channel - %d",
-									&Kern::CurrentThread(), iPslId));
 	NKern::FMSignal(&iLock);
 	}
 
 inline TBool TDmaChannel::Flash()
 	{
-	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Flash thread %O channel - %d",
-									&Kern::CurrentThread(), iPslId));
-	const TBool r = NKern::FMFlash(&iLock);
-	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Flash thread %O channel - %d Acq (%d)",
-									&Kern::CurrentThread(), iPslId, r));
-	return r;
+	return NKern::FMFlash(&iLock);
 	}
 
 inline TBool TDmaChannel::IsOpened() const
--- a/kernel/eka/include/drivers/dmadefs.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/drivers/dmadefs.h	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -16,6 +16,10 @@
 //
 //
 
+/** @file
+	@publishedPartner
+*/
+
 #ifndef __DMADEFS_H__
 #define __DMADEFS_H__
 
@@ -23,40 +27,81 @@
 #include <e32def.h>
 
 
-/** The client request callback type */
+/** The client request callback type.
+
+*/
 enum TDmaCallbackType
 	{
-	/** Transfer request completion callback */
+	/** Transfer request completion callback
+
+		@released
+	*/
 	EDmaCallbackRequestCompletion        = 0x01,
-	/** Transfer request completion callback - source side */
+	/** Transfer request completion callback - source side
+
+		@prototype
+	*/
 	EDmaCallbackRequestCompletion_Src    = 0x02,
-	/** Transfer request completion callback - destination side */
+	/** Transfer request completion callback - destination side
+
+		@prototype
+	*/
 	EDmaCallbackRequestCompletion_Dst    = 0x04,
 
-	/** Descriptor completion callback */
+	/** Descriptor completion callback
+
+		@prototype
+	*/
 	EDmaCallbackDescriptorCompletion     = 0x08,
-	/** Descriptor completion callback - source side */
+	/** Descriptor completion callback - source side
+
+		@prototype
+	*/
 	EDmaCallbackDescriptorCompletion_Src = 0x10,
-	/** Descriptor completion callback - destination side */
+	/** Descriptor completion callback - destination side
+
+		@prototype
+	*/
 	EDmaCallbackDescriptorCompletion_Dst = 0x20,
 
-	/** Frame completion callback */
+	/** Frame completion callback
+
+		@prototype
+	*/
 	EDmaCallbackFrameCompletion          = 0x40,
-	/** Frame completion callback - source side */
+	/** Frame completion callback - source side
+
+		@prototype
+	*/
 	EDmaCallbackFrameCompletion_Src      = 0x80,
-	/** Frame completion callback - destination side */
+	/** Frame completion callback - destination side
+
+		@prototype
+	*/
 	EDmaCallbackFrameCompletion_Dst      = 0x100,
 
-	/** H/W descriptor pause event callback */
+	/** H/W descriptor pause event callback
+
+		@prototype
+	*/
 	EDmaCallbackLinkedListPaused        = 0x200,
-	/** H/W descriptor pause event callback - source side */
+	/** H/W descriptor pause event callback - source side
+
+		@prototype
+	*/
 	EDmaCallbackLinkedListPaused_Src    = 0x400,
-	/** H/W descriptor pause event callback - destination side */
+	/** H/W descriptor pause event callback - destination side
+
+		@prototype
+	*/
 	EDmaCallbackLinkedListPaused_Dst    = 0x800
 	};
 
 
-/** The outcome of the transfer request */
+/** The outcome of the transfer request.
+
+	@released
+*/
 enum TDmaResult
 	{
 	/** Completed without error */
@@ -66,7 +111,6 @@
 	};
 
 
-
 /** To be used with address mode field of the DMA transfer config struct.
 
 	@see TDmaTransferConfig::iAddrMode
@@ -75,24 +119,34 @@
 	{
 	/** Constant addressing. The address remains the same for consecutive
 		accesses.
+
+		@released
 	*/
 	KDmaAddrModeConstant,
 	/** Post-increment addressing. The address increases by the element size
 		after each access.
+
+		@released
 	*/
 	KDmaAddrModePostIncrement,
 	/** Post-decrement addressing. The address decreases by the element size
 		after each access.
+
+		@prototype
 	*/
 	KDmaAddrModePostDecrement,
 	/** 1D-index addressing. The address always increases by the element size
 		plus the element skip value after each access.
+
+		@prototype
 	*/
 	KDmaAddrMode1DIndex,
 	/** 2D-index addressing. The address increases by the element size plus the
 		element skip value - but only within a frame. Once a full frame has been
 		transferred, the address increases by the element size plus the element
 		skip value plus the frame skip value.
+
+		@prototype
 	*/
 	KDmaAddrMode2DIndex
 	};
@@ -102,6 +156,8 @@
 
 	@see SDmacCaps::iBurstTransactions
 	@see TDmaTransferConfig::iBurstSize
+
+	@prototype
 */
 enum TDmaBurstSize
 	{
@@ -132,18 +188,28 @@
 	{
 	/** Location is address of a memory buffer (as opposed to a peripheral or a
 		register).
+
+		@released
 	*/
 	KDmaMemAddr                      = 0x01,
 	/** Address is a physical address (as opposed to a linear one).
+
 		If it is a memory address then KDmaMemIsContiguous will need to be set
 		as well.
+
+		@released
 	 */
 	KDmaPhysAddr                     = 0x02,
 	/** Target memory is known to be physically contiguous, hence there is
 		no need for the framework to check for memory fragmentation.
+
+		@released
 	*/
 	KDmaMemIsContiguous              = 0x04,
-	/** Don't use packed access (if possible) */
+	/** Don't use packed access (if possible)
+
+		@released
+	*/
 	KDmaDontUsePacked                = 0x08,
 	/** Location is big endian (little endian if not set).
 
@@ -151,6 +217,8 @@
 		conversion.
 
 		@see SDmacCaps::iEndiannessConversion
+
+		@prototype
 	*/
 	KDmaBigEndian                    = 0x10,
 	/** Don't do endianness conversion even if applicable.
@@ -159,6 +227,8 @@
 		conversion.
 
 		@see SDmacCaps::iEndiannessConversion
+
+		@prototype
 	*/
 	KDmaLockEndian                   = 0x20,
 	/** Execute client request callback after each subtransfer (streaming /
@@ -172,6 +242,8 @@
 		destination are different), unless the flag
 		TDmaPILFlags::KDmaAsymCompletionCallback is set too, in which case what
 		is described there applies.
+
+		@prototype
 	*/
 	KDmaCallbackAfterEveryTransfer   = 0x40,
 	/** Execute client request callback after each completed hardware
@@ -183,6 +255,8 @@
 
 		@see SDmacCaps::iDescriptorInterrupt
 		@see SDmacCaps::iAsymDescriptorInterrupt
+
+		@prototype
 	*/
 	KDmaCallbackAfterEveryDescriptor = 0x80,
 	/** Execute client request callback after each completed frame.
@@ -193,6 +267,8 @@
 
 		@see SDmacCaps::iFrameInterrupt
 		@see SDmacCaps::iAsymFrameInterrupt
+
+		@prototype
 	*/
 	KDmaCallbackAfterEveryFrame      = 0x100
 	};
@@ -203,11 +279,13 @@
 
 	@see SDmacCaps::iSynchronizationTypes
 	@see TDmaTransferConfig::iSyncFlags
+
+	@released
 */
 enum TDmaTransferSyncFlags
 	{
 	/** Leave the decision on whether the transfer is hardware synchronized at
-		this end (either source or destination) to the Framework. This is the
+		this end (either source or destination) to the framework. This is the
 		default.
 	*/
 	KDmaSyncAuto        = 0x00,
@@ -245,6 +323,8 @@
 /** To be used with the Graphics operation field of a DMA transfer request.
 
 	@see TDmaTransferArgs::iGraphicsOps
+
+	@prototype
 */
 enum TDmaGraphicsOps
 	{
@@ -265,20 +345,28 @@
 	{
 	/** Request a different max transfer size (for instance for test
 		purposes).
+
+		@released
 	*/
 	KDmaAltTransferLength         = 0x01,
 	/** Execute client request callback in ISR context instead of from a
 		DFC.
+
+		@released
 	*/
 	KDmaRequestCallbackFromIsr    = 0x02,
 	/** Execute descriptor completion callback in ISR context instead of
 		from a DFC. This option is to be used in conjunction with the
 		TDmaTransferFlags::KDmaCallbackAfterEveryDescriptor flag.
+
+		@prototype
 	*/
 	KDmaDescriptorCallbackFromIsr = 0x04,
 	/** Execute frame completion callback in ISR context instead of
 		from a DFC. This option is to be used in conjunction with the
 		TDmaTransferFlags::KDmaCallbackAfterEveryFrame flag.
+
+		@prototype
 	*/
 	KDmaFrameCallbackFromIsr      = 0x08,
 	/** Execute the client request callback separately for source and
@@ -292,6 +380,8 @@
 		Requires the DMAC to support this feature.
 
 		@see SDmacCaps::iAsymCompletionInterrupt
+
+		@prototype
 	*/
 	KDmaAsymCompletionCallback    = 0x10,
 	/** Execute the descriptor completion callback separately for source
@@ -307,6 +397,8 @@
 		Requires the DMAC to support this feature.
 
 		@see SDmacCaps::iAsymDescriptorInterrupt
+
+		@prototype
 	*/
 	KDmaAsymDescriptorCallback    = 0x20,
 	/** Execute the frame completion callback separately for source and
@@ -321,10 +413,14 @@
 		Requires the DMAC to support this feature.
 
 		@see SDmacCaps::iAsymFrameInterrupt
+
+		@prototype
 	*/
 	KDmaAsymFrameCallback         = 0x40,
 	/** This transfer (only) should use the channel priority indicated by
 		TDmaTransferArgs::iChannelPriority.
+
+		@prototype
 	*/
 	KDmaRequestChannelPriority    = 0x80
 	};
@@ -335,6 +431,8 @@
 
 	@see TDmaChannel::SCreateInfo::iPriority
 	@see TDmaTransferArgs::iChannelPriority
+
+	@prototype
 */
 enum TDmaPriority
 	{
@@ -369,21 +467,26 @@
 	@see SDmacCaps::iSrcDstAsymmetry
 	@see TDmaTransferArgs::iSrcConfig
 	@see TDmaTransferArgs::iDstConfig
+
+	@released
 */
 struct TDmaTransferConfig
 	{
 friend struct TDmaTransferArgs;
 
-	/** Default constructor. Initializes all fields with meaningful default
-		values.
+	/** Default constructor.
+
+		Initializes all fields with meaningful default values.
 	*/
 #ifdef DMA_APIV2
 	KIMPORT_C
 #endif
 	TDmaTransferConfig();
 
-	/**	Intended for general use ie. not 2D or 1D transfers
-	 */
+	/**	Alternate constructor.
+
+		Intended for general use ie. not 1D or 2D transfers
+	*/
 #ifdef DMA_APIV2
 	KIMPORT_C
 #endif
@@ -399,8 +502,10 @@
 		TInt aRepeatCount = 0
 		);
 
-	/**	Intended for 1D and 2D transfers
-	 */
+	/**	Alternate constructor.
+
+		Intended for 1D and 2D transfers.
+	*/
 #ifdef DMA_APIV2
 	KIMPORT_C
 #endif
@@ -441,7 +546,7 @@
 	TInt iBurstSize;
 	/** PIL src/dst config flags.
 		@see TDmaTransferFlags
-	 */
+	*/
 	TUint32 iFlags;
 	/** Transfer synchronization flags.
 		@see TDmaTransferSyncFlags
@@ -450,19 +555,28 @@
 	/** Information passed to the PSL */
 	TUint iPslTargetInfo;
 	/** How often to repeat this (sub-)transfer:
-		0     no repeat (the default)
-		1..n  once / n times
+		 0     no repeat (the default)
+		 1..n  once / n times
 		-1     endlessly.
+
+		@prototype
 	*/
 	TInt iRepeatCount;
-	/** Structure contents delta vector (usage tbd) */
+	/** Structure contents delta vector.
+
+		(usage tbd)
+
+		@prototype
+	 */
 	TUint32 iDelta;
 	/** Reserved for future use */
 	TUint32 iReserved;
 
 private:
-	/** Private constructor. Initializes fields with the values passed in by
-		the legacy version of the DDmaRequest::Fragment() call.
+	/** Private constructor.
+
+		Initializes fields with the values passed in by the legacy version of
+		the DDmaRequest::Fragment() call.
 	*/
 	TDmaTransferConfig(TUint32 aAddr, TUint aFlags, TBool aAddrInc);
 	};
@@ -475,6 +589,8 @@
 	controller doesn't support hardware descriptors (scatter/gather LLI).
 
 	@see DDmaRequest::Fragment
+
+	@released
 */
 struct TDmaTransferArgs
 	{
@@ -483,17 +599,20 @@
 	friend class TDmac;
 	friend class DmaChannelMgr;
 
-	/** Default constructor. Initializes all fields with meaningful default
-		values.
+	/** Default constructor.
+
+		Initializes all fields with meaningful default values.
 	*/
 #ifdef DMA_APIV2
 	KIMPORT_C
 #endif
 	TDmaTransferArgs();
 
-	/**	For transfers where src and dst TDmaTransferConfig structs share some
-		of the same options ie. iDmaTransferFlags, iAddrMode, iSyncFlags,
-		iBurstSize, and iElementSize.
+	/**	Alternate constructor.
+
+		Intended for transfers where src and dst TDmaTransferConfig structs
+		share some of the same options, i.e. iDmaTransferFlags, iAddrMode,
+		iSyncFlags, iBurstSize, and iElementSize.
 
 		@param aSrcAddr
 		@param aDstAddr
@@ -513,17 +632,25 @@
 	KIMPORT_C
 #endif
 	TDmaTransferArgs (
-		TUint aSrcAddr, TUint aDstAddr, TUint aCount,
-		TUint aDmaTransferFlags, TUint aDmaSyncFlags = KDmaSyncAuto,
+		TUint aSrcAddr,
+		TUint aDstAddr,
+		TUint aCount,
+		TUint aDmaTransferFlags,
+		TUint aDmaSyncFlags = KDmaSyncAuto,
 		TUint aDmaPILFlags = 0,
-		TDmaAddrMode aMode = KDmaAddrModePostIncrement, TUint aElementSize = 0,
+		TDmaAddrMode aMode = KDmaAddrModePostIncrement,
+		TUint aElementSize = 0,
 		TUint aChannelPriority = KDmaPriorityNone,
-		TDmaBurstSize aBurstSize = KDmaBurstSizeAny, TUint aPslRequestInfo = 0,
-		TDmaGraphicsOps aGraphicOp = KDmaGraphicsOpNone, TUint32 aColour = 0
+		TDmaBurstSize aBurstSize = KDmaBurstSizeAny,
+		TUint aPslRequestInfo = 0,
+		TDmaGraphicsOps aGraphicOp = KDmaGraphicsOpNone,
+		TUint32 aColour = 0
 		);
 
-	/** For transfers needing specific options for source and destination
-		TDmaTransferConfig structs.
+	/** Alternate constructor.
+
+		Intended for transfers needing specific options for source and
+		destination TDmaTransferConfig structs.
 
 		@param aSrc Configuration values for the source
 		@param aDst Configuration values for the destination
@@ -531,7 +658,6 @@
 		@param aChannelPriority Use for this request (only) the indicated
 		channel priority. Requires KDmaRequestChannelPriority to be set in
 		iFlags as well. @see TDmaPriority
-
 		@param aPslRequestInfo Info word passed to the PSL
 		@param aGraphicOp Graphics operation to be executed
 		@param aColour Colour value for graphics operation
@@ -545,7 +671,8 @@
 		TUint32 aFlags = 0,
 		TUint aChannelPriority = KDmaPriorityNone,
 		TUint aPslRequestInfo = 0,
-		TDmaGraphicsOps aGraphicOp = KDmaGraphicsOpNone, TUint32 aColour = 0
+		TDmaGraphicsOps aGraphicOp = KDmaGraphicsOpNone,
+		TUint32 aColour = 0
 		);
 
 	/** Configuration values for the source */
@@ -580,25 +707,32 @@
 	TUint iChannelPriority;
 	/** Info word passed to the PSL */
 	TUint iPslRequestInfo;
+	/** Stores the PSL cookie returned by TDmaChannel::PslId() at request
+		fragmentation time.
 
-	/** Structure contents delta vector (usage tbd) */
+		The value PslId() is often (but not necessarily) identical with the
+		client's TDmaChannel::SCreateInfo::iCookie, which gets passed by the
+		PIL into DmaChannelMgr::Open() as 'aOpenId'.
+	*/
+	TUint32 iChannelCookie;
+	/** Structure contents delta vector.
+
+		(usage tbd)
+
+		@prototype
+	 */
 	TUint32 iDelta;
 	/** Reserved for future use */
 	TUint32 iReserved1;
 
 private:
-	/** Private constructor. Initializes fields with the values passed in by
-		the legacy version of the DDmaRequest::Fragment() call.
+	/** Private constructor.
+
+		Initializes fields with the values passed in by the legacy version of
+		the DDmaRequest::Fragment() call.
 	*/
 	TDmaTransferArgs(TUint32 aSrcAddr, TUint32 aDstAddr, TInt aCount,
 					 TUint aFlags, TUint32 aPslInfo);
-	/** Stores the PSL cookie returned by TDmaChannel::PslId() at request
-		fragmentation time.
-		The value PslId() is often (but not necessarily) identical with the
-		client's TDmaChannel::SCreateInfo::iCookie, which gets passed by the
-		PIL into DmaChannelMgr::Open() as 'aOpenId'.
-	*/
-	TUint32 iChannelCookie;
 	/** Reserved for future use */
 	TUint32 iReserved2;
 	};
@@ -609,24 +743,31 @@
 	Instances are to be filled in by the PSL and then linked to via TDmaChannel
 	objects after they have been opened.
 
-	The contents may vary even between channels on the same DMAC (but will
+	The contents may vary even between channels on the same DMAC (but should
 	remain constant for a given channel for the duration that it is open),
 	depending on static or dynamic factors which only the PSL knows about.
 
 	@see TDmaChannel::Open
 	@see TDmaChannel::DmacCaps
+
+	@released
 */
 struct SDmacCaps
 	{
-	/** DMAC supports n + 1 different channel priorities. */
+	/** DMAC supports n + 1 different channel priorities.
+	 */
 	TUint iChannelPriorities;
-	/** DMAC supports the pausing and resuming of channels. */
+	/** DMAC supports the pausing and resuming of channels.
+	 */
 	TBool iChannelPauseAndResume;
-	/** DMA addresses must be aligned on an element size boundary. */
+	/** DMA addresses must be aligned on an element size boundary.
+	 */
 	TBool iAddrAlignedToElementSize;
-	/** DMAC supports 1D (element) index addressing in hardware. */
+	/** DMAC supports 1D (element) index addressing in hardware.
+	 */
 	TBool i1DIndexAddressing;
-	/** DMAC supports 2D (frame) index addressing in hardware. */
+	/** DMAC supports 2D (frame) index addressing in hardware.
+	 */
 	TBool i2DIndexAddressing;
 	/** DMAC supports these transfer synchronization types (bitmap of values).
 
@@ -638,24 +779,31 @@
 		@see TDmaBurstSize
 	*/
 	TUint iBurstTransactions;
-	/** DMAC supports a 'h/w descriptor complete' interrupt. */
+	/** DMAC supports a 'h/w descriptor complete' interrupt.
+	 */
 	TBool iDescriptorInterrupt;
-	/** DMAC supports a 'frame transfer complete' interrupt. */
+	/** DMAC supports a 'frame transfer complete' interrupt.
+	 */
 	TBool iFrameInterrupt;
-	/** DMAC supports a 'linked-list pause event' interrupt. */
+	/** DMAC supports a 'linked-list pause event' interrupt.
+	 */
 	TBool iLinkedListPausedInterrupt;
-	/** DMAC supports endianness conversion. */
+	/** DMAC supports endianness conversion.
+	 */
 	TBool iEndiannessConversion;
 	/** DMAC supports these graphics operations (bitmap of values).
 
 		@see TDmaGraphicsOps
 	*/
 	TUint iGraphicsOps;
-	/** DMAC supports repeated transfers (loops). */
+	/** DMAC supports repeated transfers (loops).
+	 */
 	TBool iRepeatingTransfers;
-	/** DMAC supports logical channel linking (chaining). */
+	/** DMAC supports logical channel linking (chaining).
+	 */
 	TBool iChannelLinking;
-	/** DMAC supports scatter/gather mode (linked list items). */
+	/** DMAC supports scatter/gather mode (linked list items).
+	 */
 	TBool iHwDescriptors;
 	/** DMAC supports asymmetric source and destination transfer
 		parameters (such as element size).
@@ -712,10 +860,51 @@
 	};
 
 
+//////////////////////////////////////////////////////////////////////////////
+// INTERFACE WITH TEST HARNESS
+//////////////////////////////////////////////////////////////////////////////
+
+/** Set of information used by test harness.
+
+	@deprecated
+*/
+#ifdef DMA_APIV2
+struct TDmaTestInfo
+	{
+	/** Maximum transfer size in bytes for all channels (ie. the minimum of all
+		channels' maximum size)
+	*/
+	TUint iMaxTransferSize;
+	/** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
+	TUint iMemAlignMask;
+	/** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer */
+	TUint32 iMemMemPslInfo;
+	/** Number of test single-buffer channels */
+	TInt iMaxSbChannels;
+	/** Pointer to array containing single-buffer test channel ids */
+	TUint32* iSbChannels;
+	/** Number of test double-buffer channels */
+	TInt iMaxDbChannels;
+	/** Pointer to array containing double-buffer test channel ids */
+	TUint32* iDbChannels;
+	/** Number of test scatter-gather channels */
+	TInt iMaxSgChannels;
+	/** Pointer to array containing scatter-gather test channel ids */
+	TUint32* iSgChannels;
+	};
+#endif
+
+
+/** Set of information used by test harness.
+
+	@released
+*/
 struct TDmaV2TestInfo
 	{
 	enum {KMaxChannels=32};
-	/** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/
+	/** Maximum transfer size in bytes for all channels (ie. the minimum of all
+		channels' maximum size)
+	*/
 	TUint iMaxTransferSize;
 	/** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
 	TUint iMemAlignMask;
--- a/kernel/eka/include/e32ver.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/e32ver.h	Tue May 04 09:44:26 2010 +0100
@@ -28,7 +28,7 @@
 
 const TInt KE32MajorVersionNumber=2;
 const TInt KE32MinorVersionNumber=0;
-const TInt KE32BuildVersionNumber=3074;
+const TInt KE32BuildVersionNumber=3075;
 
 const TInt KMachineConfigurationMajorVersionNumber=1;
 const TInt KMachineConfigurationMinorVersionNumber=0;
--- a/kernel/eka/include/kernel/kernel.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/include/kernel/kernel.h	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1994-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"
@@ -229,7 +229,6 @@
 
 
 const TUint8 KMutexOrdRamDrive			= KMutexOrdGeneral7; /**< @internalComponent */
-const TUint8 KMutexOrdDmaChannel		= 0x70; /**< @internalComponent */
 const TUint8 KMutexOrdShPool			= 0x68; /**< @internalComponent */
 const TUint8 KMutexOrdCodeSegLock		= 0x60; /**< @internalComponent */
 const TUint8 KMutexOrdPubSub2			= 0x5e; /**< @internalComponent */
--- a/kernel/eka/release.txt	Thu Apr 29 11:08:53 2010 +0100
+++ b/kernel/eka/release.txt	Tue May 04 09:44:26 2010 +0100
@@ -1,3 +1,12 @@
+Version 2.00.3075
+=================
+(Made by vfebvre 29/04/2010)
+
+1.	seolney
+	1.	REQ417-52838 Upgrade DMA API to support advanced addressing modes
+		PackageReleaseID=485812 FeaturePlanID=428985
+
+
 Version 2.00.3074
 =================
 (Made by vfebvre 28/04/2010)
--- a/kerneltest/e32test/dmav2/d_dma2.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/d_dma2.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -55,7 +55,7 @@
 			}
 		return FastCountToMicroSecs(diff);
 #else
-		//TODO On SMP it is possible for the value returned from
+		//On SMP it is possible for the value returned from
 		//NKern::FastCounter to depend on the current CPU (ie.
 		//NaviEngine)
 		//
@@ -100,6 +100,7 @@
 	TInt DoGetInfo(TAny* aInfo);
 
 	TInt OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie);
+	TInt OpenDmaChannel(TUint& aDriverCookie, TDmaChannel::SCreateInfo& aInfo);
 	TInt CloseDmaChannelByCookie(TUint aDriverCookie);
 	TInt PauseDmaChannelByCookie(TUint aDriverCookie);
 	TInt ResumeDmaChannelByCookie(TUint aDriverCookie);
@@ -127,9 +128,6 @@
 	*/
 	TInt CreateDmaRequest(TUint aChannelCookie, TUint& aRequestCookie, TBool aNewCallback = EFalse, TInt aMaxFragmentSizeBytes=0);
 
-	//TODO what happens if a client closes a channel that
-	//it still has dma requests associated with?
-	
 	/**
 	Destroys a previously created dma request object
 	*/
@@ -141,7 +139,7 @@
 	TInt CookieToChannelIndex(TUint aDriverCookie) const;
 	TInt CookieToRequestIndex(TUint aRequestCookie) const;
 
-	void FixupTransferArgs(TDmaTransferArgs& aTransferArgs) const;
+	void MakeAddressesAbsoulute(TDmaTransferArgs& aTransferArgs) const;
 	TInt FragmentRequest(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TBool aLegacy=ETrue);
 
 	TInt QueueRequest(TUint aRequestCookie, TRequestStatus* aStatus, TCallbackRecord* aRecord, TUint64* aDurationMicroSecs);
@@ -177,6 +175,19 @@
 	TUint64 GetDuration()
 		{return iStopwatch.ReadMicroSecs();}
 
+	/**
+	Store a copy of the TDmaTransferArgs which was used for fragmentation
+	for argument checking
+	*/
+	void SetAddressParms(const TDmaTransferArgs& aAddressParms)
+		{iFragmentedTransfer = aAddressParms;}
+
+	/**
+	Retrieve stored TDmaTransferArgs
+	*/
+	const TDmaTransferArgs& GetAddressParms() const
+		{return iFragmentedTransfer;}
+
 protected:
 	TInt Create();
 	/** Construct with old style callback */
@@ -202,6 +213,13 @@
 
 	TStopwatch iStopwatch;
 	TIsrRequeArgsSet iIsrRequeArgSet;
+
+	/**
+	This will be updated each time fragment is called.
+	It is required so that, at queue time, if ISR re-queue
+	arguments are added, they can be checked for sanity
+	*/
+	TDmaTransferArgs iFragmentedTransfer;
 	};
 
 DClientDmaRequest* DClientDmaRequest::Construct(DThread* aClient, TDfcQue* const aDfcQ, TDmaChannel& aChannel, TBool aNewStyle, TInt aMaxTransferSize)
@@ -341,38 +359,7 @@
 #endif
 	}
 
-/**
-Check that both source and destination of ISR reque args will
-lie within the range specified by aStart and aSize.
-
-@param aStart The linear base address of the region
-@param aSize The size of the region
-*/
-TBool TIsrRequeArgs::CheckRange(TLinAddr aStart, TUint aSize) const
-	{
-	TUint physStart = Epoc::LinearToPhysical(aStart);
-	TEST_ASSERT(physStart != KPhysAddrInvalid);
-
-	TAddrRange chunk(physStart, aSize);
-	TBool sourceOk = (iSrcAddr == KPhysAddrInvalid) ? ETrue : chunk.Contains(SourceRange());
-
-	TBool destOk = (iDstAddr == KPhysAddrInvalid) ? ETrue : chunk.Contains(DestRange());
-
-	return sourceOk && destOk;
-	}
-
-TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize) const
-	{
-	for(TInt i=0; i<iCount; i++)
-		{
-		if(!iRequeArgs[i].CheckRange(aAddr, aSize))
-			return EFalse;
-		}
-	return ETrue;
-	}
-
-/**
-Translate an old style dma callback to a new-style one
+/** Translate an old style dma callback to a new-style one
 */
 void DClientDmaRequest::CallbackOldStyle(TResult aResult, TAny* aArg)
 	{
@@ -431,7 +418,9 @@
 		self.iDfc.Add();
 		break;
 		}
-	case NKern::EIDFC: //fall-through
+	//Fall-through: If context is IDFC or the EEscaped marker occur
+	//it is an error
+	case NKern::EIDFC:
 	case NKern::EEscaped:
 	default:
 		TEST_FAULT;
@@ -593,10 +582,34 @@
 			{
 			TUint pslCookie = (TUint)a1;
 			TUint driverCookie = 0;
-			TInt r = OpenDmaChannel(pslCookie, driverCookie);	
+			TInt r = OpenDmaChannel(pslCookie, driverCookie);
 			umemput32(a2, &driverCookie, sizeof(TAny*));
 			return r;
 			}
+	case RDmaSession::EOpenChannelExposed:
+			{
+			TDmaChannel::SCreateInfo openInfo;
+			TUint driverCookie = 0;
+
+			TPckgBuf<SCreateInfoTest> openArgsBuf;
+			Kern::KUDesGet(openArgsBuf, *reinterpret_cast<TDes8*>(a2));
+
+			SCreateInfoTest& openTestInfo = openArgsBuf();
+			openInfo.iCookie = openTestInfo.iCookie;
+			openInfo.iDesCount = openTestInfo.iDesCount;
+			openInfo.iDfcQ = iDfcQ;
+			openInfo.iDfcPriority = openTestInfo.iDfcPriority;
+
+			#ifdef DMA_APIV2
+				openInfo.iPriority = openTestInfo.iPriority;
+				openInfo.iDynChannel = openTestInfo.iDynChannel;
+			#endif
+
+			TInt r = OpenDmaChannel(driverCookie, openInfo);
+			umemput32(a1, &driverCookie, sizeof(TAny*));
+			Kern::KUDesPut(*reinterpret_cast<TDes8*>(a2), openArgsBuf);
+			return r;
+			}
 	case RDmaSession::ECloseChannel:
 			{
 			TUint driverCookie = reinterpret_cast<TUint>(a1);
@@ -660,11 +673,15 @@
 			TDmaTransferArgs& transferArgs = const_cast<TDmaTransferArgs&>(argsBuff().iTransferArgs);
 
 			//convert address offsets in to kernel virtual addresses
-			FixupTransferArgs(transferArgs);
-
-			TEST_ASSERT((TAddressParms(transferArgs).CheckRange(iChunkBase, iChunk->Size())));
+			MakeAddressesAbsoulute(transferArgs);
 
 			TInt r = KErrGeneral;
+			if (!TAddressParms(transferArgs).CheckRange(iChunkBase, iChunk->Size()))
+			{
+				// Return error code for invalid src and destination arguments used in tranferArgs
+				r=KErrArgument;
+				return r;
+			}
 
 			TStopwatch clock;
 			clock.Start();
@@ -708,7 +725,6 @@
 			}	
 	case RDmaSession::EQueueRequestWithReque:
 			{
-			//TODO can common code with EQueueRequest be extracted?
 			TPckgBuf<RDmaSession::TQueueArgsWithReque> argsBuff;
 			Kern::KUDesGet(argsBuff, *reinterpret_cast<TDes8*>(a1));
 
@@ -723,13 +739,11 @@
 			DClientDmaRequest* const request = RequestFromCookie(requestCookie);
 			if(request != NULL)
 				{
-				argsBuff().iRequeSet.Fixup(iChunkBase);
-				//TODO reque args must be substituted in order to
-				//check the range. The original transfer args are not
-				//available when queue is called, they could
-				//however be stored within DClientDmaRequest
-				//TEST_ASSERT((argsBuff().iRequeSet.CheckRange(iChunkBase, iChunk->Size())));
-				request->AddRequeArgs(argsBuff().iRequeSet);
+				TIsrRequeArgsSet& requeArgs = argsBuff().iRequeSet;
+				requeArgs.Fixup(iChunkBase);
+
+				TEST_ASSERT(requeArgs.CheckRange(iChunkBase, iChunk->Size(), request->GetAddressParms() ));
+				request->AddRequeArgs(requeArgs);
 
 				r = QueueRequest(requestCookie, requestStatus, callbackRec, duration);
 				}
@@ -740,21 +754,6 @@
 				}
 			return r;
 			}
-	case RDmaSession::EIsrRedoRequest:
-			{
-			TPckgBuf<RDmaSession::TIsrRedoReqArgs> argsBuff;
-			Kern::KUDesGet(argsBuff, *reinterpret_cast<TDes8*>(a1));
-
-			const TUint driverCookie = argsBuff().iDriverCookie;
-			const TUint32 srcAddr = argsBuff().iSrcAddr;
-			const TUint32 dstAddr = argsBuff().iDstAddr;
-			const TInt transferCount = argsBuff().iTransferCount;
-			const TUint32 pslRequestInfo = argsBuff().iPslRequestInfo;
-			const TBool isrCb = argsBuff().iIsrCb;
-
-			TInt r = IsrRedoRequestByCookie(driverCookie,srcAddr,dstAddr,transferCount,pslRequestInfo,isrCb);
-			return r;
-			}
 	case RDmaSession::EIsOpened:
 			{
 			TUint driverCookie = (TUint)a1;
@@ -797,29 +796,21 @@
 		}
 	}
 
-TInt DDmaTestSession::OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie )
+TInt DDmaTestSession::OpenDmaChannel(TUint& aDriverCookie, TDmaChannel::SCreateInfo& aInfo)
 	{
-	TDmaChannel::SCreateInfo info;
-	info.iCookie = aPslCookie;
-	info.iDfcQ = iDfcQ;
-	info.iDfcPriority = 3;
-	info.iDesCount = 128;
-
-	TDmaChannel* channel = NULL;
-
 	//cs so thread can't be killed between
 	//opening channel and adding to array
 	NKern::ThreadEnterCS();
-	TInt r = TDmaChannel::Open(info, channel);
+	TDmaChannel* channel = NULL;
+	TInt r = TDmaChannel::Open(aInfo, channel);
 	if(KErrNone == r)
 		{
 		__NK_ASSERT_ALWAYS(channel);
-		
-		__KTRACE_OPT(KDMA, Kern::Printf("OpenDmaChannel: channel@ 0x%08x", channel)); 
+
+		__KTRACE_OPT(KDMA, Kern::Printf("OpenDmaChannel: channel@ 0x%08x", channel));
 
-
-		TInt err = iChannels.Append(channel);
-		if(KErrNone == err)
+		r = iChannels.Append(channel);
+		if(KErrNone == r)
 			{
 			aDriverCookie = reinterpret_cast<TUint>(channel);
 			}
@@ -834,6 +825,20 @@
 	return r;
 	}
 
+/**
+Open a DMA channel with arbitrary default parameters
+*/
+TInt DDmaTestSession::OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie )
+	{
+	TDmaChannel::SCreateInfo info;
+	info.iCookie = aPslCookie;
+	info.iDfcQ = iDfcQ;
+	info.iDfcPriority = 3;
+	info.iDesCount = 128;
+
+	return OpenDmaChannel(aDriverCookie, info);
+	}
+
 TInt DDmaTestSession::CookieToChannelIndex(TUint aDriverCookie) const
 	{
 	const TInt r = iChannels.Find(reinterpret_cast<TDmaChannel*>(aDriverCookie));
@@ -906,8 +911,7 @@
 	__KTRACE_OPT(KDMA, Kern::Printf("CancelAllByIndex: %d", aIndex)); 
 	__NK_ASSERT_DEBUG(aIndex < iChannels.Count()); 
 	
-	TDmaChannel* channel = iChannels[aIndex];
-	iChannels.Remove(aIndex);
+	TDmaChannel* channel = iChannels[aIndex];	
 	channel->CancelAll();
 	}
 
@@ -1188,7 +1192,11 @@
 	return r;
 	}
 
-void DDmaTestSession::FixupTransferArgs(TDmaTransferArgs& aTransferArgs) const
+/**
+Replace addresses specified as an offset from the chunk base with absolute
+virtual addresses.
+*/
+void DDmaTestSession::MakeAddressesAbsoulute(TDmaTransferArgs& aTransferArgs) const
 	{
 	aTransferArgs.iSrcConfig.iAddr += iChunkBase;
 	aTransferArgs.iDstConfig.iAddr += iChunkBase;
@@ -1225,23 +1233,29 @@
 	if(requestIndex < 0)
 		return requestIndex;
 
+	DClientDmaRequest& request = *iClientDmaReqs[requestIndex];
+	request.SetAddressParms(aTransferArgs);
+
 	TInt r = KErrNotSupported;
+
+	if (aTransferArgs.iTransferCount < 1)
+		{
+		// Return error code for invalid transfer size used in tranferArgs
+		r=KErrArgument;
+		return r;
+		}
+
 	if(aLegacy)
 		{
-		// TODO we can extract the required info from the struct to
-		// set flags
 		TUint flags = KDmaMemSrc | KDmaIncSrc | KDmaMemDest | KDmaIncDest;
-
 		const TUint src = aTransferArgs.iSrcConfig.iAddr;
 		const TUint dst = aTransferArgs.iDstConfig.iAddr;
-		r = iClientDmaReqs[requestIndex]->Fragment(src, dst, aTransferArgs.iTransferCount, flags, NULL);
+		r = request.Fragment(src, dst, aTransferArgs.iTransferCount, flags, NULL);
 		}
 	else
 		{
 #ifdef DMA_APIV2
-		r = iClientDmaReqs[requestIndex]->Fragment(aTransferArgs);
-#else
-		r = KErrNotSupported;
+		r = request.Fragment(aTransferArgs);
 #endif
 		}
 	return r;
@@ -1296,9 +1310,6 @@
 	for(TInt i=0; i<aOldInfo.iMaxSgChannels; i++)
 		newInfo.iSgChannels[i] = aOldInfo.iSgChannels[i];
 
-	//TODO will want to add initialisation for Asym channels
-	//when these are available
-
 	return newInfo;
 	}
 //////////////////////////////////////////////////////////////////////////////
@@ -1321,8 +1332,7 @@
 DDmaTestFactory::DDmaTestFactory()
     {
     iVersion = TestDmaLddVersion();
-    iParseMask = KDeviceAllowUnit;							// no info, no PDD
-    // iUnitsMask = 0;										// Only one thing
+    iParseMask = KDeviceAllowUnit;							// no info, no PDD    
     }
 
 
--- a/kerneltest/e32test/dmav2/d_dma2.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/d_dma2.h	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -30,11 +30,13 @@
 	#include <kernel.h>
 	#define TEST_FAULT FAULT();
 	#define PRINT(N) Kern::Printf("%s = 0x%08x (%d)", #N, (N), (N))
+	#define PRINTF(X) Kern::Printf X ;
 #else
 	#include <e32std.h>
 	#include <e32debug.h>
-	#define TEST_FAULT RDebug::Printf("Assertion failure in %s, %d", __FILE__, __LINE__); User::Invariant()
+	#define TEST_FAULT {RDebug::Printf("Assertion failure in %s, %d", __FILE__, __LINE__); User::Invariant();}
 	#define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N))
+	#define PRINTF(X) RDebug::Printf X ;
 #endif
 
 #define TEST_ASSERT(C) if(!(C)) {TEST_FAULT;}
@@ -44,8 +46,21 @@
 //if this fails then KPhysAddrInvalidUser must be updated to match
 //KPhysAddrInvalid
 __ASSERT_COMPILE(KPhysAddrInvalidUser == KPhysAddrInvalid);
+#else
+const TUint KPhysAddrInvalid = KPhysAddrInvalidUser;
 #endif
 
+#ifdef __KERNEL_MODE__
+//Function to format the output.
+inline void DmaAppendFormat(TDes8& aBuf, const char* aFmt, ...)
+	{
+	if(!(&aBuf))
+		return;
+	VA_LIST list;
+	VA_START(list,aFmt);
+	Kern::AppendFormat(aBuf,aFmt,list);
+	}
+#endif
 
 _LIT(KTestDmaLddName, "TestDmaV2");
 
@@ -57,7 +72,7 @@
 Indicates the number of each type of call back received
 and their context
 
-TODO as yet, it does not indicate the context of each callback, only
+@note It does not indicate the context of each callback, only
 the final one
 */
 const TInt KNumberOfCallbacks = 12;
@@ -157,6 +172,63 @@
 	};
 
 
+/** SCreateInfo for opening DMA - Reused for testing */
+struct SCreateInfoTest
+		{
+		/** Default constructor. Initializes all fields with meaningful default
+			values.
+
+			Must be inline (for now) because exporting it would break existing
+			custom DMA libs as their clients would need the export which would
+			be missing from the custom .def files.
+		*/
+		SCreateInfoTest() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {};
+
+		/** Identifier used by PSL to select channel to open */
+		TUint32 iCookie;
+		/** Number of descriptors this channel can use.
+
+			This number is not used in the upgraded version of the DMA
+			framework and is kept there only for source compatibility. If the
+			client is certain that it will only ever use that version, then the
+			value passed here doesn't matter - the framework will ignore it.
+
+			@deprecated
+		 */
+		TInt iDesCount;
+		/** DFC queue used to service DMA interrupts.
+
+			The DFC thread priority must be higher than any client thread
+			priority to avoid a situation where a transfer completes while
+			being cancelled and another transfer is started before the DFC
+			thread gets a chance to run. This would lead to a stray DFC.
+		*/
+		//TDfcQue* iDfcQ;
+
+		TAny* iDfcQ;
+
+		/** DFC priority */
+		TUint8 iDfcPriority;
+		/** Used by PSL to configure a channel priority (if possible).
+
+			The default is KDmaPriorityNone (the don't care value).
+
+		    @see TDmaPriority
+		*/
+		TUint iPriority;
+		/** Request a dynamic DMA channel.
+
+			If this is set to ETrue then the Open call is for a 'dynamic' as
+			opposed to a static and solely owned DMA channel. A number of
+			properties of the opened TDmaChannel object will be different in
+			that case.
+
+			The default value is EFalse.
+		 */
+		TBool iDynChannel;
+		};
+
+
 class TDmaChannel;
 
 struct TAddrRange
@@ -169,6 +241,8 @@
 	TBool Contains(TAddrRange aRange) const;
 
 	TBool Overlaps(const TAddrRange& aRange) const;
+	TBool IsFilled(TUint8 aValue) const;
+
 	static void SelfTest();
 
 private:
@@ -190,13 +264,21 @@
 		{}
 
 	/**
-	If any src, dst, or transfer count are zero, substitute the values from
-	aTransferArgs in their place
+	If addresses have been left as KPhysAddrInvalid or the count as 0 (ie.
+	the default values used for IsrRedoRequest) then substitute the values from
+	aTransferArgs.
 	*/
 	void Substitute(const TDmaTransferArgs& aTransferArgs);
 
 	/**
-	When recieved by the test driver, src and dst
+	If addresses have been left as KPhysAddrInvalid or the count as 0 (ie.
+	the default values used for IsrRedoRequest) then substitute the values from
+	aTransferArgs.
+	*/
+	void Substitute(const TAddressParms& aTransferArgs);
+
+	/**
+	When received by the test driver, src and dst
 	addresses will be offsets from the dma test session's
 	chunk base. They must be converted to absolute, *physical* addresses
 	*/
@@ -216,6 +298,22 @@
 
 	TBool operator==(const TAddressParms& aOther) const;
 
+
+	/**
+	Produce a printable representation
+	*/
+	void AppendString(TDes& aBuf) const
+		{
+		_LIT(KOutput, "TAddressParms: src=0x%08x (%d) dst=0x%08x (%d) count=0x%08x (%d)\0");
+#ifdef __KERNEL_MODE__
+		DmaAppendFormat(aBuf, (const char*)KOutput().Ptr(), iSrcAddr, iSrcAddr, iDstAddr, iDstAddr, iTransferCount, iTransferCount);
+#else
+		aBuf.AppendFormat(KOutput, iSrcAddr, iSrcAddr, iDstAddr, iDstAddr, iTransferCount, iTransferCount);
+#endif
+		}
+
+	void MakePhysical();
+
 	static void SelfTest();
 
 	TUint32 iSrcAddr;
@@ -255,8 +353,7 @@
 */
 struct TIsrRequeArgsSet
 	{
-
-	friend class CIsrRequeTest; //TODO see line 394 t_dma2.cpp
+	friend class CIsrRequeTest;
 	TIsrRequeArgsSet(TIsrRequeArgs* aRequeueArgs=NULL, TInt aCount =0)
 		:iCount(aCount), iIndex(0)
 		{
@@ -273,10 +370,26 @@
 
 	TIsrRequeArgs GetArgs();
 
+	/**
+	If addresses have been left as KPhysAddrInvalid or the count as 0 (ie.
+	the default values used for IsrRedoRequest) then substitute the appropriate
+	value from the previous argument struct. aTransferArgs is used to
+	substitute values for the initial argument struct.
+	*/
 	void Substitute(const TDmaTransferArgs& aTransferArgs);
 	void Fixup(TLinAddr aChunkBase);
 	TBool CheckRange(TLinAddr aAddr, TUint aSize) const;
 
+	/**
+	Check that all re-queue parameters will remain within the region defined
+	by aAddr and aSize. This overload assumes that the requeue parameters have
+	not been substituted hence the data in aInitialParms is required.
+
+	@param aInitialParms The original transfer that the re-queues in this set are based on
+	*/
+	TBool CheckRange(TLinAddr aAddr, TUint aSize, const TDmaTransferArgs& aInitialParms) const;
+
+	static void SelfTest();
 private:
 	enum {MaxCount=6};
 	TInt iCount;
@@ -300,13 +413,6 @@
 		return DoControl(EIsOpened, reinterpret_cast<TAny*>(aDriverCookie), &aChannelOpen);		
 		}
 
-	TInt ChannelIsrRedoRequest(TUint aDriverCookie,TUint32 aSrcAddr,TUint32 aDstAddr,TInt aTransferCount,TUint32 aPslRequestInfo,TBool aIsrCb)
-		{
-		TIsrRedoReqArgs args(aDriverCookie,aSrcAddr,aDstAddr,aTransferCount,aPslRequestInfo,aIsrCb);
-		TPckgC<TIsrRedoReqArgs> package(args);
-		return DoControl(EIsrRedoRequest,&package);
-		}
-
 	TInt ChannelCancelAll(TUint aDriverCookie)
 		{	
 		return DoControl(ECancelAllChannel, reinterpret_cast<TAny*>(aDriverCookie));
@@ -317,6 +423,12 @@
 		return DoControl(EOpenChannel, reinterpret_cast<TAny*>(aPslCookie), &aDriverCookie);
 		}
 
+	TInt ChannelOpen(TUint& aDriverCookie, SCreateInfoTest& aInfo)
+		{
+		TPckg<SCreateInfoTest> package(aInfo);
+		return DoControl(EOpenChannelExposed,&aDriverCookie, &package);
+		}
+
 	TInt ChannelClose(TUint aDriverCookie)
 		{	
 		return DoControl(ECloseChannel, reinterpret_cast<TAny*>(aDriverCookie));
@@ -347,23 +459,18 @@
 		}
 	
 	TInt Open()
-		{// TO DO: Add Info , this  class is just to test the opening of channels
-		//TPckgBuf<TOpenInfo> infoBuf;
-		//infoBuf().iWhat = TOpenInfo::EOpen;
-		//infoBuf().U.iOpen.iId = aId;
-		//infoBuf().U.iOpen.iDesCount = aDesCount;
-		//infoBuf().U.iOpen.iMaxTransferSize = aMaxTransferSize;
+		{
 		return DoCreate(KTestDmaLddName,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread);
 		}
 
-	//TODO rename this (append "old")
-	TInt RequestCreate(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0)
+
+	TInt RequestCreateOld(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0)
 		{	
 		return DoRequestCreate(aChannelCookie, EFalse, aMaxTransferSize, aRequestCookie);
 		}
 
-	//TODO rename this (get rid of "new"
-	TInt RequestCreateNew(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0)
+
+	TInt RequestCreate(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0)
 		{
 		return DoRequestCreate(aChannelCookie, ETrue, aMaxTransferSize, aRequestCookie);
 		}
@@ -407,6 +514,8 @@
 		TCallbackRecord dummyRec;
 		TUint64 dummyTime=0;
 
+		aStatus = KRequestPending;
+
 		TQueueArgs args(aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime);
 		TPckgC<TQueueArgs> package(args);
 		return DoControl(EQueueRequest, &package);
@@ -439,6 +548,8 @@
 		TCallbackRecord dummyRec;
 		TUint64 dummyTime=0;
 
+		aStatus = KRequestPending;
+
 		TQueueArgsWithReque args(aRequeueArgs, aCount, aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime);
 		TPckgC<TQueueArgsWithReque> package(args);
 		return DoControl(EQueueRequestWithReque, &package);
@@ -518,19 +629,6 @@
 		TUint64* iDurationMicroSecs;
 		};
 
-	struct TIsrRedoReqArgs 	
-		{
-		TIsrRedoReqArgs(TUint aDriverCookie=0,TUint32 aSrcAddr=0, TUint32 aDstAddr=0, TInt aTransferCount=0, TUint32 aPslRequestInfo=0,TBool aIsrCb=ETrue)
-			:iDriverCookie(aDriverCookie),iSrcAddr(aSrcAddr),iDstAddr(aDstAddr),iTransferCount(aTransferCount),iPslRequestInfo(aPslRequestInfo),iIsrCb(aIsrCb)
-			{}
-		TUint iDriverCookie;
-		TUint32 iSrcAddr;
-		TUint32 iDstAddr;
-		TInt iTransferCount;
-		TUint32 iPslRequestInfo;
-		TBool iIsrCb;
-		};
-
 	/**
 	This struct is used for queing and including a set of transfers
 	to be setup from ISR context callback
@@ -546,10 +644,10 @@
 		TIsrRequeArgsSet iRequeSet;
 		};
 
-
 	enum TControl
 		{
 		EOpenChannel,
+		EOpenChannelExposed,
 		ECloseChannel,
 		EPauseChannel,
 		EResumeChannel,
--- a/kerneltest/e32test/dmav2/d_dma2_cmn.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/d_dma2_cmn.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
@@ -133,7 +133,9 @@
 		return EThread;
 	case NKern::EInterrupt:
 		return EIsr;
-	case NKern::EIDFC: //fall-through
+	//Fall-through: If context is IDFC or the EEscaped marker occur
+	//it is an error
+	case NKern::EIDFC:
 	case NKern::EEscaped:
 	default:
 		return EInvalid;
@@ -175,7 +177,6 @@
 TAddrRange::TAddrRange(TUint aStart, TUint aLength)
 	:iStart(aStart), iLength(aLength)
 	{
-	TEST_ASSERT(iLength > 0);
 	}
 
 TBool TAddrRange::Contains(TAddrRange aRange) const
@@ -188,21 +189,43 @@
 	return (aRange.Contains(iStart) || aRange.Contains(End()) ||
 			Contains(aRange.Start()) || Contains(aRange.End()));
 	}
+
+TBool TAddrRange::IsFilled(TUint8 aValue) const
+	{
+	TUint8* buffer = reinterpret_cast<TUint8*>(iStart);
+	for(TUint i = 0; i < iLength; i++)
+		{
+		if(buffer[i] != aValue)
+			return EFalse;
+		}
+	return ETrue;
+	}
+
 /**
-If addresses have been left as KPhysAddrInvalid or the count as 0
-(ie. the default values used for IsrRedoRequest)
-then substitute the values from aTransferArgs.
+If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. the
+default values used for IsrRedoRequest) then substitute the values from
+aTransferArgs.
 */
 void TAddressParms::Substitute(const TDmaTransferArgs& aTransferArgs)
 	{
+	Substitute(GetAddrParms(aTransferArgs));
+	}
+
+/**
+If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. the
+default values used for IsrRedoRequest) then substitute the values from
+aTransferArgs.
+*/
+void TAddressParms::Substitute(const TAddressParms& aAddrParams)
+	{
 	if(iSrcAddr == KPhysAddrInvalidUser)
-		iSrcAddr = aTransferArgs.iSrcConfig.iAddr;
+		iSrcAddr = aAddrParams.iSrcAddr;
 
 	if(iDstAddr == KPhysAddrInvalidUser)
-		iDstAddr = aTransferArgs.iDstConfig.iAddr;
+		iDstAddr = aAddrParams.iDstAddr;
 
 	if(iTransferCount == 0)
-		iTransferCount = aTransferArgs.iTransferCount;
+		iTransferCount = aAddrParams.iTransferCount;
 	}
 
 /**
@@ -295,6 +318,18 @@
 	return TAddrRange(iDstAddr, iTransferCount);
 	}
 
+void TAddressParms::MakePhysical()
+	{
+#ifdef __KERNEL_MODE__
+	iSrcAddr = Epoc::LinearToPhysical(iSrcAddr);
+	TEST_ASSERT(iSrcAddr != KPhysAddrInvalid);
+	iDstAddr = Epoc::LinearToPhysical(iDstAddr);
+	TEST_ASSERT(iDstAddr != KPhysAddrInvalid);
+#else
+	TEST_FAULT;
+#endif
+	}
+
 void SetAddrParms(TDmaTransferArgs& aTransferArgs, const TAddressParms& aAddrParams)
 	{
 	aTransferArgs.iSrcConfig.iAddr = aAddrParams.iSrcAddr;
@@ -311,14 +346,27 @@
 	return args;
 	}
 
-
 void TIsrRequeArgsSet::Substitute(const TDmaTransferArgs& aTransferArgs)
 	{
+	TAddressParms initial(aTransferArgs);
+
+	//if on user side it is assumed that aTransferArgs addresses will be offset
+	//based (from a virtual address). In kernel mode it is expected that address
+	//will be absolute virtual addresses, and must therefore be made physical
+#ifdef __KERNEL_MODE__
+	initial.MakePhysical();
+#endif
+
+	const TAddressParms* previous = &initial;
+
 	for(TInt i=0; i<iCount; i++)
 		{
-		iRequeArgs[i].Substitute(aTransferArgs);
+		TAddressParms& current = iRequeArgs[i];
+		current.Substitute(*previous);
+		previous = &current;
 		}
 	}
+
 void TIsrRequeArgsSet::Fixup(TLinAddr aChunkBase)
 	{
 	for(TInt i=0; i<iCount; i++)
@@ -326,3 +374,58 @@
 		iRequeArgs[i].Fixup(aChunkBase);
 		}
 	}
+
+/** Check that both source and destination of ISR reque args will lie within the
+range specified by aStart and aSize.
+
+@param aStart The linear base address of the region
+@param aSize The size of the region
+*/
+TBool TIsrRequeArgs::CheckRange(TLinAddr aStart, TUint aSize) const
+	{
+	TUint chunkStart = 0;
+#ifdef __KERNEL_MODE__
+	chunkStart = Epoc::LinearToPhysical(aStart);
+	TEST_ASSERT(chunkStart != KPhysAddrInvalid);
+#else
+	chunkStart = aStart;
+#endif
+
+	// If an address is still KPhysAddrInvalid it means the arguments haven't
+	// yet been substituted
+	TAddrRange chunk(chunkStart, aSize);
+	TBool sourceOk = (iSrcAddr != KPhysAddrInvalid) && chunk.Contains(SourceRange());
+
+	TBool destOk = (iDstAddr != KPhysAddrInvalid) && chunk.Contains(DestRange());
+
+	TBool ok = sourceOk && destOk;
+	if(!ok)
+		{
+		PRINTF(("Error, re-queue args: "));
+		TBuf<128> buf;
+		AppendString(buf);
+		PRINTF(("%S", &buf));
+		PRINTF(("overflow buffer base=0x%08x, size=0x%08x", chunkStart, aSize));
+		}
+	return ok;
+	}
+
+TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize) const
+	{
+	for(TInt i=0; i<iCount; i++)
+		{
+		if(!iRequeArgs[i].CheckRange(aAddr, aSize))
+			return EFalse;
+		}
+	return ETrue;
+	}
+
+TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize, const TDmaTransferArgs& aInitialParms) const
+	{
+	// apply substitution, without modifying the original
+	TIsrRequeArgsSet copy(*this);
+	copy.Substitute(aInitialParms);
+
+	return copy.CheckRange(aAddr, aSize);
+	}
+
--- a/kerneltest/e32test/dmav2/dma_api_tests.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "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:
-// e32test\dma\dma_api_tests.cpp
-// 
-// Overview:
-//  This file contains API tests for the new DMA framework
-//
-
-#define __E32TEST_EXTENSION__
-#include "d_dma2.h"
-#include "u32std.h"
-#include "t_dma2.h"
-#include "cap_reqs.h"
-
-#include <e32test.h>
-#include <e32debug.h>
-#include <e32svr.h>
-
-static RTest test(_L("DMA Test Framework API"));
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2564
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    This test checks the correct behaviour of Open API in the new DMA framework
-//!
-//! @SYMTestActions     
-//!						1.  Open a DMA channel
-//!						2.	Verify that channel is really open.
-//!
-//! @SYMTestExpectedResults 
-//!						1.  DMA channel opens and KErrNone returned
-//!						2.  Call to ChannelIsOpened() return as ETrue.
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void test_open_api()
-{
-	//TO DO : Expose TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel)
-	//TO DO : Implement more test cases
-	test.Start(_L("*** Testing Open() API  ***"));
-
-	test.Next(_L("Open session"));
-	RDmaSession session;
-	TInt r = session.Open();
-	test_KErrNone(r);
-
-	TUint channelCookie_open_api=0;
-	
-	test.Next(_L("Open DMA Channel"));
-	channelCookie_open_api=0;
-	r = session.ChannelOpen(16, channelCookie_open_api);
-	test.Printf(_L("cookie recieved = 0x%08x\n"), channelCookie_open_api);
-	test_KErrNone(r);
-
-	//Check if channel is open
-	// test.Printf(_L("Verify that the specified DMA channel is opened\n"));	
-	// TBool channelOpened;
-	// TBool channelNotOpened = EFalse;
-	// r = session.ChannelIsOpened(channelCookie_open_api,  channelOpened);
-	// test_KErrNone(r);	
- 	// TEST_ASSERT(channelOpened != channelNotOpened)
-	
-	//close channel
-	test.Next(_L("Channel close"));
-	r = session.ChannelClose(channelCookie_open_api);
-	test_KErrNone(r);
-	
-	RTest::CloseHandleAndWaitForDestruction(session);
-	test.End();
-}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2568
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    This test checks the correct behaviour of Close API in the new DMA framework
-//!
-//! @SYMTestActions     
-//!						1.  Open a DMA channel
-//!						2.	Open DMA Channel again
-//!						3	Close the DMA channel.
-//!						4	Open DMA channel to verify that the DMA channel closed.
-//!						5.	Open DMA channel again.
-//!						6.	Queue a request on the channel.
-//!						7.	Close DMA channel while request is still queued on it.
-//!
-//! @SYMTestExpectedResults 
-//!						1.  DMA channel opens and KErrNone returned.
-//!						2.	DMA Framework returns KErrInUse as channel is already open.					
-//!						3.	DMA channel closes and KErrNone returned.
-//!						4.	DMA channel opens and KErrNone returned.
-//!						5.	DMA Framework returns KErrInUse as channel is already open.
-//!						6.	DMA request queued and KErrNone returned.
-//!						7.	DMA channel closes and DMA framework flags an error.
-//!							
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void test_close_api()
-{
-	test.Start(_L("*** Testing Close() API  ***"));
-	
-	test.Next(_L("Open session"));
-	RDmaSession session;
-	TInt r = session.Open();
-	test_KErrNone(r);
-
-	const TInt size = 64 * KKilo;
-	TUint reqCookieNewStyle_close_api=0;	
-	TUint channelCookie_close_api=0;
-	
-	test.Next(_L("Open a single DMA channel"));
-	r = session.ChannelOpen(16, channelCookie_close_api);
-	test.Printf(_L("cookie recieved = 0x%08x\n"), channelCookie_close_api);
-	test_KErrNone(r);
-
-	// test.Next(_L("Open DMA channel again"));
-	// TUint channelCookie_close_api_1=0;
-	// r = session.ChannelOpen(16, channelCookie_close_api_1);
-	// test.Printf(_L("Verify that DMA channel is already opened\n"));
-	// test_Equal(KErrInUse,r); 
-
-	test.Next(_L("Close the DMA channel"));
-	r = session.ChannelClose(channelCookie_close_api);
-	test_KErrNone(r);
-
-	test.Next(_L("Open DMA channel again"));
-	r = session.ChannelOpen(16, channelCookie_close_api);
-	test.Printf(_L("Verify that DMA channel was closed\n"));
-	test_KErrNone(r); 
-
-	//Fails if a request is created and cancel
-	test.Next(_L("Queue a request on the channel"));
-  	r = session.RequestCreateNew(channelCookie_close_api, reqCookieNewStyle_close_api); //Create Dma request (with new-style callback)
-  	test.Printf(_L("cookie recieved for open channel = 0x%08x\n"), reqCookieNewStyle_close_api);
-  	test_KErrNone(r);
-  
-  	TDmaTransferArgs transferArgs_close_api;
-  	transferArgs_close_api.iSrcConfig.iAddr = 0;
-  	transferArgs_close_api.iDstConfig.iAddr = size;
-  	transferArgs_close_api.iSrcConfig.iFlags = KDmaMemAddr;
-  	transferArgs_close_api.iDstConfig.iFlags = KDmaMemAddr;
-  	transferArgs_close_api.iTransferCount = size;
-  	r = session.FragmentRequest(reqCookieNewStyle_close_api, transferArgs_close_api);
-  	test_KErrNone(r);
-  	
-  	test.Next(_L("Queue DMA Request"));
-  	TCallbackRecord record_close_api;
-  	r = session.QueueRequest(reqCookieNewStyle_close_api, &record_close_api);
-  	test_KErrNone(r);
-	
-	test.Next(_L("Destroy Dma request"));
-	r = session.RequestDestroy(reqCookieNewStyle_close_api);
-	test_KErrNone(r);
-
-	test.Next(_L("Close the DMA channel"));
-	r = session.ChannelClose(channelCookie_close_api);
-	test_KErrNone(r);
-
-	test.End();
-	RTest::CloseHandleAndWaitForDestruction(session);
-}
-
-void RDmaSession::ApiTest()
-	{
-    test_open_api();     // Verify that Open() opens a DMA channel
-    test_close_api();    // Verify that Close() closes a DMA channel
-	}
-
-void ApiTests()
-	{
-	test.Next(_L("Running framework API tests"));
-	RDmaSession::ApiTest();	
-	test.Close();
-	}
--- a/kerneltest/e32test/dmav2/self_test.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/self_test.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
@@ -49,9 +49,32 @@
 	Print(testInfo);
 	}
 
-	test.Next(_L("Channel open"));
+	// Self test just needs 1 channel
+	// The real test will test all available ones
+	test.Next(_L("Select test channel"));
+	TUint testChannel = 0;
+	if(testInfo.iMaxSbChannels > 0)
+		{
+		testChannel = testInfo.iSbChannels[0];
+		}
+	else if(testInfo.iMaxDbChannels > 0)
+		{
+		testChannel = testInfo.iDbChannels[0];
+		}
+	else if(testInfo.iMaxSgChannels > 0)
+		{
+		testChannel = testInfo.iSgChannels[0];
+		}
+	else
+		{
+		test.Printf(_L("Driver exposes no channels to test"));
+		test(EFalse);
+		}
+
+	test.Printf(_L("using PSL cookie %d (0x%08x)\n"), testChannel, testChannel);
+	test.Next(_L("Open channel"));
 	TUint channelCookie=0;
-	r = session.ChannelOpen(16, channelCookie);
+	r = session.ChannelOpen(testChannel, channelCookie);
 	test.Printf(_L("cookie recived = 0x%08x\n"), channelCookie);
 	test_KErrNone(r);
 
@@ -99,7 +122,7 @@
 
 	test.Next(_L("Create Dma request - max fragment size 32K"));
 	TUint reqCookie=0;
-	r = session.RequestCreate(channelCookie, reqCookie, 32 * KKilo);
+	r = session.RequestCreateOld(channelCookie, reqCookie, 32 * KKilo);
 	test.Printf(_L("cookie recived = 0x%08x\n"), reqCookie);
 	test_KErrNone(r);
 
@@ -107,7 +130,7 @@
 		{
 		test.Next(_L("Create Dma request (with new-style callback)"));
 		TUint reqCookieNewStyle=0;
-		r = session.RequestCreateNew(channelCookie, reqCookieNewStyle);
+		r = session.RequestCreate(channelCookie, reqCookieNewStyle);
 		test.Printf(_L("cookie recived = 0x%08x\n"), reqCookieNewStyle );
 		test_KErrNone(r);
 
@@ -271,50 +294,6 @@
 void TDmaCapability::SelfTest()
 	{
 	test.Start(_L("Unit test_Value of TDmaCapability::CompareToDmaCaps\n"));
-
-	{
-	test.Next(_L("ENone\n"));
-	TResult t = none.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == ERun);
-	}
-
-	{
-	test.Next(_L("EChannelPauseAndResume - wanted\n"));
-	TResult t = pauseRequired.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == EFail);
-	}
-	{
-	test.Next(_L("EChannelPauseAndResume - wanted - Allow skip\n"));
-	TResult t = pauseRequired_skip.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == ESkip);
-	}
-	{
-	test.Next(_L("EChannelPauseAndResume - not wanted\n"));
-	TResult t = pauseNotWanted.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == ERun);
-	}
-
-	{
-	test.Next(_L("EHwDescriptors - not wanted\n"));
-	TResult t = hwDesNotWanted.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == EFail);
-	}
-
-	{
-	test.Next(_L("EHwDescriptors - not wanted - Allow skip\n"));
-	TResult t = hwDesNotWanted_skip.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == ESkip);
-	}
-
-	{
-	test.Next(_L("EHwDescriptors - wanted\n"));
-	TResult t = hwDesWanted.CompareToDmaCaps(KTestCapSet);
-	test_Value(t, t == ERun);
-	}
-
-
-//TODO use this macro for the above tests
-
 // Note: The construction of the test description message
 // is horribly confusing. The _L macro will make the
 // *first* string token wide, but not the next two.
@@ -328,6 +307,13 @@
 	test_Equal(EXPCT, t);\
 	}
 
+	CAP_TEST(none, KTestCapSet, ERun);
+	CAP_TEST(pauseRequired, KTestCapSet, EFail);
+	CAP_TEST(pauseRequired_skip, KTestCapSet, ESkip);
+	CAP_TEST(pauseNotWanted, KTestCapSet, ERun);
+	CAP_TEST(hwDesNotWanted, KTestCapSet, EFail);	
+	CAP_TEST(hwDesNotWanted_skip, KTestCapSet, ESkip);
+	CAP_TEST(hwDesWanted, KTestCapSet, ERun);
 
 	CAP_TEST(capEqualV1, KDmacTestCapsV1, ERun);
 	CAP_TEST(capEqualV2, KDmacTestCapsV2, ERun);
@@ -345,56 +331,39 @@
 
 void TTestCase::SelfTest()
 	{
-	//TODO should use macros for these tests
 	test.Start(_L("Unit test of TTestCase::TestCaseValid\n"));
 
-	TTestCase testCase(NULL, EFalse, pauseRequired, hwDesNotWanted);
-	test.Next(_L("pauseRequired, hwDesNotWanted\n"));
-	TResult t = testCase.TestCaseValid(KTestCapSet);
-	test_Value(t, t == EFail);
-
-	test.Next(_L("pauseRequired_skip, hwDesNotWanted\n"));
-	testCase.iChannelCaps[0] = pauseRequired_skip;
-	t = testCase.TestCaseValid(KTestCapSet);
-	test_Value(t, t == EFail);
-
-	test.Next(_L("pauseRequired_skip, hwDesNotWanted_skip\n"));
-	testCase.iChannelCaps[1] = hwDesNotWanted_skip;
-	t = testCase.TestCaseValid(KTestCapSet);
-	test_Value(t, t == ESkip);
-
-	test.Next(_L("pauseNotWanted, hwDesNotWanted_skip\n"));
-	testCase.iChannelCaps[0] = pauseNotWanted;
-	t = testCase.TestCaseValid(KTestCapSet);
-	test_Value(t, t == ESkip);
+// Create a TTestCase with paramaters CAP1 and CAP2
+// call TTestCase::TestCaseValid against CAPSET
+// Expected result is EXPCT
+#define TEST_TEST_CASE(CAP1, CAP2, CAPSET, EXPCT)\
+	{\
+	test.Next(_L(#CAP1 L", " L ## #CAP2 L" -- Against: " L ## #CAPSET L", Expect: " L ## #EXPCT));\
+	TTestCase testCase(NULL, EFalse, CAP1, CAP2);\
+	testCase.iChannelCaps[0] = (CAP1);\
+	TResult t = testCase.TestCaseValid(CAPSET);\
+	test_Equal(EXPCT, t);\
+	}
 
-	test.Next(_L("pauseNotWanted, hwDesWanted\n"));
-	testCase.iChannelCaps[1] = hwDesWanted;
-	t = testCase.TestCaseValid(KTestCapSet);
-	test_Value(t, t == ERun);
+	TEST_TEST_CASE(pauseRequired, hwDesNotWanted, KTestCapSet, EFail);
+	TEST_TEST_CASE(pauseRequired_skip, hwDesNotWanted, KTestCapSet, EFail);
+	TEST_TEST_CASE(pauseRequired_skip, hwDesNotWanted_skip, KTestCapSet, ESkip);
+	TEST_TEST_CASE(pauseNotWanted, hwDesNotWanted_skip, KTestCapSet, ESkip);
+	TEST_TEST_CASE(pauseNotWanted, hwDesWanted, KTestCapSet, ERun);
+    TEST_TEST_CASE(pauseNotWanted, none, KTestCapSet, ERun);
 
-	test.Next(_L("pauseNotWanted\n"));
-	testCase.iChannelCaps[1] = none;
-	t = testCase.TestCaseValid(KTestCapSet);
-	test_Value(t, t == ERun);
+	TEST_TEST_CASE(pauseNotWanted, capAboveV1, KDmacTestCapsV1, ESkip);
+	TEST_TEST_CASE(pauseNotWanted, capAboveV1, KDmacTestCapsV2, ERun);
 
-	test.Next(_L("pauseNotWanted + V1 PIL required\n"));
-	testCase.iChannelCaps[1] = capAboveV1;
-	test.Next(_L("Against KDmacTestCapsV1"));
-	t = testCase.TestCaseValid(KDmacTestCapsV1);
-	test_Equal(ESkip, t);
-	test.Next(_L("Against KDmacTestCapsV2"));
-	t = testCase.TestCaseValid(KDmacTestCapsV2);
-	test_Equal(ERun, t);
+	TEST_TEST_CASE(pauseNotWanted, capBelowV2, KDmacTestCapsV1, ERun);
+	TEST_TEST_CASE(pauseNotWanted, capBelowV2, KDmacTestCapsV2, ESkip);
 
-	test.Next(_L("pauseNotWanted + >V1 PIL required\n"));
-	testCase.iChannelCaps[1] = capBelowV2;
-	test.Next(_L("Against KDmacTestCapsV1"));
-	t = testCase.TestCaseValid(KDmacTestCapsV1);
-	test_Equal(ERun, t);
-	test.Next(_L("Against KDmacTestCapsV2"));
-	t = testCase.TestCaseValid(KDmacTestCapsV2);
-	test_Equal(ESkip, t);
+	// contradictory requirements
+	TEST_TEST_CASE(capAboveV1, capBelowV2, KDmacTestCapsV2, ESkip);
+	TEST_TEST_CASE(capBelowV2, capAboveV1, KDmacTestCapsV2, ESkip);
+
+	TEST_TEST_CASE(capAboveV1, capBelowV2, KDmacTestCapsV1, ESkip);
+	TEST_TEST_CASE(capBelowV2, capAboveV1, KDmacTestCapsV1, ESkip);
 
 	test.End();
 	test.Close();
@@ -461,7 +430,7 @@
 
 void TCallbackRecord::SelfTest()
 	{
-	test.Start(_L("SeltTest of TCallbackRecord"));
+	test.Start(_L("SelfTest of TCallbackRecord"));
 
 	test.Next(_L("create default TCallbackRecord record, record2"));
 	TCallbackRecord record;
@@ -559,6 +528,7 @@
 	test.Start(_L("SelfTest of CDmaBenchmark"));
 	test.Next(_L("MeanResult()"));
 
+	// The mean of these numbers is 10
 	TUint64 results[] = {8, 12, 1, 19, 3, 17, 10};
 	const TInt count = ARRAY_LENGTH(results);
 
@@ -612,6 +582,18 @@
 
 	test(!a.Contains(b));
 	test(!b.Contains(a));
+
+	test.Next(_L("Test IsFilled()"));
+	TUint8 buffer[] = {0,0,0,0};
+	TAddrRange range((TUint)buffer, 4);
+	test(range.IsFilled(0));
+	buffer[3] = 1;
+	test(!range.IsFilled(0));
+	buffer[2] = 1;
+	buffer[1] = 1;
+	buffer[0] = 1;
+	test(range.IsFilled(1));
+
 	test.End();
 	}
 
@@ -649,6 +631,187 @@
 	test.End();
 	}
 
+void TIsrRequeArgsSet::SelfTest()
+	{
+	test.Start(_L("Selftest of TIsrRequeArgsSet"));
+
+	TUint size = 0x1000;
+	TDmaTransferArgs tferArgs(0, 1*size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr);
+
+	TIsrRequeArgs requeArgArray[] = {
+		TIsrRequeArgs(),									// Repeat
+		TIsrRequeArgs(KPhysAddrInvalidUser, 2*size, 0),		// Change destination
+		TIsrRequeArgs(),									// Repeat
+		TIsrRequeArgs(3*size, KPhysAddrInvalidUser, 0),		// Change source
+		TIsrRequeArgs(),									// Repeat
+	};
+	TIsrRequeArgsSet argSet(requeArgArray, ARRAY_LENGTH(requeArgArray));
+
+	test.Next(_L("Test that Substitute updates transfer args in order"));
+	argSet.Substitute(tferArgs);
+
+	TAddressParms expectedFinal(3*size, 2*size, size);
+	if(!(expectedFinal == argSet.iRequeArgs[4]))
+		{
+		TBuf<0x100> out;
+
+		out += _L("substitue: ");
+		GetAddrParms(tferArgs).AppendString(out);
+		test.Printf(out);
+
+		out.Zero();
+		out += _L("\nexpected final: ");
+		expectedFinal.AppendString(out);
+		test.Printf(out);
+
+		out.Zero();
+		out += _L("\nactual: ");
+		argSet.iRequeArgs[4].AppendString(out);
+		test.Printf(out);
+
+		test(EFalse);
+		}
+
+	TIsrRequeArgs requeArgArray2[] = {
+		TIsrRequeArgs(),									// Repeat
+		TIsrRequeArgs(KPhysAddrInvalidUser, 2*size, 0),		// Change destination
+		TIsrRequeArgs(KPhysAddrInvalidUser, 1*size, 0),		// Change destination back
+	};
+	argSet = TIsrRequeArgsSet(requeArgArray2, ARRAY_LENGTH(requeArgArray2));
+
+	test.Next(_L("CheckRange(), negative"));
+
+	test(!argSet.CheckRange(0, (2 * size) - 1, tferArgs));
+	test(!argSet.CheckRange(0, (2 * size) + 1, tferArgs));
+	test(!argSet.CheckRange(0, (2 * size), tferArgs));
+
+	test(!argSet.CheckRange(1 ,(3 * size), tferArgs));
+	test(!argSet.CheckRange(1 ,(3 * size) + 1, tferArgs));
+
+	test(!argSet.CheckRange(1 * size , 2 * size, tferArgs));
+
+	test.Next(_L("CheckRange(), positive"));
+	test(argSet.CheckRange(0, 3 * size, tferArgs));
+	test(argSet.CheckRange(0, 3 * size+1, tferArgs));
+	test(argSet.CheckRange(0, 4 * size, tferArgs));
+
+
+	test.End();
+	}
+
+void RArrayCopyTestL()
+	{
+	test.Start(_L("Selftest of RArray CopyL"));
+
+	RArray<TInt> orig;
+	TInt i;													// VC++
+	for(i=0; i<10; i++)
+		{
+		orig.AppendL(i);
+		}
+
+	RArray<TInt> newArray;
+	CopyL(orig, newArray);
+
+	test_Equal(10, newArray.Count());
+
+	for(i=0; i<10; i++)
+		{
+		test_Equal(orig[i], newArray[i])
+		}
+
+	orig.Close();
+	newArray.Close();
+	test.End();
+	}
+
+void RArrayInsertLTest()
+	{
+	test.Start(_L("Selftest of RArray InsertL"));
+
+	RArray<TInt> array;
+	TInt numbers[10] = {0,1,2,3,4,5,6,7,8,9};
+	ArrayAppendL(array, &numbers[0], numbers + ARRAY_LENGTH(numbers));
+
+	test_Equal(10, array.Count());
+	for(TInt i=0; i<10; i++)
+		{
+		test_Equal(numbers[i], array[i])
+		}
+
+	array.Close();
+	test.End();
+	}
+
+/**
+Run check buffers on the supplied TAddressParms array
+*/
+TBool DoTferParmTestL(const TAddressParms* aParms, TInt aCount, TBool aAllowRepeat, TBool aPositive)
+	{
+	_LIT(KPositive, "positive");
+	_LIT(KNegative, "negative");
+	test.Printf(_L("CheckBuffers %S test: %d args, repeats allowed %d\n"),
+			(aPositive ? &KPositive : &KNegative), aCount, aAllowRepeat);
+	RArray<const TAddressParms> array;
+	ArrayAppendL(array, aParms, aParms + aCount);
+	TPreTransferIncrBytes preTran;
+	TBool r = preTran.CheckBuffers(array, aAllowRepeat);
+	array.Close();
+	return r;
+	}
+
+void TPreTransferIncrBytes::SelfTest()
+	{
+	// Test that TPreTransferIncrBytes::CheckBuffers can identify
+	// overlapping buffers
+	test.Start(_L("Selftest of TPreTransferIncrBytes"));
+
+// Macro generates test for 2 element array
+#define TPARM_TEST2(EXPECT, ALLOW_REPEAT, EL0, EL1)\
+		{\
+		TAddressParms set[2] = {EL0, EL1}; \
+		const TBool r = DoTferParmTestL(set, 2, ALLOW_REPEAT, EXPECT);\
+		test_Equal(EXPECT, r);\
+		}
+
+// Generate positive 2 element test
+#define TPARM_TEST2_POSITIVE(ALLOW_REPEAT, EL0, EL1) TPARM_TEST2(ETrue, ALLOW_REPEAT, EL0, EL1)
+// Generate negative 2 element test
+#define TPARM_TEST2_NEG(ALLOW_REPEAT, EL0, EL1) TPARM_TEST2(EFalse, ALLOW_REPEAT, EL0, EL1)
+
+// Macro generates test for 3 element array
+#define TPARM_TEST3(EXPECT, ALLOW_REPEAT, EL0, EL1, EL2)\
+		{\
+		TAddressParms set[3] = {EL0, EL1, EL2}; \
+		const TBool r = DoTferParmTestL(set, 3, ALLOW_REPEAT, EXPECT);\
+		test_Equal(EXPECT, r);\
+		}
+
+// Generate positive 3 element test
+#define TPARM_TEST3_POSITIVE(ALLOW_REPEAT, EL0, EL1, EL2) TPARM_TEST3(ETrue, ALLOW_REPEAT, EL0, EL1, EL2)
+// Generate negative 3 element test
+#define TPARM_TEST3_NEG(ALLOW_REPEAT, EL0, EL1, EL2) TPARM_TEST3(EFalse, ALLOW_REPEAT, EL0, EL1, EL2)
+
+	TPARM_TEST2_POSITIVE(EFalse, TAddressParms(0,16,16), TAddressParms(32, 48, 16));
+	TPARM_TEST2_POSITIVE(ETrue, TAddressParms(0, 16, 16), TAddressParms(0, 16, 16)); // both overlap (repeat allowed)
+
+	TPARM_TEST2_NEG(EFalse, TAddressParms(0,16,16), TAddressParms(24, 40, 16)); // second source depends on first destination
+	TPARM_TEST2_NEG(EFalse, TAddressParms(0,16,16), TAddressParms(16, 0, 16)); // second dest overwrites first source
+	TPARM_TEST2_NEG(EFalse, TAddressParms(0, 16, 16), TAddressParms(0, 16, 16)); // both overlap (repeat not allowed)
+	TPARM_TEST2_NEG(ETrue, TAddressParms(0, 16, 16), TAddressParms(0, 20, 16)); // exact repeat allowed, but overlap is only partial
+	TPARM_TEST2_NEG(ETrue, TAddressParms(0, 16, 16), TAddressParms(32, 16, 16)); // exact repeat allowed, but 2nd overwrites first dest
+
+
+	TPARM_TEST3_POSITIVE(EFalse, TAddressParms(0,16,16), TAddressParms(32, 48, 16), TAddressParms(64, 128, 64)); // no overlaps
+	TPARM_TEST3_POSITIVE(ETrue, TAddressParms(0, 16, 16), TAddressParms(0, 16, 16), TAddressParms(0, 16, 16)); // all overlap (repeat allowed)
+	TPARM_TEST3_POSITIVE(EFalse, TAddressParms(0,16,16), TAddressParms(0, 32, 16), TAddressParms(0, 48, 16)); // no overlaps (1 src to 3 dsts)
+
+	TPARM_TEST3_NEG(EFalse, TAddressParms(0,16,16), TAddressParms(128, 256, 128), TAddressParms(24, 40, 16)); // 3rd source depends on first destination
+	TPARM_TEST3_NEG(EFalse, TAddressParms(0,16,16), TAddressParms(128, 256, 128), TAddressParms(16, 0, 16)); // 3rd dest overwrites first source
+	TPARM_TEST3_NEG(EFalse, TAddressParms(0, 16, 16), TAddressParms(0, 16, 16), TAddressParms(0, 16, 16)); // all overlap (repeat not allowed)
+	test.Next(_L("CheckBuffers(RArray<TAddressParms>)"));
+	}
+
 void SelfTests()
 	{
 	test.Next(_L("Running framework unit tests"));
@@ -660,6 +823,10 @@
 	CDmaBmFragmentation::SelfTest();
 	TAddrRange::SelfTest();
 	TAddressParms::SelfTest();
+	TIsrRequeArgsSet::SelfTest();
+	RArrayCopyTestL();
+	RArrayInsertLTest();
+	TPreTransferIncrBytes::SelfTest();
 	test.End();
 	test.Close();
 	}
--- a/kerneltest/e32test/dmav2/t_dma2.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/t_dma2.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -11,7 +11,7 @@
 // Contributors:
 //
 // Description:
-// e32test\dma\t_dma.cpp
+// e32test\dmav2\t_dma2.cpp
 
 #include "d_dma2.h"
 #include "u32std.h"
@@ -26,18 +26,67 @@
 
 // DMA test framework command  parameter options
 
-// SelfTest Option
+// SelfTest option
 _LIT(KArgSelfTest, "/SELFTEST");  
 _LIT(KArgSelfTest2, "/S");		  
 
-//Verbose Option
+//Verbose option
 _LIT(KArgVerboseOutput, "/VERBOSE"); 
 _LIT(KArgVerboseOutput2, "/V");	     
   
+//Simple transfer test option
+_LIT(KArgSimpleTest, "/simple"); 
+
+//Callback test option
+_LIT(KArgCallBackTest, "/callback");
+
+//Suspend test option
+_LIT(KArgSuspendTest, "/suspend");
+
+//Multipart transfer tests
+_LIT(KArgMultiPartTest, "/multi");
+
+//Isr and dfc test option
+_LIT(KArgIsrDfcTest, "/isrdfc");
+
+//Isr reque  test option
+_LIT(KArgIsrequeTest, "/isreque");
+
+//Benchmark test option
+_LIT(KArgBenchmarkTest, "/bench");
+
+//Graphics test option
+_LIT(KArgGraphicTest, "/graphic");
+
+//DMA channel (opening and closing)  test option
+_LIT(KArgChannelTest, "/channel");
+
+//Queue test option
+_LIT(KArgQueueTest, "/queue");
+
+//Fragment test option
+_LIT(KArgFragmentTest, "/fragment");
+
+//Request test option
+_LIT(KArgRequestTest, "/request");
+
+
 
 TBool gHelpRequested;   // print usage 
 TBool gVerboseOutput;   // enable verbose output 
 TBool gSelfTest;        // run SelfTest 
+TBool gSimpleTest;		// run only Simple transfer test
+TBool gCallBack;		// run only Callback test
+TBool gSuspend;			// run only Pause and resume tests
+TBool gIsrReque;		// run only IsrReque tests
+TBool gMultiPart;		// run only Multipart tests
+TBool gIsrAndDfc;		// run only IsrAndDfc tests
+TBool gBenchmark;		// run only Benchmark tests
+TBool gGraphic;			// run only Graphic tests
+TBool gFragment;		// run only Fragment related tests
+TBool gChannel;			// run only Channel(open/close)tests
+TBool gQueue;			// run only Queue related tests
+TBool gRequest;			// run only Request related tests
 
 /**
 This function prints out the PSL test Information
@@ -77,8 +126,25 @@
 
 void CDmaTest::OpenDmaSession()
 	{
-	TInt r = iDmaSession.Open();
+	// Only open a new session if one
+	// was not already supplied
+	if(iDmaSession.Handle() == KNullHandle)
+		{
+		TInt r = iDmaSession.Open();
+		TEST_ASSERT(r == KErrNone);
+		r = iDmaSession.OpenSharedChunk(iChunk);
+		TEST_ASSERT(r == KErrNone);
+		}
+	}
+
+// Open another handle to the test driver
+void CDmaTest::OpenDmaSession(const RDmaSession& aSession)
+	{
+	iDmaSession = aSession;
+	TInt r = iDmaSession.Duplicate(RThread(), EOwnerThread);
 	TEST_ASSERT(r == KErrNone);
+
+	// open another handle to the test driver chunk
 	r = iDmaSession.OpenSharedChunk(iChunk);
 	TEST_ASSERT(r == KErrNone);
 	}
@@ -89,6 +155,26 @@
 	iDmaSession.Close();
 	}
 
+void CDmaTest::PreTransferSetup()
+	{
+	}
+
+TInt CDmaTest::DoPostTransferCheck()
+	{
+	return KErrNotSupported;
+	}
+
+void CDmaTest::ChannelPause(TUint aChannelSessionCookie)
+{
+	TInt r = iDmaSession.ChannelPause(aChannelSessionCookie);
+	TEST_ASSERT(r == KErrNone);
+}
+
+void CDmaTest::ChannelResume(TUint aChannelSessionCookie)
+{
+	TInt r = iDmaSession.ChannelResume(aChannelSessionCookie);
+	TEST_ASSERT(r == KErrNone);
+}
 //////////////////////////////////////////////////////////////////////
 // CSingleTransferTest
 //////////////////////////////////////////////////////////////////////
@@ -123,7 +209,7 @@
 			RDebug::Printf("Calling New Request API\n");
 			}
 		iActual.iRequestResult.iCreate =
-			iDmaSession.RequestCreateNew(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
+			iDmaSession.RequestCreate(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
 		}
 	else
 		{
@@ -132,7 +218,7 @@
 			RDebug::Printf("Calling Old Request API\n");
 			}
 		iActual.iRequestResult.iCreate =
-			iDmaSession.RequestCreate(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
+			iDmaSession.RequestCreateOld(iChannelSessionCookie, iRequestSessionCookie, iMaxFragmentSize);
 		}
 	}
 
@@ -158,7 +244,6 @@
 			}
 		iActual.iRequestResult.iFragmentationResult =
 			iDmaSession.FragmentRequestOld(iRequestSessionCookie, iTransferArgs);
-
 		}
 
 	const TInt fragmentCount = iDmaSession.RequestFragmentCount(iRequestSessionCookie);
@@ -211,6 +296,22 @@
 	RDebug::RawPrint(_L("Single transfer"));
 	}
 
+void CSingleTransferTest::PrintTestInfo() const
+	{
+	CDmaTest::PrintTestInfo();
+
+	// State which API versions are being used
+	if(iUseNewFragment)
+		RDebug::RawPrint(_L(", Fragment v2,"));
+	else
+		RDebug::RawPrint(_L(", Fragment v1,"));
+
+	if(iUseNewRequest)
+		RDebug::RawPrint(_L(" DDmaRequest v2"));
+	else
+		RDebug::RawPrint(_L(" DDmaRequest v1"));
+	}
+
 void CSingleTransferTest::PreTransferSetup()
 	{
 	if(iPreTransfer)
@@ -239,18 +340,166 @@
 	return result;
 	}
 
+//////////////////////////////////////////////////////////////////////
+// CDmaTestDecorator
+//////////////////////////////////////////////////////////////////////
 
+CDmaTestDecorator::CDmaTestDecorator(CDmaTest* aDecoratedTest)
+	: CDmaTest(_L("Decorated Test"), 1, NULL, NULL), iDecoratedTest(aDecoratedTest)
+	{}
+
+CDmaTestDecorator::CDmaTestDecorator(const CDmaTestDecorator& aOther)
+	: CDmaTest(aOther), iDecoratedTest( static_cast<CDmaTest*>( aOther.iDecoratedTest->Clone() ) )
+	// Need cast because Clone does not have a covariant return type,
+	// as not all compillers allow it
+	{}
+
+//////////////////////////////////////////////////////////////////////
+// CMultiVersionTest
+//////////////////////////////////////////////////////////////////////
+
+CMultiVersionTest::CMultiVersionTest(CSingleTransferTest* aDmaTest)
+	: CDmaTestDecorator(aDmaTest), iNewVersionTest(NULL)
+	{
+	}
+
+CMultiVersionTest::CMultiVersionTest(const CMultiVersionTest& aOther)
+	: CDmaTestDecorator(aOther), iNewVersionTest( aOther.iNewVersionTest ? static_cast<CSingleTransferTest*>(aOther.iNewVersionTest->Clone()) : NULL)
+	{
+	}
+
+CMultiVersionTest::~CMultiVersionTest()
+	{
+	delete iDecoratedTest;
+	delete iNewVersionTest;
+	}
+
+void CMultiVersionTest::SetupL()
+	{
+	// Open a tempory dma session to find out the
+	// capabilities of the dma channel.
+	OpenDmaSession();
+	Configure();
+	CloseDmaSession();
+	}
+
+void CMultiVersionTest::Announce() const
+	{
+	CTest::Announce();
+
+	iDecoratedTest->Announce();
+
+	if(iNewVersionTest)
+		iNewVersionTest->Announce();
+	}
+
+void CMultiVersionTest::PrintTestType() const
+	{
+	RDebug::RawPrint(_L("Multi version test wrapper"));
+	}
+
+void CMultiVersionTest::PrintTestInfo() const
+	{
+		if(iNewVersionTest)
+			{ 		
+			RDebug::RawPrint(_L("Running tests using Version 2 PIL"));
+			}
+		else
+			{
+			RDebug::RawPrint(_L("Running tests using Version 1 PIL"));		
+			}
+	}
+
+void CMultiVersionTest::RunTest()
+	{
+	OpenDmaSession();
+
+	// iDecoratedTest is the test, in the old configuration
+	// iNewVersionTest is the same test, configured
+	// to use the new APIs
+	//
+	// 2 objects are needed since they can each store
+	// their own results
+
+	iDecoratedTest->OpenDmaSession(iDmaSession);
+	(*iDecoratedTest)();
+
+	if(iNewVersionTest)
+		{
+		iNewVersionTest->OpenDmaSession(iDmaSession);
+		(*iNewVersionTest)();
+		}
+
+	CloseDmaSession();
+	}
+
+/**
+Maybe create another test object to run with new API
+
+Pass on the cookie for the channel they must test
+*/
+void CMultiVersionTest::Configure()
+	{
+	static_cast<CSingleTransferTest*>(iDecoratedTest)->UseNewDmaApi(EFalse);
+	iDecoratedTest->SetChannelCookie(iChannelCookie);
+
+	if(Version2PILAvailable())
+		{
+		iNewVersionTest = static_cast<CSingleTransferTest*>(iDecoratedTest->Clone());
+		TEST_ASSERT(iNewVersionTest != NULL);
+
+		iNewVersionTest->UseNewDmaApi(ETrue);
+		iNewVersionTest->SetChannelCookie(iChannelCookie);
+		}
+	}
+
+/**
+Discover from DMA channel what PIL versions are available.
+In practice V1 APIs will always be available, V2 may be.
+*/
+TBool CMultiVersionTest::Version2PILAvailable()
+	{
+	TUint channelSessionCookie;
+	TInt r = iDmaSession.ChannelOpen(iChannelCookie, channelSessionCookie);
+	TEST_ASSERT(r == KErrNone);
+
+	TDmacTestCaps channelCaps;
+	r = iDmaSession.ChannelCaps(channelSessionCookie, channelCaps);
+	TEST_ASSERT(r == KErrNone);
+
+	r = iDmaSession.ChannelClose(channelSessionCookie);
+	TEST_ASSERT(r == KErrNone);
+
+	return channelCaps.iPILVersion >= 2;
+	}
+
+TBool CMultiVersionTest::Result()
+	{
+	TBool v1Result = iDecoratedTest->Result();
+	if(gVerboseOutput || !v1Result)
+		RDebug::Printf("V1 API result: %s", v1Result ? "success" : "failure");
+
+	TBool v2Result = iNewVersionTest ? iNewVersionTest->Result() : ETrue;
+	if(gVerboseOutput || !v1Result)
+		RDebug::Printf("V2 API result: %s", v2Result ? "success" : "failure");
+	return v1Result && v2Result;
+	}
 
 //////////////////////////////////////////////////////////////////////
 // CDmaBenchmark
 //////////////////////////////////////////////////////////////////////
-
 CDmaBenchmark::CDmaBenchmark(const TDesC& aName, TInt aIterations, const TResultSet& aExpectedResults, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
 	:CSingleTransferTest(aName, aIterations, aTransferArgs, aExpectedResults, aMaxFragmentSize, NULL, NULL)
 	{
 	UseNewDmaApi(EFalse);
 	}
 
+CDmaBenchmark::CDmaBenchmark(const CDmaBenchmark& aOriginal)
+	:CSingleTransferTest(aOriginal)
+	{
+	CopyL(aOriginal.iResultArray, iResultArray);
+	}
+
 CDmaBenchmark::~CDmaBenchmark()
 	{
 	iResultArray.Close();
@@ -288,17 +537,12 @@
 		RDebug::Printf("  Mean time: %lu us", MeanResult());
 		}
 
-	//TODO this will be handled by the ctor later
-	iResultArray.Close();
-
 	return result;
 	}
 
-
 //////////////////////////////////////////////////////////////////////
 // CDmaBmFragmentation
 //////////////////////////////////////////////////////////////////////
-
 CDmaBmFragmentation::CDmaBmFragmentation(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
 	:CDmaBenchmark(aName, aIterations, ExpectedResults, aTransferArgs, aMaxFragmentSize)
 	{}
@@ -331,21 +575,334 @@
 	Fragment();
 	FreeRequest();
 	CloseChannel();
+	CloseDmaSession();
+	}
+
+//////////////////////////////////////////////////////////////////////
+//	CPauseResumeTest
+//
+//	-Time how long a given transfer takes
+//	-Pause the channel
+//	-repeat the transfer (queued asynchronously)
+//	-wait for some time (say, 3 times the time measured)
+//	-read the value of the TRequestStatus object, to check it is still pending
+//	-resume the channel
+//	-Wait on the request
+//	-Confirm that the request completed
+//////////////////////////////////////////////////////////////////////
+CPauseResumeTest::~CPauseResumeTest()
+	{
+	}
+
+void CPauseResumeTest::RunTest()
+	{
+	OpenDmaSession();
+
+	//Open a single DMA channel for a transfer
+	OpenChannel();
+
+	RDebug::Printf("Resume unpaused idle channel");
+	TInt r = iDmaSession.ChannelResume(iChannelSessionCookie);
+	TEST_ASSERT(KErrCompletion == r);
+
+	RDebug::Printf("Pause idle channel");
+	r = iDmaSession.ChannelPause(iChannelSessionCookie);
+	TEST_ASSERT(KErrNone == r);
+
+	RDebug::Printf("Pause paused idle Channel");
+	r = iDmaSession.ChannelPause(iChannelSessionCookie);
+	TEST_ASSERT(KErrCompletion == r);
+
+	RDebug::Printf("Resume paused idle channel");
+	r = iDmaSession.ChannelResume(iChannelSessionCookie);
+	TEST_ASSERT(KErrNone == r);
+
+	//Setup a DMA request and Fragment the request.
+	CreateDmaRequest();
+	Fragment();
+
+	//Queue the DMA request and time how long a transfer takes
+	TUint64 queueTime;
+	DoCalibrationTransfer(queueTime);
+
+	RDebug::Printf("Calibration transfer completed in %Lu us",queueTime);
+	TUint32 waitQueueReqTime = I64LOW(queueTime*3); //3 times the time measured in DoCalibrationTransfer
+	TEST_ASSERT(I64HIGH(queueTime*3) == 0); // If transfer takes over an hour, something has gone wrong anyway
+
+	// Initialise buffers, after calibration transfer
+	PreTransferSetup();
+
+	RDebug::Printf("Resume unpaused channel");
+	r = iDmaSession.ChannelResume(iChannelSessionCookie);
+	TEST_ASSERT(KErrCompletion == r);
+
+	//Pause DMA Transfer
+	RDebug::Printf("Pausing DMA Channel");
+	r = iDmaSession.ChannelPause(iChannelSessionCookie);
+	TEST_ASSERT(KErrNone == r);
+
+	RDebug::Printf("Pause paused Channel");
+	r = iDmaSession.ChannelPause(iChannelSessionCookie);
+	TEST_ASSERT(KErrCompletion == r);
+
+	//Repeat the transfer (queued asynchronously)
+	TRequestStatus queueRequestStatus;
+	iActual.iRequestResult.iQueueResult = QueueAsyncRequest(queueRequestStatus,queueTime);
+	RDebug::Printf("Queue a DMA Request and wait for %u us ", waitQueueReqTime);
+
+	User::After(waitQueueReqTime);
+	RDebug::Printf("Finished waiting");
+	TEST_ASSERT(queueRequestStatus.Int() == KRequestPending);
+
+	TBool queueEmpty = ETrue;
+	r = iDmaSession.ChannelIsQueueEmpty(iChannelSessionCookie,queueEmpty);
+	TEST_ASSERT(r == KErrNone);
+	TEST_ASSERT(!queueEmpty);
+
+	//Resume DMA channel
+	RDebug::Printf("Resuming paused DMA Channel");
+	r = iDmaSession.ChannelResume(iChannelSessionCookie);
+	TEST_ASSERT(KErrNone == r);
+
+	//Wait for transfer to complete
+	User::WaitForRequest(queueRequestStatus);
+	if (queueRequestStatus.Int() == KErrNone)
+		{
+		RDebug::Printf("DMA QueueAsyncRequest completed");
+		}
+
+	FreeRequest();
+	CloseChannel();
+
+	PostTransferCheck();
+	CloseDmaSession();
+	}
+
+/**
+Time how long transfer takes, with no pausing
+*/
+void CPauseResumeTest::DoCalibrationTransfer(TUint64 &atime)
+	{
+	//Queue the DMA request.
+	TCallbackRecord pCallbackRecord;
+	TInt r = iDmaSession.QueueRequest(iRequestSessionCookie,&pCallbackRecord,&atime);
+	TEST_ASSERT(r == KErrNone);
+	}
+
+TInt CPauseResumeTest::QueueAsyncRequest(TRequestStatus &aRequestState, TUint64 &atime)
+	{
+	return iDmaSession.QueueRequest(iRequestSessionCookie,aRequestState, &iActual.iCallbackRecord, &atime);
+	}
+
+void CPauseResumeTest::PrintTestType() const
+	{
+	RDebug::RawPrint(_L("Pause and Resume API Test"));
+	}
+
+//////////////////////////////////////////////////////////////////////
+// COpenCloseTest
+//////////////////////////////////////////////////////////////////////
+COpenCloseTest::~COpenCloseTest()
+	{
+	}
+
+TBool COpenCloseTest::DoRunClose()
+	{
+	// For storing cookie during neagtive test i,e open channel twice
+	TUint testChannelSessionCookie = 0; 
+
+	// Open a single DMA channel
+	TInt r = iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
+	if (r == KErrNone)//Check that DMA channel opened with no errors
+		{
+		RDebug::Printf("DMA channel opened");					
+		}
+	else
+		{
+		RDebug::Printf("Open DMA channel failed");			
+		return EFalse;
+		}
+
+	// Open DMA channel again and check that opening DMA channel again fails		
+	r = iDmaSession.ChannelOpen(iChannelCookie, testChannelSessionCookie);
+	if (r == KErrInUse)
+		{
+		RDebug::Printf("Opening DMA channel again fails as expected");	
+		}
+	else
+		{
+		RDebug::Printf("Open DMA channel again failed");
+		return EFalse;
+		}
+
+	// Close the DMA channel and check that DMA channel closes with no errors
+	r =iDmaSession.ChannelClose(iChannelSessionCookie);	 
+	if (r == KErrNone) 
+		{
+		RDebug::Printf("DMA channel closes with no errors");				
+		}
+	else
+		{
+		RDebug::Printf("Close the DMA channel failed");
+		return EFalse;
+		}
+	
+	// Verify that the DMA channel was actually closed by opening DMA channel
+	r = iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
+	if (r == KErrNone)
+		{
+		RDebug::Printf("DMA channel opened after a previous close operation");
+		return ETrue;
+		}
+	else
+		{
+		RDebug::Printf("Open DMA channel to verify that the DMA channel closed failed");
+		return EFalse;
+		}	
+	}
+
+TBool COpenCloseTest::DoRunOpen()
+	{
+	// Open a single DMA channel
+	TInt r = iDmaSession.ChannelOpen(iChannelCookie, iChannelSessionCookie);
+	if (r == KErrNone)//Check that DMA channel opened with no errors
+		{			
+		RDebug::Printf("DoRunOpen:DMA channel opened");			
+		}
+	else
+		{
+		RDebug::Printf("DoRunOpenDMA channel failed to open");				
+		return EFalse;
+		}	
+
+	// Verify that channel is really open by closing DMA channel
+	// and checking that DMA channel closes with no errors
+	r = iDmaSession.ChannelClose(iChannelSessionCookie);
+	if (r == KErrNone)
+		{
+		RDebug::Printf("DoRunOpen:DMA channel closes with no errors");			
+		return ETrue;
+		}
+	else
+		{
+		RDebug::Printf("DoRunOpen:DMA channel failed to close");		
+		return EFalse;
+		}
+	}
+
+TBool COpenCloseTest::DoRunOpenExposed()
+	{
+	SCreateInfoTest TOpenInfo;
+	TOpenInfo.iCookie =iChannelCookie;
+	TOpenInfo.iDfcPriority = 3;
+	
+	const TInt desCount[3] = {0,1,128}; 
+	const TBool dynChannel[3] =	{EFalse,EFalse,ETrue};  
+	const TInt expectedResults[3] = {KErrArgument,KErrNone,KErrInUse};  
+	TInt actualResults[3] = {1, 1, 1};
+
+	for (TInt i =0; i<3; i++)
+		{	
+		TOpenInfo.iDesCount = desCount[i];
+		TOpenInfo.iDynChannel = dynChannel[i];		
+
+		// Open a single DMA channel
+		RDebug::Printf("DoRunOpenExposed:Trying to open DMA channel using iDesCount(%d) and iDynChannel(%d)  ", TOpenInfo.iDesCount,TOpenInfo.iDynChannel);
+		actualResults[i] = iDmaSession.ChannelOpen(iChannelSessionCookie, TOpenInfo);
+		if (actualResults[i] == KErrNone)// Verify that channel is really open by closing DMA channel	
+			{
+			TInt err = iDmaSession.ChannelClose(iChannelSessionCookie);
+			TEST_ASSERT(err == KErrNone)//Check that DMA channel closed with no errors
+			}
+		}
+
+	// This case should fail if idesCount  =  0.
+	// PIL has been changed to return KErrArgument instead of using an assertion check
+	if (expectedResults[0] == actualResults[0])
+		{
+		RDebug::Printf("DoRunOpenExposed:DMA channel failed to open as expected as for iDesCount = 0 ");			
+		}
+	else
+		{
+		RDebug::Printf("DoRunOpenExposed:Error code returned (%d), expected KErrArgument as iDesCount= 0) ", actualResults[0]);	
+		return EFalse;
+		}
+
+	// For this case( idesCount  =  1), DMA channel should open with no issues	
+	if (expectedResults[1] == actualResults[1])
+		{		
+		RDebug::Printf("DoRunOpenExposed:DMA channel closes with no errors as expected for iDesCount = 1 ");
+		}
+	else
+		{
+		RDebug::Printf("DoRunOpenExposed:Failed to open DMA channel with error code (%d)", actualResults[1]);	
+		return EFalse;
+		}
+
+	// For this case(dynaChannel=ETrue), DMA channel now returns KErrInUse. dynaChannel is not supported in the PSL.
+	// PSL now returns a NULL pointer when dynaChannel is requested. The PIL interprets a NULL 
+	// pointer being returned from opening a DMA channel as a channel in use. Hence, KErrInUse is returned.
+	if (expectedResults[2] == actualResults[2])
+		{
+		RDebug::Printf("DoRunOpenExposed:DMA channel failed to open as expected as dynamic channel is not supported");		
+		}
+	else
+		{
+		RDebug::Printf("DoRunOpenExposed:Error code returned (%d), expected KErrInUse as as dynamic channel is not supported", actualResults[2]);			
+		return EFalse;
+		}
+
+	return ETrue;
+	}
+
+void COpenCloseTest::RunTest()
+	{
+	OpenDmaSession(); 
+
+	if (iRunOpen) 
+	{	// Run Open() API test
+		iOpenCloseResult = DoRunOpenExposed();
+		if(iOpenCloseResult)
+			iOpenCloseResult = DoRunOpen();
+	}
+	else
+	{
+		// Run Close() API test	
+		iOpenCloseResult = DoRunClose();
+	}
 
 	CloseDmaSession();
 	}
 
+void COpenCloseTest::PrintTestType() const
+	{
+	RDebug::RawPrint(_L("Close/Open API Test"));
+
+	}
+
+TBool COpenCloseTest::Result()
+	{
+	if(gVerboseOutput)
+		{
+		RDebug::Printf("Results for Close/Open API Test");
+		}
+
+	if(!iOpenCloseResult)
+		{
+		RDebug::Printf("Open/Close test sequence failed"); 
+		}
+			
+	return iOpenCloseResult;
+	}
 //////////////////////////////////////////////////////////////////////
 // CDmaBmTransfer
 //////////////////////////////////////////////////////////////////////
-
 CDmaBmTransfer::CDmaBmTransfer(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize)
 	:CDmaBenchmark(aName, aIterations,
 		TResultSet(KErrNone, TRequestResults(),	KErrUnknown, TCallbackRecord(TCallbackRecord::EThread,1)),
 		aTransferArgs, aMaxFragmentSize)
 	{}
 
-
 void CDmaBmTransfer::PrintTestType() const
 	{
 	RDebug::RawPrint(_L("Transfer Benchmark"));
@@ -375,13 +932,247 @@
 		}
 	}
 
+/*
+1.	Open a DMA channel for a transfer.
+2.	Queue multiple request on the DMA channel.
+3.	Call CancelAll () on the DMA channel.
+4.	Verify that all transfers have been cancelled.
+5.	Open a DMA channel for a transfer. This channel should support pause and resume.
+6.	Call Pause () on the channel.
+7.	Queue multiple request on the DMA channel.
+8.	Call CancelAll () on the channel.
+9.	Verify that all transfers have been cancelled.
+
+   Note: This check does not add results to TResultSet like some
+   other tests as its operation is different. The test checks for 
+   the the cancelllation of all transfers queued on a channel by
+   calling iDmaSession.ChannelIsQueueEmpty(); 
+*/
+
+//////////////////////////////////////////////////////////////////////
+// CCancelAllTest
+//////////////////////////////////////////////////////////////////////
+
+
+CCancelAllTest::CCancelAllTest(const TDesC& aName, TInt aIterations,
+		const TDmaTransferArgs* aTransferArgs, const TResultSet* aResultSets,
+		TInt aCount)
+	:CMultiTransferTest(aName, aIterations, aTransferArgs, aResultSets, aCount)
+	{}
+
+void CCancelAllTest::RunTest()
+	{
+	OpenDmaSession();
+	PreTransferSetup();
+
+	// Open a DMA channel for a transfer.This channel should support pause and resume.
+	OpenChannel();
+
+	//Call Pause () on the channel
+	RDebug::Printf("Pausing DMA Channel");
+	ChannelPause(iChannelSessionCookie);
+	
+	// Queue multiple request on the DMA channel.
+	CreateDmaRequests();
+	Fragment();
+
+	QueueRequestsAsync();
+
+	// Call CancelAll () on the DMA channel and Verify that all transfers have been cancelled.
+	TInt r = CancelAllRequests();
+	TEST_ASSERT(r == KErrNone);
+
+	//Call Resume () on the channel.
+	RDebug::Printf("Cancel should clear Pause state: resuming channel should fail");
+	ChannelResume(iChannelSessionCookie);		
+	//TEST_ASSERT(r == KErrCompletion);
+
+	r = DoPostTransferCheck();
+	TEST_ASSERT(r == KErrNone);
+	//Destroy request
+    for(TInt i=0; i<2; i++)
+		{
+		r = iDmaSession.RequestDestroy(iRequestCookies[i]);
+		TEST_ASSERT(r == KErrNone);
+		}
+
+	//Close DMA channel
+	CloseChannel();
+
+	CloseDmaSession();
+	}
+
+TInt CCancelAllTest::CancelAllRequests()
+	{
+	if(gVerboseOutput)
+		{
+		RDebug::Printf("CCancelAllTest::CancelAllRequests()");
+		}
+	TInt r = KErrGeneral;
+	r  = iDmaSession.ChannelCancelAll(iChannelSessionCookie);
+	if (r != KErrNone)
+		return r;
+
+	TBool queueEmpty;
+	r = iDmaSession.ChannelIsQueueEmpty(iChannelSessionCookie,queueEmpty);
+	if (r != KErrNone)
+		return r;
+
+	if(!queueEmpty)
+		return KErrGeneral;
+
+	if(gVerboseOutput)
+		{
+		RDebug::Printf("Both current and pending requests cancelled");
+		}
+	return KErrNone;
+	}
+
+void CCancelAllTest::PrintTestType() const
+	{
+	RDebug::RawPrint(_L("CCancelAllTest"));
+	}
+
+void CCancelAllTest::QueueRequestsAsync()
+	{
+	if(iPauseWhileQueuing)
+		{
+		TInt r = iDmaSession.ChannelPause(iChannelSessionCookie);
+		TEST_ASSERT(r == KErrNone);
+		}
+
+	// Queue all the DMA requests asynchronously
+	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
+	for(TInt i=0; i<iTransferArgsCount; i++)
+		{
+		TResultSet& resultSet = iActualResults[i];
+		if(resultSet.iRequestResult.iFragmentationResult != KErrNone)
+			continue;
+
+		TInt r = iDmaSession.QueueRequest(iRequestCookies[i], iDummyRequestStatus, &resultSet.iCallbackRecord, NULL);
+		resultSet.iRequestResult.iQueueResult = r;
+		}
+
+	if(iPauseWhileQueuing)
+		{
+		TInt r = iDmaSession.ChannelResume(iChannelSessionCookie);
+		TEST_ASSERT(r == KErrNone);
+		}
+	}
+
+//////////////////////////////////////////////////////////////////////
+// CIsQueueEmptyTest
+//////////////////////////////////////////////////////////////////////
+CIsQueueEmptyTest::CIsQueueEmptyTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs* aTransferArgs,
+		const TResultSet* aResultSets, TInt aCount)
+	:CMultiTransferTest(aName, aIterations, aTransferArgs, aResultSets, aCount)
+	{}
+
+CIsQueueEmptyTest::CIsQueueEmptyTest(const CIsQueueEmptyTest& aOther)
+	:CMultiTransferTest(aOther)
+	{}
+
+CIsQueueEmptyTest::~CIsQueueEmptyTest()
+	{
+	}
+
+void CIsQueueEmptyTest::RunTest()
+	{
+	OpenDmaSession();
+	PreTransferSetup();
+	
+	OpenChannel();
+
+	CreateDmaRequests();
+	Fragment();
+	QueueRequests();
+
+	TInt r = DoPostTransferCheck();
+	TEST_ASSERT(r == KErrNone);
+
+	CloseDmaSession();
+	}
+
+void CIsQueueEmptyTest::DoIsQueueEmpty()
+	{
+	TBool queueEmpty;
+	TInt r = iDmaSession.ChannelIsQueueEmpty(iChannelSessionCookie,queueEmpty);
+	TEST_ASSERT(r == KErrNone);
+
+	if(queueEmpty)
+		{
+		RDebug::Printf("Verified that calling IsQueueEmpty() returns ETrue before calling Queue()");
+		}
+	else
+		{
+		RDebug::Printf("IsQueueEmpty() fails to return ETrue before calling Queue()");
+		TEST_ASSERT(queueEmpty);	
+		}
+	}
+
+void CIsQueueEmptyTest::DoQueueNotEmpty()
+	{
+	TBool queueEmpty;
+	TInt r = iDmaSession.ChannelIsQueueEmpty(iChannelSessionCookie,queueEmpty);
+	TEST_ASSERT(r == KErrNone);
+
+	if (!queueEmpty)
+		{
+		RDebug::Printf("Verified that calling IsQueueEmpty() returns EFalse after calling Queue()");
+		}
+	else
+		{
+		RDebug::Printf("IsQueueEmpty() fails to return EFalse after calling Queue()");
+		TEST_ASSERT(!queueEmpty);
+		}
+	}
+
+void CIsQueueEmptyTest::PrintTestType() const
+	{
+	RDebug::RawPrint(_L("IsQueue Empty Test using Multi Transfer"));
+	}
+
+void CIsQueueEmptyTest::QueueRequests()
+	{
+	// Queue all the DMA requests asynchronously
+	TInt i;
+	RArray<TRequestStatus> requestStates;
+	
+	ChannelPause(iChannelSessionCookie);
+	DoIsQueueEmpty();
+
+	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
+	for(i=0; i<iTransferArgsCount; i++)
+		{
+		TResultSet& resultSet = iActualResults[i];
+		if(resultSet.iRequestResult.iFragmentationResult != KErrNone)
+			continue;
+
+		TInt r = requestStates.Append(TRequestStatus());
+		TEST_ASSERT(r == KErrNone);
+
+		r = iDmaSession.QueueRequest(iRequestCookies[i], requestStates[i], &resultSet.iCallbackRecord, NULL);
+		resultSet.iRequestResult.iQueueResult = r;
+
+		DoQueueNotEmpty();
+		}
+	
+	ChannelResume(iChannelSessionCookie);
+
+	// wait for all transfers to complete
+	const TInt count = requestStates.Count();
+
+	for(i=0; i<count; i++)
+		{
+		User::WaitForRequest(requestStates[i]);
+		}
+
+	requestStates.Close();
+	}
 
 //////////////////////////////////////////////////////////////////////
 // CMultiTransferTest
 //////////////////////////////////////////////////////////////////////
-
-//TODO
-// Add pre and post transfer for CMultiTransferTest
 CMultiTransferTest::CMultiTransferTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs* aTransferArgs,
 		const TResultSet* aResultSets, TInt aCount)
 	: CDmaTest(aName, aIterations, NULL, NULL), iTransferArgs(aTransferArgs), iTransferArgsCount(aCount), iNewDmaApi(ETrue),
@@ -392,10 +1183,8 @@
 	: CDmaTest(aOther), iTransferArgs(aOther.iTransferArgs), iTransferArgsCount(aOther.iTransferArgsCount),
 	iNewDmaApi(aOther.iNewDmaApi),
 	iExpectedArray(aOther.iExpectedArray), iPauseWhileQueuing(aOther.iPauseWhileQueuing)
-	//const cast is required because their isn't a ctor taking const
-	//array values
-	//TODO iRequestCookies(const_cast<TUint*>(&aOther.iRequestCookies[0]), aOther.iRequestCookies.Count())
 	{
+	CopyL(aOther.iRequestCookies, iRequestCookies);
 	}
 
 CMultiTransferTest::~CMultiTransferTest()
@@ -497,10 +1286,13 @@
 	TEST_ASSERT(iActualResults.Count() == iTransferArgsCount);
 	for(TInt i=0; i<iTransferArgsCount; i++)
 		{
-		// Since all transfers will use the same channel,
-		// they all get the same result
-		// Arguably, iChannelOpenResult doesn't
-		// belong TResultSet
+		// In a multi transfer test a series of requests are created and queued.
+		// They all use the same channel, is opened here at the beginning of the test
+		//
+		// Each transfer has a TResultSet which holds a result for the channel opening,
+		// which we store here. Although in this case it is redundant,
+		// in future it might be that different transfers open
+		// different channels.
 		iActualResults[i].iChannelOpenResult = r;
 		}
 	}
@@ -528,11 +1320,11 @@
 
 		if(iNewDmaApi)
 			{
-			r = iDmaSession.RequestCreateNew(iChannelSessionCookie, cookie);
+			r = iDmaSession.RequestCreate(iChannelSessionCookie, cookie);
 			}
 		else
 			{
-			r = iDmaSession.RequestCreate(iChannelSessionCookie, cookie);
+			r = iDmaSession.RequestCreateOld(iChannelSessionCookie, cookie);
 			}
 		iActualResults[i].iRequestResult.iCreate = r;
 
@@ -611,9 +1403,9 @@
 	requestStates.Close();
 	}
 
-//TODO support test setup for CMultiTransferTest
 void CMultiTransferTest::PreTransferSetup()
 	{
+	// TODO this is the wrong place to do this!
 	for(TInt i=0; i<iTransferArgsCount; i++)
 		{
 		//pre-fill actual results with error values
@@ -634,8 +1426,6 @@
 //////////////////////////////////////////////////////////////////////
 // CIsrRequeTest
 //////////////////////////////////////////////////////////////////////
-
-
 CIsrRequeTest::CIsrRequeTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aArgs,
 			TIsrRequeArgs* aRequeueArgs, TInt aCount,
 			const TResultSet& aExpected,const MPreTransfer* aPreTfer,const MPostTransferCheck* aPostTferChk, TUint aMaxFragmentSize)
@@ -655,14 +1445,6 @@
 	RDebug::RawPrint(_L("ISR Requeue"));
 	}
 
-/*
-//TODO will need to support buffer checking of the trasnfers
-TBool CIsrRequeTest::Result()
-	{
-	return CSingleTransferTest::Result();
-	}
-*/
-
 void CIsrRequeTest::PreTransferSetup()
 	{
 	if(iPreTransfer)
@@ -677,7 +1459,6 @@
 //////////////////////////////////////////////////////////////////////
 // TResultSet
 //////////////////////////////////////////////////////////////////////
-
 void TResultSet::Print() const
 	{
 	PRINT(iChannelOpenResult);
@@ -696,7 +1477,6 @@
 //////////////////////////////////////////////////////////////////////
 // MPostTransferCheck classes
 //////////////////////////////////////////////////////////////////////
-
 TInt TCompareSrcDst::Check(const CSingleTransferTest& aTest) const
 	{
 	if(gVerboseOutput)
@@ -706,9 +1486,14 @@
 	return Check(aTest.TransferArgs(), aTest.Chunk().Base());
 	}
 
-//TODO
-//this check will not deal correctly transfers were subsequent
-//requeues overlap
+// Note: this check will not deal correctly with transfers were subsequent
+// requeues overlap previous sources or destinations
+// or where the source of transfer depends on a previous transfer.
+// This is because it simply compares the source and destination
+// pairwise for each transfer
+//
+// If TPreTransferIncrBytes is used for the pre-test then the transfers
+// will be checked however.
 TInt TCompareSrcDst::Check(const CIsrRequeTest& aTest) const
 	{
 	if(gVerboseOutput)
@@ -729,8 +1514,7 @@
 	}
 
 TInt TCompareSrcDst::Check(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const
-	{
-	//TODO could make use of Fixup() method
+	{	
 	const TUint32 srcOffset = aTransferArgs.iSrcConfig.iAddr;
 	const TUint32 dstOffset = aTransferArgs.iDstConfig.iAddr;
 	const TInt size = aTransferArgs.iTransferCount;
@@ -780,6 +1564,14 @@
 	return memcompare(src, size, dst, size);
 	}
 
+// Note: this check will not deal correctly with transfers were subsequent
+// requeues overlap previous sources or destinations
+// or where the source of trasnfer depends on a previous trasnfer.
+// This is because it simply compares the source and destination
+// pairwise for each transfer
+//
+// If TCompareSrcDst is used for the pre-test then the transfers
+// will be checked however.
 TInt TCompareSrcDst::Check(CMultiTransferTest& aTest) const
 	{
 	if(gVerboseOutput)
@@ -833,10 +1625,57 @@
 	{
 	return KErrNotSupported;
 	}
+
+
+TInt TCheckNoTransfer::Check(const CSingleTransferTest&) const
+	{
+	return KErrNotSupported;
+	}
+
+TInt TCheckNoTransfer::Check(const CIsrRequeTest&) const
+	{
+	return KErrNotSupported;
+	}
+
+TInt TCheckNoTransfer::Check(CMultiTransferTest& aTest) const
+	{
+	if(gVerboseOutput)
+		{
+		RDebug::Printf("TCheckNoTransfer Comparing CMultiTransferTest buffers");
+		}
+
+	const TInt transferCount = aTest.TransferCount();
+	TUint8* const chunkBase = aTest.Chunk().Base();
+
+	// check buffers for each transfer
+	for(TInt i=0; i<transferCount; i++)
+		{
+		TInt r = KErrCorrupt;
+		if(IsZeroed(aTest.TransferArgs(i), chunkBase))
+			{
+			r = KErrNone;
+			}
+
+		aTest.SetPostTransferResult(i, r);
+		}
+	// CMultiTransferTest is handled differently to the others.
+	// Whereas CSingleTransferTest logs just the return value
+	// of the check, here, we write back a result for each transfer
+	// so the return value from this function is not important
+	return KErrNone;
+	}
+
+TBool TCheckNoTransfer::IsZeroed(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const
+	{
+	TAddressParms parms = GetAddrParms(aTransferArgs);
+	parms.Fixup(reinterpret_cast<TLinAddr>(aChunkBase));
+	const TAddrRange destination = parms.DestRange();
+
+	return destination.IsFilled(0);
+	}
 //////////////////////////////////////////////////////////////////////
 // MPreTransfer classes
 //////////////////////////////////////////////////////////////////////
-
 void TPreTransferIncrBytes::Setup(const CSingleTransferTest& aTest) const
 	{
 	if(gVerboseOutput)
@@ -904,7 +1743,12 @@
 		{
 		RDebug::Printf("TPreTransferIncrBytes(CMultiTransferTest)");
 		}
-	//TODO check for overlap
+
+	if(!CheckBuffers(aTest))
+		{
+		RDebug::Printf("Successive transfer destinations may not overlap previous src or dst buffers");
+		TEST_FAULT;
+		}
 
 	TUint8* const chunkBase = aTest.Chunk().Base();
 	const TInt transferCount = aTest.TransferCount();
@@ -943,26 +1787,85 @@
 	}
 
 /**
+A CMultiTransferTest will wait for all transfers to complete
+before comapairing source and destination buffers. For this to be successful
+each transfer must be independent ie. no destination or source may be
+overwritten by another transfer and source buffers may not depend on an
+earlier transfer
+*/
+TBool TPreTransferIncrBytes::CheckBuffers(const CMultiTransferTest& aTest) const
+	{
+	TUint8* const chunkBase = aTest.Chunk().Base();
+	const TInt transferCount = aTest.TransferCount();
+
+	// assemble an array of TAddressParams from aTest, that
+	// can then be passed to CheckBuffers(RArray<TAddressParms>)
+	RArray<const TAddressParms> array;
+
+	for(TInt i=0; i<transferCount; i++)
+		{
+		TAddressParms params = GetAddrParms(aTest.TransferArgs(i));
+		params.Fixup((TLinAddr)chunkBase);
+
+		array.AppendL(params);
+		}
+
+	 // 2nd arg EFalse as there is no need to permit exact repeats
+	const TBool r = CheckBuffers(array, EFalse);
+
+	array.Close();
+	return r;
+	}
+
+/**
 Check that the destination of each TAddressParms does not overlap with
 any previous source or destination or that if it does the whole transfer
 matches.
 This is so that successive transfers do not overwrite the destinations or
 sources of preceeding ones.
-Exactly matching transfers are allowed to test the case that a repeat
-transfer is required - though it can't then be determined just from
-looking at the buffers that the repeat was successful
+
+If aAllowExactRepeat is true then exactly matching transfers are allowed
+to test the case where a repeat transfer is required - though it can't
+then be determined just from looking at the buffers that the repeat was
+successful
 */
-TBool TPreTransferIncrBytes::CheckBuffers(const RArray<const TAddressParms> aTransferParams) const
+TBool TPreTransferIncrBytes::CheckBuffers(const RArray<const TAddressParms>& aTransferParams, TBool aAllowExactRepeat) const
 	{
+
 	const TInt count = aTransferParams.Count();
 
+	if(gVerboseOutput)
+		{
+		RDebug::Printf("CheckBuffers, %d transfers", count);
+		}
+
+	TBuf<128> buf;
 	for(TInt i=1; i<count; i++)
 		{
 		const TAddressParms& current = aTransferParams[i];
+
+		if(gVerboseOutput)
+			{
+			buf.Zero();
+			current.AppendString(buf);
+			RDebug::Print(_L("Check current: %S, against:"), &buf);
+			}
+
 		for(TInt j=0; j<i; j++)
 			{
 			const TAddressParms& previous = aTransferParams[j];
-			const TBool ok = !previous.Overlaps(current.DestRange()) || current == previous;
+			if(gVerboseOutput)
+				{
+				buf.Zero();
+				previous.AppendString(buf);
+				RDebug::Print(_L("Previous: %S"), &buf);
+				}
+
+			const TBool curDstOverlapsPrevTfer = previous.Overlaps(current.DestRange());
+			const TBool curSrcDependsOnPrevDest = current.SourceRange().Overlaps(previous.DestRange());
+			const TBool permitExactRepeat = aAllowExactRepeat && (current == previous);
+
+			const TBool ok = !(curDstOverlapsPrevTfer || curSrcDependsOnPrevDest) || permitExactRepeat;
 			if(!ok)
 				return EFalse;
 			}
@@ -972,7 +1875,6 @@
 //////////////////////////////////////////////////////////////////////
 // TTransferIter class
 //////////////////////////////////////////////////////////////////////
-
 void TTransferIter::operator++ ()
 	{
 	iPtr++; //the standard post increment
@@ -1007,7 +1909,7 @@
 	{
 	const TInt elemSize = iCfg->iElementSize;
 	RTest test(_L("TTransferIter invariant"));
-	const TInt bytesTransfered = (
+	const TUint bytesTransfered = (
 			elemSize * (iFrame * iCfg->iElementsPerFrame + iElem)
 			+ ((TUint)iPtr % (elemSize))
 			);
@@ -1237,9 +2139,6 @@
 		//Here, we must create a test thread for each channel
 		RPointerArray<CTest> concurrentTests;
 
-		if(testCase.iConcurrentTest)
-			RDebug::Printf("== Begin concurrent test run ==");
-
 		const TInt chanRecCount = iChannelRecords.Count();
 		for(TInt j=0; j < chanRecCount; j++)
 			{
@@ -1256,7 +2155,7 @@
 				TEST_ASSERT(dmaTest != NULL);
 
 				dmaTest->SetChannelCookie(record.iCookie);
-				dmaTest->Announce();
+				dmaTest->SetupL();
 				if(testCase.iConcurrentTest)
 					{
 					//Add test to array to be run concurrently
@@ -1265,9 +2164,9 @@
 					}
 				else
 					{
+					dmaTest->Announce();
 					//Run test in this thread
 					(*dmaTest)();
-					//TTestThread(
 					TBool result = dmaTest->Result();
 					TEST_ASSERT(result);
 
@@ -1297,11 +2196,20 @@
 			//if the test case has been run on all channels it will then  wait for all threads to complete.
 			}
 
+		// Run the tests which should happen concurrently
 		const TInt count = concurrentTests.Count();
 		if(count>0)
 			{
+			RDebug::Printf("== Begin concurrent test run ==");
+
+			TInt i;											// VC++
+			for(i=0; i<count; i++)
+				{
+				concurrentTests[i]->Announce();
+				}
+
 			MultipleTestRun(concurrentTests);
-			for(TInt i=0; i<count; i++)
+			for(i=0; i<count; i++)
 				{
 				TBool result = static_cast<CDmaTest*>(concurrentTests[i])->Result();
 				TEST_ASSERT(result);
@@ -1374,8 +2282,20 @@
 	{
 	test.Printf(_L("*** DMA TEST FRAMEWORK ***\n"));
 	test.Printf(_L("Usage : t_dma2.exe [/option]\n"));
-	test.Printf(_L("  /V  or /VERBOSE    = Control test output\n"));
-	test.Printf(_L("  /S  or /SELFTEST   = Run DMA self test\n"));
+	test.Printf(_L("  /V or /VERBOSE  = Control test output\n"));
+	test.Printf(_L("  /S or /SELFTEST = Run DMA self tests\n"));
+	test.Printf(_L("  /simple = Run only simple transfer tests\n"));
+	test.Printf(_L("  /callback = Run only callback tests\n"));
+	test.Printf(_L("  /multi = Run only multipart transfer tests\n"));
+	test.Printf(_L("  /isrdfc = Run only isr and dfc tests\n"));
+	test.Printf(_L("  /isreque = Run only isr reque tests\n"));
+	test.Printf(_L("  /bench = Run only benchmark tests\n"));
+	test.Printf(_L("  /suspend = Run only pause and resume tests\n"));
+	test.Printf(_L("  /graphic = Run only graphic tests\n"));
+	test.Printf(_L("  /channel = Run only DMA channel (opening and closing) tests\n"));
+	test.Printf(_L("  /queue = Run only queue tests\n"));
+	test.Printf(_L("  /fragment = Run only fragmentation related tests\n"));
+	test.Printf(_L("  /request = Run only requests tests related tests\n"));
 	test.Printf(_L("\n"));
 	}
 
@@ -1424,6 +2344,90 @@
 			tokenParsed = ETrue;			
 			}
 
+		// '/suspend' option
+		if ((0== tc->FindF(KArgSuspendTest)))
+			{
+			gSuspend = ETrue;
+			tokenParsed = ETrue;
+			}	
+		
+		// '/simple' option
+		if ((0== tc->FindF(KArgSimpleTest)))
+			{
+			gSimpleTest = ETrue;
+			tokenParsed = ETrue;
+			}	
+		
+		// '/multi' option
+		if ((0== tc->FindF(KArgMultiPartTest)))
+			{
+			gMultiPart = ETrue;
+			tokenParsed = ETrue;
+			}	
+	
+		// '/callback' option
+		if ((0== tc->FindF(KArgCallBackTest)))
+			{
+			gCallBack = ETrue;
+			tokenParsed = ETrue;
+			}	
+		
+		// '/IsrAndDfc' option
+		if ((0== tc->FindF(KArgIsrDfcTest)))
+			{
+			gIsrAndDfc  = ETrue;
+			tokenParsed = ETrue;
+			}	
+		
+		// '/IsrReque' option
+		if ((0== tc->FindF(KArgIsrequeTest)))
+			{
+			gIsrReque = ETrue;
+			tokenParsed = ETrue;
+			}	
+
+		// '/Benchmark' option
+		if ((0== tc->FindF(KArgBenchmarkTest)))
+			{
+			gBenchmark = ETrue;
+			tokenParsed = ETrue;
+			}	
+
+		// '/Queue' option
+		if ((0== tc->FindF(KArgQueueTest)))
+			{
+			gQueue = ETrue;
+			tokenParsed = ETrue;
+			}	
+
+		// '/Fragment' option
+		if ((0== tc->FindF(KArgFragmentTest)))
+			{
+			gFragment = ETrue;
+			tokenParsed = ETrue;
+			}	
+		
+		// '/Channel' option
+		if ((0== tc->FindF(KArgChannelTest)))
+			{
+			gChannel = ETrue;
+			tokenParsed = ETrue;
+			}	
+		
+		// '/Graphic' option
+		if ((0== tc->FindF(KArgGraphicTest)))
+			{
+			gGraphic = ETrue;
+			tokenParsed = ETrue;
+			}	
+
+		// '/Request' option
+		if ((0== tc->FindF(KArgRequestTest)))
+			{
+			gRequest = ETrue;
+			tokenParsed = ETrue;
+			}	
+	
 		if (!tokenParsed)
 			{
 			// warn about unparsed parameter
@@ -1444,8 +2448,61 @@
 	TTestRunner testRunner;
 
 	test.Next(_L("Add global test cases to test runner\n"));
-	testRunner.AddTestCases(TestArray);
 
+	if (gSimpleTest) //Add only simple tranfer test cases
+	{
+		testRunner.AddTestCases(TestArraySimple);
+	}
+	else if (gCallBack)  //Add only callback test cases
+	{
+		testRunner.AddTestCases(TestArrayCallback);
+	}
+	else if (gIsrReque)  //Add only ISR Reque test cases
+	{
+		testRunner.AddTestCases(TestArrayIsrReque);
+	}
+	else if (gMultiPart)  //Add only Multipart test cases
+	{
+		testRunner.AddTestCases(TestArrayMultiPart);
+	}
+	else if (gIsrAndDfc)  //Add only IsrAndDfc test cases
+	{
+		testRunner.AddTestCases(TestArrayIsrAndDfc);
+	}
+	else if (gBenchmark)  //Add only Benchmark test cases
+	{
+		testRunner.AddTestCases(TestArrayBenchmark);
+	}
+	else if (gGraphic)  //Add only 2D test cases
+	{
+		testRunner.AddTestCases(TestArray2DTest);
+	}
+	else if (gFragment)  //Add only Fragment test cases
+	{
+		testRunner.AddTestCases(TestArrayFragment);
+	}
+	else if (gChannel)  //Add only Channel test cases
+	{
+		testRunner.AddTestCases(TestArrayChannel);
+	}
+	else if (gSuspend)  //Add only Suspend test cases
+	{
+		testRunner.AddTestCases(TestArraySuspend);
+	}
+	else if (gQueue)  //Add only queue test cases
+	{
+		testRunner.AddTestCases(TestArrayQueue);
+	}
+	else if (gRequest)  //Add only request test cases
+	{
+		testRunner.AddTestCases(TestArrayRequest);
+	}
+	else
+	{
+		testRunner.AddTestCases(TestArray);//Add all test cases
+	}
+
+	
 	test.Next(_L("call TTestRunner::RunTests()\n"));
 	testRunner.RunTests();
 
@@ -1455,7 +2512,6 @@
 TInt E32Main()
 	{
 	__UHEAP_MARK;
-	//__KHEAP_MARK;
 	test.Title();
 
 	gHelpRequested = EFalse;
@@ -1495,10 +2551,7 @@
 
 	if (!(dma2Loaded || dma2CompatLoaded))
 		{
-		//TODO how can we distinguish this case from a platform where
-		//dma is supposed to be supported but the dma test ldd is
-		//missing?
-		test.Printf(_L("DMA not supported - test skipped\n"));
+		test.Printf(_L("DMA test driver not found - test skipped\n"));
 		return 0;
 		}
 	else if (dma2Loaded && !dma2CompatLoaded)
@@ -1527,10 +2580,12 @@
 	SelfTests(); 	
 	}
 
-	ApiTests();
-
 	RunDMATests();
 
+	// Wait for the supervisor thread to run and perform asynchronous
+	// cleanup, so that kernel heap space will be freed
+	r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)5000, 0);
+	test_KErrNone(r);
 	__KHEAP_MARKEND;
 
 	r = User::FreeLogicalDevice(KTestDmaLddName);
@@ -1540,7 +2595,6 @@
 
 	delete cleanup;
 
-	//__KHEAP_MARKEND;
 	__UHEAP_MARKEND;
 	return 0;
 	}
--- a/kerneltest/e32test/dmav2/t_dma2.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/t_dma2.h	Tue May 04 09:44:26 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
@@ -22,15 +22,25 @@
 #include "d_dma2.h"
 #include <e32std.h>
 
-
 class TTestCase;
 // Global array of test cases
 extern RPointerArray<TTestCase> TestArray;
-
+extern RPointerArray<TTestCase> TestArrayCallback;
+extern RPointerArray<TTestCase> TestArrayIsrReque;
+extern RPointerArray<TTestCase> TestArrayMultiPart;
+extern RPointerArray<TTestCase> TestArrayIsrAndDfc;
+extern RPointerArray<TTestCase> TestArrayBenchmark;
+extern RPointerArray<TTestCase> TestArray2DTest;
+extern RPointerArray<TTestCase> TestArrayIsrAndDfc;
+extern RPointerArray<TTestCase> TestArrayChannel;
+extern RPointerArray<TTestCase> TestArraySuspend;
+extern RPointerArray<TTestCase> TestArrayQueue;
+extern RPointerArray<TTestCase>	TestArraySimple;
+extern RPointerArray<TTestCase>	TestArrayRequest;
+extern RPointerArray<TTestCase>	TestArrayFragment;
 
 extern TBool gVerboseOutput;   // Verbose output control
 
-
 const TInt KParameterTextLenMax = 80;	// command-line param length
 
 /**
@@ -43,18 +53,13 @@
 */
 void SelfTests();
 
-void ApiTests();
-
 class CSingleTransferTest;
 class CIsrRequeTest;
 class CMultiTransferTest;
 
-
 /**
 An interface to a classs that sets up the buffers before a test
 */
-//TODO both pre and post transfer checks should perhaps derive from an
-//abstract visitor base
 class MPreTransfer
 	{
 public:
@@ -134,6 +139,25 @@
 	};
 
 /**
+Check whether destination buffers are zero filled
+
+Used to check that a transfer hasn't taken place.
+*/
+class TCheckNoTransfer : public MPostTransferCheck
+	{
+public:
+	TCheckNoTransfer()
+		{}
+
+	virtual TInt Check(const CSingleTransferTest& aTest) const;
+	virtual TInt Check(const CIsrRequeTest& aTest) const;
+	virtual TInt Check(CMultiTransferTest& aTest) const;
+
+protected:
+	TBool IsZeroed(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const;
+	};
+
+/**
 Base class for all DMA tests
 */
 class CDmaTest : public CTest
@@ -144,8 +168,11 @@
 		{}
 
 	void OpenDmaSession();
+	/* Duplicate aSession */
+	void OpenDmaSession(const RDmaSession& aSession);
 	void CloseDmaSession();
-
+	void ChannelPause(const TUint aChannelSessionCookie);
+	void ChannelResume(const TUint aChannelSessionCookie);
 	virtual void PrintTestInfo() const;
 	virtual TBool Result() = 0;
 
@@ -158,8 +185,8 @@
 	void SetChannelCookie(TUint32 aCookie)
 		{iChannelCookie = aCookie;}
 
-	virtual void PreTransferSetup() =0;
-	virtual TInt DoPostTransferCheck() =0;
+	virtual void PreTransferSetup();
+	virtual TInt DoPostTransferCheck();
 protected:
 	RDmaSession iDmaSession;
 	RChunk iChunk;
@@ -174,6 +201,49 @@
 	};
 
 /**
+The Decorator Pattern is used allowing test classes to be optionally extended
+using wrapper/decorator classes.
+This is the base class for test decorators
+*/
+class CDmaTestDecorator : public CDmaTest
+	{
+public:
+
+protected:
+	CDmaTestDecorator(CDmaTest* aDecoratedTest);
+	CDmaTestDecorator(const CDmaTestDecorator& aOther);
+
+	CDmaTest* iDecoratedTest;
+	};
+
+/**
+Will run the wrapped test against both versions of the DMA
+API if available, otherwise just the old version.
+*/
+class CMultiVersionTest : public CDmaTestDecorator
+	{
+public:
+	CMultiVersionTest(CSingleTransferTest* aDmaTest); 
+	CMultiVersionTest(const CMultiVersionTest& aOther);
+	~CMultiVersionTest();
+
+	virtual void Announce() const;
+	virtual void PrintTestType() const;
+	virtual void PrintTestInfo() const; 
+
+	virtual CTest* Clone() const {return new CMultiVersionTest(*this);}
+	virtual void SetupL();
+
+	virtual void RunTest();
+	virtual TBool Result();
+
+protected:
+	void Configure();
+	TBool Version2PILAvailable();
+	CSingleTransferTest* iNewVersionTest;
+	};
+
+/**
 Holds return codes for the various functions which must be called
 to create, fragment, and queue a DMA request
 */
@@ -186,14 +256,20 @@
 		TInt aFragmentationResult = KErrNone,
 		TInt aQueueResult = KErrNone
 		)
-		:iCreate(aCreate), iFragmentCount(aFragmentCount), iFragmentationResult(aFragmentationResult), iQueueResult(aQueueResult)
+		:iCreate(aCreate), 
+		 iFragmentCount(aFragmentCount), 
+		 iFragmentationResult(aFragmentationResult), 
+		 iQueueResult(aQueueResult)
 		{}
 
 	/**
 	Constructs with error results
 	*/
 	TRequestResults(TFalse)
-		:iCreate(KErrUnknown), iFragmentCount(0), iFragmentationResult(KErrUnknown), iQueueResult(KErrUnknown)
+		:iCreate(KErrUnknown), 
+		 iFragmentCount(0), 
+		 iFragmentationResult(KErrUnknown), 
+		 iQueueResult(KErrUnknown)
 		{}
 
 	inline TRequestResults& CreationResult(TInt aErrorCode) {iCreate = aErrorCode; return *this;}
@@ -273,15 +349,24 @@
 	virtual void Setup(const CSingleTransferTest& aTest) const;
 	virtual void Setup(const CIsrRequeTest& aTest) const;
 	virtual void Setup(const CMultiTransferTest& aTest) const;
+
+	static void SelfTest();
 protected:
 	virtual void Setup(const TAddressParms& aParams) const;
+
 	TBool CheckBuffers(const CIsrRequeTest& aTest) const;
-	TBool CheckBuffers(const RArray<const TAddressParms> aTransferParams) const;
+	TBool CheckBuffers(const CMultiTransferTest& aTest) const;
+
+	TBool CheckBuffers(const RArray<const TAddressParms>& aTransferParams, TBool aAllowExactRepeat=ETrue) const;
+
+	// This function is part of the unit test
+	friend TBool DoTferParmTestL(const TAddressParms* aParms, TInt aCount, TBool aAllowRepeat, TBool aPositive);
 	};
 
 const TPreTransferIncrBytes KPreTransferIncrBytes;
 const TCompareSrcDst KCompareSrcDst;
 const TCompare2D KCompare2D;
+const TCheckNoTransfer KCheckNoTransfer;
 
 
 /**
@@ -328,7 +413,7 @@
 
 	TUint8* iPtr; //<! Pointer to the current byte
 
-	TInt iBytes; //!< The number of bytes traversed
+	TUint iBytes; //!< The number of bytes traversed
 	};
 
 /**
@@ -360,6 +445,7 @@
 	*/
 	virtual void RunTest();
 	virtual void PrintTestType() const;
+	virtual void PrintTestInfo() const;
 
 	virtual CTest* Clone() const {return new CSingleTransferTest(*this);}
 
@@ -422,12 +508,102 @@
 	};
 
 /**
+This class will be used for testing DMA Close() and Open() API
+
+Extends CDmaTest by implemeting a RunTest() with a sequence of operations 
+to test Close() and Open() API 
+*/
+class COpenCloseTest : public CDmaTest 
+	{
+public:
+	COpenCloseTest(
+			const TDesC& aName, TInt aIterations,	
+			const MPostTransferCheck* aPostTferChk = NULL,
+			const MPreTransfer* aPreTfer = NULL
+			)
+		: CDmaTest(aName, aIterations, aPreTfer, aPostTferChk), iOpenCloseResult(EFalse) , iRunOpen(EFalse)
+		{}
+
+	~COpenCloseTest();
+
+	virtual void RunTest();
+	virtual void PrintTestType() const;
+
+	virtual CTest* Clone() const {return new COpenCloseTest(*this);}
+	
+	/**
+	Checks the results of the sequeunce of  sequence of operations 
+	to test Close() and Open() API, return ETrue for a pass, EFalse for a fail
+	 */
+	virtual TBool Result();
+
+	// The methods below is a setters ie. The Named Parameter Idiom
+	// @see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18
+	inline COpenCloseTest& RunOpenApiTest(TBool aFlag) {iRunOpen=aFlag; return *this;}
+
+protected:	
+	TBool DoRunClose();
+	TBool DoRunOpen();
+	TBool DoRunOpenExposed();
+
+protected:
+	/**
+	A handle to kernel side TDmaChannel object received after a channel is opened.
+	*/
+	TUint iChannelSessionCookie;
+	/**
+	A handle to kernel side DDmaRequest object.
+	*/
+	TUint iRequestSessionCookie;
+
+	/**
+	If true then Close/Open  API test passed
+	*/
+	TBool iOpenCloseResult;
+	
+	/**
+	 If true then run Open API test otherwise run Close API test
+	*/
+	TBool iRunOpen;
+	};
+
+/**
+Used for testing Pause and Resume
+
+Extends CSingle transfer by adding the capability to test
+Pause  & Resume() API.
+*/
+class CPauseResumeTest : public CSingleTransferTest
+	{
+public:
+	 CPauseResumeTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aArgs, const TResultSet& aExpected)
+		:CSingleTransferTest(aName, aIterations, aArgs, aExpected)
+	 {}
+
+	~CPauseResumeTest();
+
+	virtual void RunTest();
+	virtual void PrintTestType() const;
+
+	virtual CTest* Clone() const {return new  CPauseResumeTest(*this);}
+
+	// The methods below is a setters ie. The Named Parameter Idiom
+	// @see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18
+	inline CPauseResumeTest& UseNewDmaApi(TBool aFlag) {CSingleTransferTest::UseNewDmaApi(aFlag); return *this;}
+
+protected:
+	void DoCalibrationTransfer(TUint64 &atime);
+	TInt QueueAsyncRequest(TRequestStatus &aRequestState,TUint64 &atime);
+	};
+
+/**
 This class will be used for tests which benchmark certain DMA operations
 */
 class CDmaBenchmark : public CSingleTransferTest
 	{
 public:
 	CDmaBenchmark(const TDesC& aName, TInt aIterations, const TResultSet& aExpectedResults, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize);
+	CDmaBenchmark(const CDmaBenchmark& aOriginal);
 	~CDmaBenchmark();
 
 	virtual TBool Result();
@@ -440,15 +616,11 @@
 	*/
 	TUint64 MeanResult();
 
-	//TODO must be included within copy ctor or all instances will
-	//share on result set!
 	RArray<TUint64> iResultArray;
-
 	};
 
 /**
 Fragments requests (only) and records duration
-TODO make sure we are using old style DDmaRequest
 */
 class CDmaBmFragmentation : public CDmaBenchmark
 	{
@@ -550,6 +722,68 @@
 	};
 
 /**
+Used for testing TDmaChannel::IsQueueEmpty
+Extends CMultiTransferTest by adding the capability to test IsQueueEmpty() API. 
+*/
+class CIsQueueEmptyTest : public  CMultiTransferTest 
+	{
+public:
+	CIsQueueEmptyTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs* aTransferArgs, const TResultSet* aResultSets, TInt aCount);
+	CIsQueueEmptyTest(const CIsQueueEmptyTest& aOther);
+	~CIsQueueEmptyTest();
+
+	inline CIsQueueEmptyTest& SetPreTransferTest(const MPreTransfer* aPreTfer) {iPreTransfer = aPreTfer; return *this;}
+	inline CIsQueueEmptyTest& SetPostTransferTest(const MPostTransferCheck* aPostTfer) {iPostTransferCheck = aPostTfer; return *this;}
+
+	virtual CTest* Clone() const {return new CIsQueueEmptyTest(*this);}
+	virtual void RunTest();
+	virtual void PrintTestType() const;
+
+protected:
+	void DoQueueNotEmpty();	
+	void DoIsQueueEmpty();
+	void QueueRequests();
+	};
+
+/**
+Used for testing CancelAll, Will create and queue multiple requests
+Extends CSingle transfer by adding the capability to test CancelAll API
+*/
+class CCancelAllTest : public CMultiTransferTest
+	{
+public:
+	CCancelAllTest(const TDesC& aName, TInt aIterations,
+		const TDmaTransferArgs* aTransferArgs, const TResultSet* aResultSets,
+		TInt aCount
+		);
+	//CCancelAllTest(const CCacheNotifyDirCh
+
+	virtual void RunTest();
+	virtual void PrintTestType() const;
+	virtual CTest* Clone() const {return new CCancelAllTest(*this);}
+
+	inline CCancelAllTest& PauseWhileQueuing()
+		{iPauseWhileQueuing = ETrue; return *this;}
+	inline CCancelAllTest& SetPreTransferTest(const MPreTransfer* aPreTfer)
+		{iPreTransfer = aPreTfer; return *this;}
+	inline CCancelAllTest& SetPostTransferTest(const MPostTransferCheck* aPostTfer)
+		{iPostTransferCheck = aPostTfer; return *this;}
+
+protected:
+	void QueueRequestsAsync();
+	TInt CancelAllRequests();
+	void PauseChannel();
+	void ResumeChannel();
+
+	/**
+	A single request status that we use for all
+	asynchronously queued requests (we do not intend
+	to wait for them)
+	*/
+	TRequestStatus iDummyRequestStatus;
+	};
+
+/**
 Used for testing TDmaChannel::IsrRedoRequest
 
 Extends CSingle transfer by adding the capability to queue with
@@ -567,15 +801,6 @@
 	virtual void PrintTestType() const;
 
 	virtual void Queue();
-
-	/**
-	Compares the actual vs the exepected results and reports
-	of the test passed
-	@return ETrue for a pass, EFalse for a fail
-	 */
-	//virtual TBool Result();
-
-
 	virtual CTest* Clone() const {return new CIsrRequeTest(*this);}
 
 	const TIsrRequeArgsSet& GetRequeueArgs() const
@@ -617,8 +842,6 @@
 class TTestCase
 	{
 public:
-	//TODO it might be better to group sets of TDmaCapability
-	//into their own class eg. TDmaCapSet.
 	TTestCase(CDmaTest* aTest,
            TBool aConcurrent = EFalse,
 		   const TDmaCapability = TDmaCapability(),
@@ -661,11 +884,10 @@
 	~TTestRunner();
 
 	/**
-	This function will populate TTestRunner with an array of test cases which 
-	would be a collection of DMA test,its hardware prerequisites,and other 
-	information about how the test	
+	This function will populate TTestRunner with an array of test cases
+	to be run
 
-	@aTTestCases on return, this contains an the DMA test cases 
+	@param aTTestCases Array of test cases
 	*/
 	void AddTestCases(RPointerArray<TTestCase>& aTTestCases);
 
@@ -715,5 +937,25 @@
 	RArray<TUint> iPslCookies;
 };
 
+/**
+Copy an RArray
+*/
+template <typename T>
+void CopyL(const RArray<T>& aOriginal, RArray<T>& aNew)
+	{
+	const TInt count = aOriginal.Count();
+	for(TInt i=0; i<count; ++i)
+		{
+		aNew.AppendL(aOriginal[i]);
+		}
+	}
+
+template <typename T, typename Iterator>
+void ArrayAppendL(RArray<T>& aArray, Iterator aBegin, Iterator aEnd)
+	{
+	for(Iterator begin = aBegin; begin != aEnd; ++begin)
+		aArray.AppendL(*begin);
+	}
+
 
 #endif // #ifndef __T_DMA2_H__
--- a/kerneltest/e32test/dmav2/test_cases.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/test_cases.cpp	Tue May 04 09:44:26 2010 +0100
@@ -24,24 +24,121 @@
 const TCallbackRecord isrCallback(TCallbackRecord::EIsr,1);
 
 const TInt size = 128 * KKilo;
-//--------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    Simple DMA transfer test using CSingleTransferTest and New DMA APIs
+const TInt trans64K_1 = ((64 * KKilo) -1); // 65535
+
+//----------------------------------------------------------------------------------------------
+//! TestCaseID      KBASE-DMA-2571
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    This test verifies the correct behavior of CancelAll API in the new DMA 
+//!					framework 
 //!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestActions     
+//!						1.	Open a DMA channel for a transfer.
+//!						2.  Queue multiple request on the DMA channel.
+//!						3.	Call CancelAll () on the DMA channel.
+//!						4.  Verify that all transfers have been cancelled.
+//!						5   Open a DMA channel for a transfer. This channel should support pause and resume.
+//!						6.  Call Pause () on the channel.
+//!						7.	Queue multiple request on the DMA channel.
+//!						8.	Call CancelAll () on the channel.
+//!						9.	Verify that all transfers have been cancelled.
+//!
+//!
+//! TestExpectedResults 1.  DMA channel opens and KErrNone returned.
+//!						2.  DMA queue request created and KErrNone returned.
+//!						3.  CancelAll () cancels all queued request.
+//!						4.  All queued request are cancelled
+//!						5.	DMA Request completes
 //!
 //!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
+//! TestPriority        High
+//! TestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+namespace CancelAllTest
+	{
+	const TInt size = 2 * KMega;
+	const TDmaTransferArgs transferArgArray[] = {
+		TDmaTransferArgs(0, size, size, KDmaMemAddr),
+		TDmaTransferArgs(2 * size, 3 * size, size, KDmaMemAddr)
+	};
+
+	TResultSet noTransferExpected = TResultSet()
+		.PostTransferResult(KErrNone)
+		.CallbackRecord(TCallbackRecord::Empty());
+
+	const TResultSet expected[] =
+		{
+		TResultSet(noTransferExpected),
+		TResultSet(noTransferExpected)
+		};
+
+	// Test that 2 requests can be queued on a paused channel
+	// then cleared using CancelAll.
+	// It is expected that no data will have been transferred to the
+	// destination buffer.
+	CCancelAllTest testcancelall =
+		CCancelAllTest(_L("CancelAllTest : Cancel and verify cancellation of requests"), 1, transferArgArray, expected, ARRAY_LENGTH(transferArgArray))
+			.SetPreTransferTest(&KPreTransferIncrBytes)
+			.SetPostTransferTest(&KCheckNoTransfer);
+
+	TTestCase testCase(&testcancelall,EFalse,capAboveV1,pauseRequired_skip);
+	}
+
+//--------------------------------------------------------------------------------------------
+//! TestCaseID      KBASE-DMA-2569
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    This test verifies the correct behavior of Pause and Resume API in the new DMA 
+//!					framework 
+//!
+//! TestActions     
+//!						1.	Open a DMA channel for a transfer.
+//!						2.  Setup a DMA request and time how long the transfer takes
+//!						3.	Pause the DMA channel
+//!						4.  Repeat DMA transfer (queued asynchronously)
+//!						5.  Resume DMA Channel
+//! 
+//!	TestExpectedResults 1.  DMA channel opens and KErrNone returned.
+//!						2.  DMA request created and KErrNone returned.
+//!						3.  DMA channel Paused.
+//!						4.  Request queued and waits until Resume is called
+//!						5.	DMA Request completes
+//!
+//! TestPriority        High
+//! TestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+namespace PauseResumeApiTest
+	{
+	const TInt srcAddr		= 0;
+	const TInt desAddr		= 2 * KMega;	
+	const TInt transferSize = 1 * KMega;	
+
+	TDmaTransferArgs transferArgs(srcAddr, desAddr, transferSize, KDmaMemAddr);
+	const TResultSet expectedResults(threadCallback);
+	CPauseResumeTest testPauseResume = CPauseResumeTest(_L("Pause and Resume Test"), 1, transferArgs, expectedResults); 
+	TTestCase testCasePauseResume(&testPauseResume, EFalse, capAboveV1,pauseRequired_skip);	
+	}
+
+//--------------------------------------------------------------------------------------------
+//! TestCaseID      KBASE-DMA-2560
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Simple DMA transfer test using CSingleTransferTest and New DMA APIs
+//!
+//! TestActions     
+//!						1.	Open a DMA channel for a transfer.
+//!						2.	Create single transfer test and run test
+//!				
+//!
+//!
+//! TestExpectedResults 
+//!						1.  DMA channel opens and KErrNone returned.
+//!						2.	DMA transfer completes with no errors.
 //!							
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace Simple_1
 	{
@@ -51,60 +148,29 @@
 
 	CSingleTransferTest simpleTest(_L("Simple Test - New DMA APIs"), 1, transferArgs, expectedResults);
 
-	TTestCase testCase(&simpleTest, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&simpleTest, ETrue, capAboveV1);
+	TTestCase testCase(new (ELeave) CMultiVersionTest(&simpleTest), EFalse);
+	TTestCase testCaseConcurrent(new (ELeave) CMultiVersionTest(&simpleTest), ETrue);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    Simple DMA transfer test using CSingleTransferTest and OLD DMA APIs
-//!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
-//!
-//!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.						
-//!							
+//! TestCaseID      KBASE-DMA-2573
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    DMA ISR Callback test (Isr Callback - use old request Ctor)
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace Simple_2
-	{
-	TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr);
-
-	const TResultSet expectedResults(threadCallback);
-
-	CSingleTransferTest simpleTest = CSingleTransferTest(_L("Simple Test - Old DMA APIs"), 1, transferArgs, expectedResults, 0).
-		UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&simpleTest, EFalse);
-	TTestCase testCaseConcurrent(&simpleTest, ETrue);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2573
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    DMA ISR Callback test (Isr Callback - use old request Ctor)
+//! TestActions     
+//!						1.	Setup DMA transfer to request a callback from ISR using old style DDmaRequest.
+//!						2.	Create single transfer test and run test
+//!						3.	Verify that DDmaRequest request fails
 //!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
-//!
+//! TestExpectedResults 
+//!						1.  DMA channel opens and KErrNone returned.
+//!						2.	DMA transfer created with no errors.
+//!						3.	DDmaRequest request fails. 
+//!						
 //!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
-//!							
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace Callback
 	{
@@ -131,23 +197,25 @@
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2574,KBASE-DMA-2575
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    DMA ISR Reque test
+//! TestCaseID      KBASE-DMA-2574,KBASE-DMA-2575
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    DMA ISR Reque test
 //!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestActions     
+//!					1.	Setup DMA transfer to request a callback from ISR.
+//!					2.	Set up ISR to requeue the DMA request on the same channel and adjust its transfer parameters.
+//!					3.	Create single transfer test and run test
+//!					4.	Verify a client can queue the just completed DMA request from within an ISR callback.
 //!
-//!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
+//! TestExpectedResults 
+//!					
+//!					DMA transfer completes and just completed request can be requeued from within an ISR 
+//!					callback on the same channel. Requeued DMA request completes successfully
 //!							
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace ISR_Reque
 	{
@@ -156,6 +224,9 @@
 
 	const TRequestResults requestResult(KErrNone, 1); // request must be in a single fragment
 
+	//-------------------------------------------------------------
+	//This case requeues 4 transfers at the end of an ISR callback
+	//-------------------------------------------------------------
 	namespace endOnIsrCb
 		{
 		TIsrRequeArgs requeArgs[] = {
@@ -174,6 +245,9 @@
 		TTestCase testCase(new (ELeave) CIsrRequeTest(_L("4 Requeues - end on isr cb"), 1, tferArgs, requeArgs, count, expected, &KPreTransferIncrBytes, &KCompareSrcDst), ETrue, capAboveV1);
 		}
 
+	//---------------------------------------------------------------
+	///This case requeues 4 transfers at the end of a thread callback
+	//---------------------------------------------------------------
 	namespace endOnThreadCb
 		{
 		TIsrRequeArgs requeArgs[] = {
@@ -189,7 +263,10 @@
 
 		TTestCase testCase(new (ELeave) CIsrRequeTest(_L("4 Requeues - end on thread cb"), 1, tferArgs, requeArgs, count, expected, &KPreTransferIncrBytes, &KCompareSrcDst), ETrue, capAboveV1);
 		}
-
+	
+	//----------------------------------------------------------------------------------------------
+	// This case requeues a transfer from within an thread callback after changing the transfer size
+	//----------------------------------------------------------------------------------------------
 	namespace changeSize
 		{
 		TIsrRequeArgs requeArgs[] = {
@@ -203,10 +280,13 @@
 		TTestCase testCase(new (ELeave) CIsrRequeTest(_L("1 Requeues - change transfer size"), 1, tferArgs, requeArgs, count, expected, &KPreTransferIncrBytes, &KCompareSrcDst), ETrue, capAboveV1);
 		}
 
+	//--------------------------------------------------------------------------------------------
+	// This case requeues a just completed request from within an ISR callback 
+	//--------------------------------------------------------------------------------------------
 	namespace endOnRedo
 		{
-		// TODO have made this bigger than 4k so that we don't miss the second interrupt when tracing enabled
-		// this indicates the PSL's interrupt handler misses an interrupt if it occurs during the interrupt.
+		// The transfer size has been made bigger than 4K so that we do not miss the second interrupt when tracing 
+		// enabled is. This indicates the PSL's interrupt handler misses an interrupt if it occurs during the interrupt.
 		const TInt size = 0x10000;
 		TDmaTransferArgs tferArgs(0, 2*size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr);
 
@@ -222,6 +302,9 @@
 		TTestCase testCase(new (ELeave) CIsrRequeTest(_L("2 Requeues - Isr redo request repeated"), 1, tferArgs, requeArgs, count, expected, &KPreTransferIncrBytes, &KCompareSrcDst), EFalse, capAboveV1);
 		}
 
+	//--------------------------------------------------------------------------------------------
+	// This case requeues a request from within an ISR callback using invalid requeue parameters
+	//--------------------------------------------------------------------------------------------
 	namespace invalidAddresses
 		{
 		TIsrRequeArgs requeArgs[] = {
@@ -235,41 +318,51 @@
 		// pre and post test would fail because of bad requeue parameters
 		TTestCase testCase(new (ELeave) CIsrRequeTest(_L("Requeue with matching addresses"), 1, tferArgs, requeArgs, count, expected, NULL, NULL), ETrue, capAboveV1);
 		}
-
+	//--------------------------------------------------------------------------------------------
+	// This case requeues a request containing more than 1 fragment from within an ISR callback
+	// 
+	//		
+	// This test case is currently caught by a FAULT instead of a return code
+	// as expected. Currently, the facility to return an error code to the test
+	// framework is not yet supported.
+	//
+	// It has been implemented to expect an error code of KErrGeneral as requeues for request that
+	// contains more than one fragments are not allowed. 
+	//--------------------------------------------------------------------------------------------
 	namespace multipleFragments
 		{
 		TIsrRequeArgs requeArgs[] = {
 			TIsrRequeArgs()
 		};
 		const TInt count = ARRAY_LENGTH(requeArgs);
+		const TRequestResults isrequestResult(KErrNone, 2); // request contains 2 fragments
 
-		const TCallbackRecord callbackRecord = TCallbackRecord(TCallbackRecord::EThread, count + 1).IsrRedoResult(KErrNone);
-
-		TRequestResults results2Fragments = TRequestResults(requestResult).FragmentCount(2);
+		const TCallbackRecord callbackRecord = TCallbackRecord(TCallbackRecord::EIsr, 1).IsrRedoResult(KErrGeneral);
+		TRequestResults results2Fragments = TRequestResults(isrequestResult).FragmentCount(2); 
 		const TResultSet expected(KErrNone, results2Fragments, KErrNone, callbackRecord);
 
 		TTestCase testCase(new (ELeave) CIsrRequeTest(_L("Attempt to Requeue 2 fragment request"), 1, tferArgs, requeArgs, count, expected, &KPreTransferIncrBytes, &KCompareSrcDst, size/2), ETrue, capAboveV1);
 
 		}
-	}
+	}	
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      PBASE-DMA-FUNC-xxx
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    DMA Multiple transfer test
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestCaseID      PBASE-DMA-FUNC-2586
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    DMA Multiple transfer test
+//! TestActions     
+//!						1.Setup DMA transfer to using muliple transfers.
+//!						2.Create multipart transfer test and run test.	
 //!
 //!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
+//! TestExpectedResults 
+//!						1.  DMA tranfer set up with no errors. 
+//!						2.	Multipart transfer tests completes with no issues.		
 //!							
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace Multipart
 	{
@@ -278,7 +371,7 @@
 	const TInt size = 2 * KMega;
 	const TDmaTransferArgs transferArgArray[] = {
 		TDmaTransferArgs(0, size, size, KDmaMemAddr),
-		TDmaTransferArgs(size, 2 * size, size, KDmaMemAddr)
+		TDmaTransferArgs(2 * size, 3 * size, size, KDmaMemAddr)
 	};
 
 	const TResultSet expected[] =
@@ -286,7 +379,6 @@
 		TResultSet(),
 		TResultSet()
 		};
-	const TResultSet expectedResults(isrCallback);
 
 	CMultiTransferTest multipart =
 		CMultiTransferTest(_L("Sg request concatination"), 1, transferArgArray, expected, ARRAY_LENGTH(transferArgArray))
@@ -297,32 +389,32 @@
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2580
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    These tests attempt to queue ISR cb requests while the queue is not 
-//!						empty and queing normal requests when an ISR cb is pending
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestCaseID      KBASE-DMA-2580
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    These tests attempt to queue ISR cb requests while the queue is not 
+//!					empty and queing normal requests when an ISR cb is pending
+//! TestActions     
+//!				
+//!					1.	Setup DMA transfer to request a callback from ISR.
+//!					2.	Create single transfer test and run test
+//!					3.	Queue another request using Queue()before ISR Callback completion
+//!					4.	Verify a DMA framework flags an error.
 //!
 //!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
-//!							
+//! TestExpectedResults 
+//!					DMA framework flags an error  if ISR callback has not been executed 
+//!					for the last time without re-queueing the initial transfer request		
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace IsrAndDfc
 	{
-	// need long transfer, so that 1st request is still queued
-	// when the second one is queued
-	// TODO pause is the better way to ensure this
-	//const TInt size = 2 * KMega;
-	//TODO have changed size to ensure that the first isr callback request in IsrBeforeDfc
-	//will only have one fragment
+	// This test case needs a long transfer so that 1st request is still queued when the second 
+	// one is queued. The use of Pause is recommended in order to guarantee this. For this case, 
+	// the size has been selected to ensure that the first isr callback request in IsrBeforeDfc
+	// will only have one fragment
 	const TInt size = 0x40000;
 	TDmaTransferArgs dfcTransfer(0, size, size, KDmaMemAddr);
 	TDmaTransferArgs isrTransfer(2*size, 3*size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr);
@@ -348,8 +440,9 @@
 		CMultiTransferTest dfcBeforeIsr =
 			CMultiTransferTest(_L("DFC cb req before ISR cb req "), 1, transferArgArray, expected, ARRAY_LENGTH(transferArgArray))
 				.SetPreTransferTest(&KPreTransferIncrBytes)
-				.SetPostTransferTest(&KCompareSrcDst);
-		TTestCase testCase(&dfcBeforeIsr, EFalse, hwDesWanted_skip);
+				.SetPostTransferTest(&KCompareSrcDst)
+				.PauseWhileQueuing();
+		TTestCase testCase(&dfcBeforeIsr, EFalse, pauseRequired_skip, capAboveV1);
 		}
 
 	namespace IsrBeforeDfc
@@ -368,30 +461,32 @@
 		CMultiTransferTest dfcBeforeIsr =
 			CMultiTransferTest(_L("ISR cb req before DFC cb req "), 1, transferArgArray, expected, ARRAY_LENGTH(transferArgArray))
 				.SetPreTransferTest(&KPreTransferIncrBytes)
-				.SetPostTransferTest(&KCompareSrcDst);
-		TTestCase testCase(&dfcBeforeIsr, EFalse, hwDesWanted_skip);
+				.SetPostTransferTest(&KCompareSrcDst)
+				.PauseWhileQueuing();
+		TTestCase testCase(&dfcBeforeIsr, EFalse, pauseRequired_skip, capAboveV1);
 		}
 
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      PBASE-DMA-FUNC-xxx
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    DMA 2D transfer test
+//! TestCaseID      PBASE-DMA-FUNC-2587
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    DMA 2D transfer test
 //!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestActions     
+//!						1. Set up DMA transfer using TDmaTransArgs parameters specified in order to
+//!						   rotate an image by 90 degrees clockwise.
+//!						2. Verify that destination buffer gets transformed according to the DMA
+//!						   transfer arguments after transfer.
 //!
-//!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
+//! TestExpectedResults 
+//!						1. DMA tranfer set up with no errors. 
+//!						2. Destination buffer gets transformed accordingly.
 //!							
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace _2D_Test
 	{
@@ -429,23 +524,25 @@
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2565
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    DMA Fragmentation count test
+//! TestCaseID      KBASE-DMA-2565
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    DMA Fragmentation count test
 //!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestActions     
+//!					1.	Set up the arguments for Fragment using the setting in the test scenario table below.
+//!					2.	Create single transfer test and run test
+//!					3.	Verify that FragmentCount API returns the expected value and framework responds correctly
+//!					4.	Repeat steps 1 to 3 above until all the settings in the scenario table below have been used.
 //!
-//!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
+//! TestExpectedResults 
+//!					On calling FragmentCount (), the number of fragments (descriptors / pseudo descriptors) that
+//!					the transfer request has been split into is returned. 
+//!					
 //!							
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace FragmentationCount
 	{
@@ -454,32 +551,42 @@
 	const TRequestResults requestResult(KErrNone, 128);
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 	CSingleTransferTest test1(_L("Fragmentation Count - 128 fragments"), 1, transferArgs, expectedResults, KKilo);
-	TTestCase testCase(&test1, EFalse);
+	TTestCase testCase(new (ELeave) CMultiVersionTest(&test1), EFalse);
 
 	const TRequestResults requestResult2(KErrNone, 4);
 	const TResultSet expectedResults2(KErrNone, requestResult2, KErrNone, threadCallback);
 	CSingleTransferTest test2(_L("Fragmentation Count - 4 fragments"), 1, transferArgs, expectedResults2, 32*KKilo);
-	TTestCase testCase2(&test2, EFalse);
+	TTestCase testCase2(new (ELeave) CMultiVersionTest(&test2), EFalse);
+
+	// Also specifying an element size to get the PIL to further adjust the
+	// fragment size(s): element size = 32, transfer length = 128KB, max
+	// transfer length = 6500 bytes, # of fragments expected = 21 (20 with 6496
+	// bytes each + 1 with 1152 bytes).
+	TDmaTransferArgs transferArgs3(0, size, size, KDmaMemAddr, KDmaSyncAuto, 0, KDmaAddrModePostIncrement, 32);
+	const TRequestResults requestResult3(KErrNone, 21);
+	const TResultSet expectedResults3(KErrNone, requestResult3, KErrNone, threadCallback);
+	CSingleTransferTest test3(_L("Fragmentation Count - 21 fragments"),
+							  1, transferArgs3, expectedResults3, 6500);
+	TTestCase testCase3(new (ELeave) CMultiVersionTest(&test3), EFalse);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2584,KBASE-DMA-2585
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    DMA Benchmark tests
-//!
-//! @SYMTestActions     
-//!						1.
-//!						2.	
+//! TestCaseID      KBASE-DMA-2584,KBASE-DMA-2585
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    DMA Benchmark tests
+//!					To compare the speed of request fragmentation for a given transfer
+//!					between the new and old frameworks on the NaviEngine platform.
+//! TestActions     
+//!				1.	Fragment a memory to memory dma transfer of 4Mb, where both source and destination are physically contiguous. 
+//!				2.	Fragment using the default element size, and also with a 4K limit.
+//!				3.	Carry out for a channel using pseudo descriptors and for a scatter gather channel.
 //!
+//! TestExpectedResults 
+//!				 The results obtained for both framework versions should  be comparable.							
 //!
-//! @SYMTestExpectedResults 
-//!						1.  
-//!						2.		
-//!							
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //-----------------------------------------------------------------------------------------------
 namespace Benchmark
 	{
@@ -489,8 +596,8 @@
 		const TInt size = 1 * KMega;
 		TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr);
 
-		TTestCase testCase_256k(new (ELeave) CDmaBmFragmentation(_L("1 Mb transfer - 256k frag size"), bmIters, transferArgs, 256 * KKilo), EFalse);
-		TTestCase testCase_8k(new (ELeave) CDmaBmFragmentation(_L("1 Mb transfer - 8k frag size"), bmIters, transferArgs, 8 * KKilo), EFalse);
+		TTestCase testCase_256K(new (ELeave) CDmaBmFragmentation(_L("1 MB transfer - 256K frag size"), bmIters, transferArgs, 256 * KKilo), EFalse);
+		TTestCase testCase_8K(new (ELeave) CDmaBmFragmentation(_L("1 MB transfer - 8K frag size"), bmIters, transferArgs, 8 * KKilo), EFalse);
 		}
 
 	namespace Transfer
@@ -509,16 +616,16 @@
 			TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr);
 
 			TTestCase testCase_128(new (ELeave) CDmaBmTransfer(_L("128 K - 128K frag size"), bmIters, transferArgs, 128 * KKilo), EFalse);
-			TTestCase testCase_16(new (ELeave) CDmaBmTransfer(_L("128 K - 16k frag size"), bmIters, transferArgs, 16 * KKilo), EFalse);
-			TTestCase testCase_4(new (ELeave) CDmaBmTransfer(_L("128 K - 4k frag size"), bmIters, transferArgs, 4 * KKilo), EFalse);
-			TTestCase testCase_1(new (ELeave) CDmaBmTransfer(_L("128 K - 1k frag size"), bmIters, transferArgs, 1 * KKilo), EFalse);
+			TTestCase testCase_16(new (ELeave) CDmaBmTransfer(_L("128 K - 16K frag size"), bmIters, transferArgs, 16 * KKilo), EFalse);
+			TTestCase testCase_4(new (ELeave) CDmaBmTransfer(_L("128 K - 4K frag size"), bmIters, transferArgs, 4 * KKilo), EFalse);
+			TTestCase testCase_1(new (ELeave) CDmaBmTransfer(_L("128 K - 1K frag size"), bmIters, transferArgs, 1 * KKilo), EFalse);
 			}
-		namespace _4Mb
+		namespace _4MB
 			{
 			const TInt size = 4 * KMega;
 			TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr);
 
-			CDmaBmTransfer bmTest(_L("4 Mb"), bmIters, transferArgs, 0);
+			CDmaBmTransfer bmTest(_L("4 MB"), bmIters, transferArgs, 0);
 			TTestCase testCase(&bmTest, EFalse);
 			}
 		}
@@ -544,7 +651,7 @@
 				CDmaBmTransfer bmTest = CDmaBmTransfer(_L("4 bytes DFC cb"), iterations, transferArgs, 0).
 					UseNewDmaApi(ETrue).
 					ExpectedResults(expected);
-				TTestCase testCase(&bmTest, EFalse);
+				TTestCase testCase(&bmTest, EFalse, capAboveV1);
 				}
 			namespace _4K
 				{
@@ -553,7 +660,7 @@
 				CDmaBmTransfer bmTest = CDmaBmTransfer(_L("4K DFC cb"), iterations, transferArgs, 0).
 					UseNewDmaApi(ETrue).
 					ExpectedResults(expected);
-				TTestCase testCase(&bmTest, EFalse);
+				TTestCase testCase(&bmTest, EFalse, capAboveV1);
 				}
 			}
 
@@ -569,7 +676,7 @@
 				CDmaBmTransfer bmTest = CDmaBmTransfer(_L("4 bytes Isr cb"), iterations, transferArgs, 0).
 					UseNewDmaApi(ETrue).
 					ExpectedResults(expected);
-				TTestCase testCase(&bmTest, EFalse);
+				TTestCase testCase(&bmTest, EFalse, capAboveV1);
 				}
 			namespace _4K
 				{
@@ -578,20 +685,21 @@
 				CDmaBmTransfer bmTest = CDmaBmTransfer(_L("4K Isr cb"), iterations, transferArgs, 0).
 					UseNewDmaApi(ETrue).
 					ExpectedResults(expected);
-				TTestCase testCase(&bmTest, EFalse);
+				TTestCase testCase(&bmTest, EFalse, capAboveV1);
 				}
 			}
 		}
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleFragment using CSingleTransferTest
+//! TestCaseID      KBASE-DMA-2560
+//! TestCaseID      KBASE-DMA-2561
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new & old style fragment using CSingleTransferTest
 //!						Test Scenario 1 - DstAddr > SrcAddr & TransferSize=32K & Location is 
 //!						address of a memory buffer
-//! @SYMTestActions     
+//! TestActions     
 //!						1.	Set up the arguments for aTransfeArgs using the settings below.
 //!							
 //!							SrcAddr		 = 4 * KKilo;
@@ -602,15 +710,15 @@
 //!						2.	Setup expected result.
 //!						3.	Create single transfer test and run test
 //!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults 
 //!						1.  TransfeArgs set up in DMA framework
 //!						2.	Expected results set up in DMA framework					
 //!						3.	Fragment request completes and KErrNone returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
-namespace TestNewStyleFragment_1
+namespace Fragment_1
 	{	
 	const TInt srcAddr = 4 * KKilo;
 	const TInt desAddr = 64 * KKilo;
@@ -622,59 +730,18 @@
 	const TRequestResults requestResult(KErrNone, 32); 
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 
-	CSingleTransferTest testscenario_1(_L("TestNewStyleFragment - Test Scenario 1"), 1, transferArgs, expectedResults,KKilo);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("Fragment - Scenario 1"), 1, transferArgs, expectedResults,KKilo));
 
-	TTestCase testCase(&testscenario_1, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_1, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleFragment using CSingleTransferTest
-//!						Test Scenario 2 -  SrcAddr	== DstAddr   					
-//!		
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!							SrcAddr	 = 4 * KKilo;
-//!							desAddr	 = 4 * KKilo;
-//!							transferSize = 32 * KKilo;	
-//!							iFlags		 = KDmaMemAddr;
-//!
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework					
-//!						3.	Fragment passes and KErrNone returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestNewStyleFragment_2
-	{
-	const TInt srcAddr = 4 * KKilo;
-	const TInt desAddr = 4 * KKilo;
-	const TInt transferSize =  32 * KKilo;
-
-	TDmaTransferArgs transferArgs(srcAddr,desAddr, transferSize, KDmaMemAddr);
-	const TRequestResults requestResult(KErrNone, 32); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_2(_L("TestNewStyleFragment - Test Scenario 2"), 1, transferArgs, expectedResults,KKilo);
-
-	TTestCase testCase(&testscenario_2, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_2, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleFragment using CSingleTransferTest
+//! TestCaseID      KBASE-DMA-2560
+//! TestCaseID      KBASE-DMA-2561
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new & old style fragment using CSingleTransferTest
 //!						Test Scenario 3 -  TransferSize=0   
 //!
 //!						1.	Set up the arguments for aTransfeArgs using the settings below.
@@ -688,36 +755,38 @@
 //!						3.	Create single transfer test and run test
 //!
 //!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults 
 //!
 //!						1.  TransfeArgs set up in DMA framework
 //!						2.	Expected results set up in DMA framework			
 //!						3.	Fragment request fails and KErrArgument returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
-namespace TestNewStyleFragment_3
+namespace Fragment_2
 	{
 	const TInt srcAddr = 32 * KKilo;
 	const TInt desAddr = 64 * KKilo;
 	const TInt transferSize = 0;
 	
 	TDmaTransferArgs transferArgs( srcAddr, desAddr, transferSize,KDmaMemAddr);
-	const TRequestResults requestResult(KErrArgument, 0); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
+	const TRequestResults requestResult(KErrNone, 0, KErrArgument, KErrUnknown); 
+	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, TCallbackRecord::Empty());
+
 
-	CSingleTransferTest testscenario_3(_L("TestNewStyleFragment - Test Scenario 3"), 1, transferArgs, expectedResults);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("Fragment - Scenario 3"), 1, transferArgs, expectedResults));
 
-	TTestCase testCase(&testscenario_3, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_3, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleFragment using CSingleTransferTest
+//! TestCaseID      KBASE-DMA-2560
+//! TestCaseID      KBASE-DMA-2561
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new & old style fragment using CSingleTransferTest
 //!						Test Scenario 4 -  TransferSize=1Byte   
 //!
 //!						1.	Set up the arguments for aTransfeArgs using the settings below.
@@ -730,16 +799,16 @@
 //!						2.	Setup expected result.
 //!						3.	Create single transfer test and run test
 //!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults 
 //!
 //!						1.  TransfeArgs set up in DMA framework
 //!						2.	Expected results set up in DMA framework			
 //!						3.	Fragment request completes and KErrNone returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
-namespace TestNewStyleFragment_4
+namespace Fragment_3
 	{	
 	const TInt srcAddr = 32 * KKilo;
 	const TInt desAddr = 64 * KKilo;
@@ -749,17 +818,18 @@
 	const TRequestResults requestResult(KErrNone, 1);
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 
-	CSingleTransferTest testscenario_4(_L("TestNewStyleFragment - Test Scenario 4"), 1, transferArgs, expectedResults);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("Fragment - Scenario 4"), 1, transferArgs, expectedResults));
 
-	TTestCase testCase(&testscenario_4, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_4, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleFragment using CSingleTransferTest
+//! TestCaseID      KBASE-DMA-2560
+//! TestCaseID      KBASE-DMA-2561
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new & old style fragment using CSingleTransferTest
 //!						Test Scenario 5 -  TransferSize=128KB    
 //!
 //!						1.	Set up the arguments for aTransfeArgs using the settings below.
@@ -772,18 +842,17 @@
 //!						2.	Setup expected result.
 //!						3.	Create single transfer test and run test
 //!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults 
 //!
 //!						1.  TransfeArgs set up in DMA framework
 //!						2.	Expected results set up in DMA framework			
 //!						3.	Fragment request completes and KErrNone returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
-namespace TestNewStyleFragment_5
+namespace Fragment_4
 	{
-	
 	const TInt srcAddr		= 16 * KKilo;
 	const TInt desAddr		= 2 * KMega;	
 	const TInt transferSize = 1 * KMega;
@@ -792,17 +861,18 @@
 	const TRequestResults requestResult(KErrNone); 
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 
-	CSingleTransferTest testscenario_5(_L("TestNewStyleFragment - Test Scenario 5"), 1, transferArgs, expectedResults);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("Fragment - Scenario 5"), 1, transferArgs, expectedResults));
 
-	TTestCase testCase(&testscenario_5, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_5, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2560
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleFragment using CSingleTransferTest
+//! TestCaseID      KBASE-DMA-2560
+//! TestCaseID      KBASE-DMA-2561
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new & old style fragment using CSingleTransferTest
 //!						Test Scenario 6 -  TransferSize=3MB   
 //!
 //!						1.	Set up the arguments for aTransfeArgs using the settings below.
@@ -815,451 +885,122 @@
 //!						2.	Setup expected result.
 //!						3.	Create single transfer test and run test
 //!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults 
 //!
 //!						1.  TransfeArgs set up in DMA framework
 //!						2.	Expected results set up in DMA framework			
 //!						3.	Fragment request completes and KErrNone returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
-namespace TestNewStyleFragment_6
+namespace Fragment_5
 	{
 	const TInt srcAddr = 16 * KKilo;
 	const TInt desAddr = 4 * KMega;
 	const TInt transferSize = 3 * KMega;
 
 	TDmaTransferArgs transferArgs(srcAddr, desAddr, transferSize, KDmaMemAddr);
-	const TRequestResults requestResult(KErrNone); 
+	const TRequestResults requestResult(KErrNone);
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 
-	CSingleTransferTest testscenario_6(_L("TestNewStyleFragment - Test Scenario 6"), 1, transferArgs, expectedResults);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("Fragment - Scenario 6"), 1, transferArgs, expectedResults));
 
-	TTestCase testCase(&testscenario_6, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_6, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldstyleFragment using CSingleTransferTest
-//!						Test Scenario 1 - DstAddr > SrcAddr & TransferSize=32K & Location is 
-//!						address of a memory buffer
-//!
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!							SrcAddr		 = 4 * KKilo;
-//!							desAddr		 = 64 * KKilo;
-//!							transferSize = 32 * KKilo;	
-//!							iFlags		 = KDmaMemAddr;
-
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework					
-//!						3.	Fragment request completes and KErrNone returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestOldStyleFragment_1
-	{	
-	const TInt srcAddr = 4 * KKilo;
-	const TInt desAddr = 64 * KKilo;
-	const TInt transferSize =  32 * KKilo;
-	
-	TDmaTransferArgs transferArgs( srcAddr, desAddr, transferSize, KDmaMemAddr);
-
-	const TRequestResults requestResult(KErrNone,32); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_1 = CSingleTransferTest(_L("TestOldStyleFragment - Test Scenario 1"), 1, transferArgs, expectedResults,KKilo).
-		UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&testscenario_1, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_1, ETrue, capAboveV1);
-	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldstyleFragment using CSingleTransferTest
-//!						Test Scenario 2 - DstAddr == SrcAddr
-//!
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!							SrcAddr	 = 4 * KKilo;
-//!							desAddr	 = 4 * KKilo;
-//!							transferSize = 4 * KKilo
-//!							iFlags		 = KDmaMemAddr;
-//!
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	Fragment passes and KErrNone returned
+//! TestCaseID      KBASE-DMA-2562
+//! TestCaseID      KBASE-DMA-2563
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new and old style DDmaRequest using CSingleTransferTest
+//!						Test Scenario 1 -  aMaxTransferSize=0
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestOldStyleFragment_2
-	{
-	const TInt srcAddr = 4 * KKilo;
-	const TInt desAddr = 4 * KKilo;
-	const TInt transferSize =  4 * KKilo;
-
-	TDmaTransferArgs transferArgs(srcAddr,desAddr, transferSize, KDmaMemAddr);
-	const TRequestResults requestResult(KErrNone, 4);  
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_2 = CSingleTransferTest(_L("TestOldStyleFragment - Test Scenario 2"), 1, transferArgs, expectedResults,KKilo)
-		.UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&testscenario_2, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_2, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldstyleFragment using CSingleTransferTest
-//!						Test Scenario 3 -  TransferSize=0  
-//!
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!							SrcAddr	 = 32K
-//!							desAddr	 = 64K;
-//!							transferSize = 0
-//!							iFlags		 = KDmaMemAddr;
-//!
+//!						1.	Set up the DDmaRequest using  aMaxTransferSize set to 0.
 //!						2.	Setup expected result.
 //!						3.	Create single transfer test and run test
 //!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	Fragment request Fails and KErrArgument returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestOldStyleFragment_3
-	{
-
-	const TInt srcAddr = 32 * KKilo;
-	const TInt desAddr = 64 * KKilo;
-	const TInt transferSize = 0;
-	
-	TDmaTransferArgs transferArgs(srcAddr, desAddr, transferSize,KDmaMemAddr);
-	const TRequestResults requestResult(KErrArgument, 0); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_3 = CSingleTransferTest(_L("TestOldStyleFragment - Test Scenario 3"), 1, transferArgs, expectedResults).
-		UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&testscenario_3, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_3, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldstyleFragment using CSingleTransferTest
-//!						Test Scenario 4 -  TransferSize=1Byte   
-//!
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!	
-//!							SrcAddr		 = 32K;
-//!							desAddr		 = 64K;
-//!							transferSize = 1 byte	
-//!							iFlags		 = KDmaMemAddr;
-//!
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults
 //!
 //!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	Fragment request completes and KErrNone returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//------------------------------------------------------------------------------------------------
-namespace TestOldStyleFragment_4
-	{	
-	const TInt srcAddr = 32 * KKilo;
-	const TInt desAddr = 64 * KKilo;
-	const TInt transferSize = 1;
-	
-	TDmaTransferArgs transferArgs( srcAddr, desAddr, transferSize, KDmaMemAddr);
-	const TRequestResults requestResult(KErrNone, 1); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_4 = CSingleTransferTest(_L("TestOldStyleFragment - Test Scenario 4"), 1, transferArgs, expectedResults).
-		UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&testscenario_4, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_4, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldstyleFragment using CSingleTransferTest
-//!						Test Scenario 5 -  TransferSize=1MB
-//!
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!							SrcAddr		 = 16K;
-//!							desAddr		 = 2MB;
-//!							transferSize = 1MB	
-//!							iFlags		 = KDmaMemAddr;
-//!
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	Fragment request completes and KErrNone returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestOldStyleFragment_5
-	{
-	const TInt srcAddr = 16 * KKilo;	
-	const TInt desAddr = 2 * KMega;
-	const TInt transferSize = 1 *  KMega;
-
-	TDmaTransferArgs transferArgs(srcAddr, desAddr, transferSize, KDmaMemAddr);
-
-	const TRequestResults requestResult(KErrNone); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_5 = CSingleTransferTest(_L("TestOldStyleFragment - Test Scenario 5"), 1, transferArgs, expectedResults).
-		UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&testscenario_5, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_5, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2561
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldstyleFragment using CSingleTransferTest
-//!						Test Scenario 6 -  TransferSize=3MB     
-//!
-//!						1.	Set up the arguments for aTransfeArgs using the settings below.
-//!							
-//!							SrcAddr	 = 16K
-//!							desAddr	 = 4MB;
-//!							transferSize = 3MB  
-//!							iFlags		 = KDmaMemAddr;
-//!
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	Fragment request completes and KErrNone returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestOldStyleFragment_6
-	{
-	const TInt srcAddr = 16 * KKilo;
-	const TInt desAddr = 4 * KMega;
-	const TInt transferSize = 3 * KMega; 
-	TDmaTransferArgs transferArgs(srcAddr, desAddr, transferSize, KDmaMemAddr);
-
-	const TRequestResults requestResult(KErrNone); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_6 = CSingleTransferTest(_L("TestOldStyleFragment - Test Scenario 6"), 1, transferArgs, expectedResults).
-		UseNewDmaApi(EFalse);
-
-	TTestCase testCase(&testscenario_6, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_6, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2562
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldStyleDDmaRequest using CSingleTransferTest
-//!						Test Scenario 1 -  aMaxTransferSize=0 
-//!
-//!						1.	Set up the DDmaRequest using  aMaxTransferSize set to 0. 
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
+//!						2.	Expected results set up in DMA framework
 //!						3.	DDmaRequest constructor behaves as expected and KErrArgument returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //------------------------------------------------------------------------------------------------
-namespace TestOldStyleDDmaRequest_1
+namespace DDmaRequest_1
 	{
 	const TInt desAddr = 4 * KKilo;
 	const TInt transferSize = 4 * KKilo;
 	TDmaTransferArgs transferArgs(0, desAddr, transferSize, KDmaMemAddr);
 
-	const TRequestResults requestResult(KErrNone, 0); 
+	const TRequestResults requestResult(KErrNone, 0);
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 
-	CSingleTransferTest testscenario_1 = CSingleTransferTest(_L("TestOldStyleDDmaRequest - Test Scenario 1"), 1, transferArgs, expectedResults,0).
-		UseNewDmaApi(EFalse);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("DDmaRequest - Scenario 1"), 1, transferArgs, expectedResults,0));
 
-	TTestCase testCase(&testscenario_1, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_1, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
 //!-------------------------------------------------------------------------------------------------
-//! @SYMTestCaseID       KBASE-DMA-2562
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestOldStyleDDmaRequest using CSingleTransferTest
-//!						Test Scenario 2 -  aMaxTransferSize= 65535   
+//! TestCaseID      KBASE-DMA-2562
+//! TestCaseID      KBASE-DMA-2563
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    Test new and old style DDmaRequest using CSingleTransferTest
+//!						Test Scenario 2 -  aMaxTransferSize= (64K - 1)   // 65535
 //!
-//!						1.	Set up the arguments for DDmaRequest using aMaxTransferSize set to 65535.
+//!						1.	Set up the arguments for DDmaRequest using aMaxTransferSize set to (64K - 1).
 //!						2.	Setup expected result.
 //!						3.	Create single transfer test and run test
 //!
-//! @SYMTestExpectedResults 
+//! TestExpectedResults
 //!
 //!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
+//!						2.	Expected results set up in DMA framework
 //!						3.	DDmaRequest constructor behaves as expected and KErrArgument returned
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //---------------------------------------------------------------------------------------------------
-namespace TestOldStyleDDmaRequest_2
+namespace DDmaRequest_2
 	{
 	const TInt desAddr = 4 * KKilo;
 	const TInt transferSize = 4 * KKilo;
 	TDmaTransferArgs transferArgs(0, desAddr, transferSize, KDmaMemAddr);
 
-	const TRequestResults requestResult(KErrNone, 1); 
+	const TRequestResults requestResult(KErrNone, 1);
 	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
 
-	CSingleTransferTest testscenario_2 = CSingleTransferTest(_L("TestOldStyleDDmaRequest - Test Scenario 2"), 1, transferArgs, expectedResults, 65535).
-		UseNewDmaApi(EFalse);
+	CMultiVersionTest multiVersion(new (ELeave) CSingleTransferTest(_L("DDmaRequest - Scenario 2"), 1, transferArgs, expectedResults, trans64K_1));
 
-	TTestCase testCase(&testscenario_2, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_2, ETrue, capAboveV1);
+	TTestCase testCase(&multiVersion, EFalse);
+	TTestCase testCaseConcurrent(&multiVersion, ETrue);
 	}
 
 //----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2563
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleDDmaRequest using CSingleTransferTest
-//!						Test Scenario 1 -  aMaxTransferSize=0 
-//!
-//!						1.	Set up the DDmaRequest using  aMaxTransferSize set to 0. 
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	DDmaRequest constructor behaves as expected and KErrArgument returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-namespace TestNewStyleDDmaRequest_1
-	{
-	const TInt desAddr = 4 * KKilo;
-	const TInt transferSize = 4 * KKilo;
-	TDmaTransferArgs transferArgs(0, desAddr, transferSize, KDmaMemAddr);
-
-	const TRequestResults requestResult(KErrNone, 0); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_1(_L("TestNewStyleDDmaRequest - Test Scenario 1"), 1, transferArgs, expectedResults,0);
-
-	TTestCase testCase(&testscenario_1, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_1, ETrue, capAboveV1);
-	}
-
-//!-------------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBASE-DMA-2563
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    TestNewStyleDDmaRequest using CSingleTransferTest
-//!						Test Scenario 2 -  aMaxTransferSize= 65535   
-//!
-//!						1.	Set up the arguments for DDmaRequest using aMaxTransferSize set to 65535.
-//!						2.	Setup expected result.
-//!						3.	Create single transfer test and run test
-//!
-//! @SYMTestExpectedResults 
-//!
-//!						1.  TransfeArgs set up in DMA framework
-//!						2.	Expected results set up in DMA framework			
-//!						3.	DDmaRequest constructor behaves as expected and KErrArgument returned
-//!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//---------------------------------------------------------------------------------------------------
-namespace TestNewStyleDDmaRequest_2
-	{
-	const TInt desAddr = 4 * KKilo;
-	const TInt transferSize = 4 * KKilo;
-	TDmaTransferArgs transferArgs(0, desAddr, transferSize, KDmaMemAddr);
-
-	const TRequestResults requestResult(KErrNone, 1); 
-	const TResultSet expectedResults(KErrNone, requestResult, KErrNone, threadCallback);
-
-	CSingleTransferTest testscenario_2(_L("TestNewStyleDDmaRequest - Test Scenario 2"), 1, transferArgs, expectedResults, 65535);
-
-	TTestCase testCase(&testscenario_2, EFalse, capAboveV1);
-	TTestCase testCaseConcurrent(&testscenario_2, ETrue, capAboveV1);
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      PBASE-DMA-FUNC-xxx
-//! @SYMTestType        CIT
-//! @SYMPREQ            REQ
-//! @SYMTestCaseDesc    SmallFrags: This test provokes the failure seen in DEF140598
+//! TestCaseID      KBASE-DMA-2585
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    SmallFrags: This test provokes the failure seen in DEF140598
 //!						The test checks that requests with small fragments
 //!						do not trigger a spurious missed interrupt clean up
 //!
-//! @SYMTestExpectedResults 
+//! TestActions     
+//!						1.	Open a DMA channel for a transfer.
+//!						2.	Create single transfer test using small frags and run test
 //!
-//!						1.  		
-//!						2.	
+//! TestExpectedResults 
+//!						1.  DMA channel opens and KErrNone returned.
+//!						2.	DMA transfer completes with no errors.
 //!
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
+//! TestPriority        High
+//! TestStatus          Implemented
 //----------------------------------------------------------------------------------------------
 namespace SmallFrags
 	{
@@ -1269,19 +1010,205 @@
 	const TResultSet expectedResults(threadCallback);
 
 	TTestCase testCase(
-			new (ELeave) CSingleTransferTest(_L("8 * 4byte frags"), 10, transferArgs, expectedResults, 4),
-			EFalse, capAboveV1);
+			new (ELeave) CMultiVersionTest(new (ELeave) CSingleTransferTest(_L("8 * 4byte frags"), 10, transferArgs, expectedResults, 4)),
+			EFalse);
+	}
+
+//----------------------------------------------------------------------------------------------
+//! TestCaseID      KBASE-DMA-2568
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    This test checks the correct behaviour of Close API in the new DMA framework
+//!
+//! TestActions     
+//!						1.  Open a DMA channel
+//!						2.	Open DMA Channel again
+//!						3	Close the DMA channel.
+//!						4	Open DMA channel to verify that the DMA channel closed.						
+//!
+//! TestExpectedResults 
+//!						1.  DMA channel opens and KErrNone returned.
+//!						2.	DMA Framework returns KErrInUse as channel is already open.					
+//!						3.	DMA channel closes and KErrNone returned.
+//!						4.	DMA channel opens and KErrNone returned.						
+//!							
+//!
+//! TestPriority        High
+//! TestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+namespace CloseApiTest
+	{
+	COpenCloseTest testCloseApi = COpenCloseTest(_L("Close API Test"), 1).RunOpenApiTest(EFalse); 
+	TTestCase testCaseCloseApi(&testCloseApi, EFalse, capAboveV1);
+	}
+
+//----------------------------------------------------------------------------------------------
+//! TestCaseID      KBASE-DMA-2564
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    This test checks the correct behaviour of Open API in the new DMA framework
+//!
+//! TestActions     
+//!						1.  Open a DMA channel
+//!						2.	Verify that channel is really open by closing DMA channel
+//!
+//! TestExpectedResults 
+//!						1.  DMA channel opens and KErrNone returned
+//!						2.  DMA channel closes again returns KErrNone.
+//!
+//! TestPriority        High
+//! TestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+namespace OpenApiTest
+	{
+	COpenCloseTest testOpenApi = COpenCloseTest(_L("Open API Test"), 1).RunOpenApiTest(ETrue); 
+	TTestCase testCaseOpenApi(&testOpenApi, EFalse, capAboveV1);
+	}
+
+//----------------------------------------------------------------------------------------------
+//! TestCaseID      KBASE-DMA-2567
+//! TestType        CIT
+//! PREQ            REQ
+//! TestCaseDesc    This test verifies the correct behavior of TBool IsQueueEmpty() in the new DMA 
+//!					framework and check its return value 
+//!
+//! TestActions     
+//!						1.	Open a single DMA channel for a transfer.
+//!						2.	Setup a DMA request and Fragment the request.
+//!						3.	Call IsQueueEmpty().
+//!						4.	Queue the DMA request.
+//!						5.	Call IsQueueEmpty().
+//! TestExpectedResults 
+//!						1.  DMA channel opens and KErrNone returned.
+//!						2.  DMA request created and fragmented and KErrNone returned.
+//!						3.  IsQueueEmpty() returns ETrue.
+//!						4.  Request queued and KErrNone returned
+//!						5.	IsQueueEmpty() returns EFalse.
+//!
+//! TestPriority        High
+//! TestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+namespace IsQueueEmptyTest
+	{
+	const TInt size = 2 * KMega;
+	const TDmaTransferArgs transferArgArray[] = {
+		TDmaTransferArgs(0, size, size, KDmaMemAddr),
+		TDmaTransferArgs(2 * size, 3 * size, size, KDmaMemAddr)
+	};
+
+	const TResultSet expected[] =
+		{
+		TResultSet(),
+		TResultSet()
+		};
+	const TResultSet expectedResults(isrCallback);
+
+	CIsQueueEmptyTest isQueueEmpty =
+		CIsQueueEmptyTest(_L("IsQueueEmptyTest using muliple frags"), 1, transferArgArray, expected, ARRAY_LENGTH(transferArgArray))
+			.SetPreTransferTest(&KPreTransferIncrBytes)
+			.SetPostTransferTest(&KCompareSrcDst);
+
+	TTestCase testCase(&isQueueEmpty,EFalse,capAboveV1,pauseRequired_skip);
 	}
 
 
-//TODO TTestCase could automatically be added to aray by ctor
-//
+static TTestCase* StaticSimpleTestArray[] = {
+	&Simple_1::testCase,
+	&Simple_1::testCaseConcurrent,
+};
+
+static TTestCase* StaticCallbackTestArray[] = {
+	&Callback::testCase,
+	&Callback::testCaseOldRequest,	
+};
+
+static TTestCase* StaticIsrRequeTestArray[] = {
+	&ISR_Reque::endOnRedo::testCase,
+	&ISR_Reque::endOnIsrCb::testCase,
+	&ISR_Reque::endOnThreadCb::testCase,
+	&ISR_Reque::changeSize::testCase,
+#ifdef _DEBUG
+	&ISR_Reque::invalidAddresses::testCase, // addresses only checked in UDEB
+#endif
+#ifdef _REMOVEDTEST
+	// This test case is currently caught by a FAULT instead of a return code
+	// as expected. Currently, the facility to return an error code to the test
+	// framework is not yet supported.
+	&ISR_Reque::multipleFragments::testCase, 
+#endif
+};
+
+static TTestCase* StaticMultipartTestArray[] = {
+	&Multipart::testCase,
+};
+
+static TTestCase* StaticIsrAndDfcTestArray[] = {
+	&IsrAndDfc::DfcBeforeIsr::testCase,
+	&IsrAndDfc::IsrBeforeDfc::testCase,
+};
+
+static TTestCase* Static2DTestArray[] = {
+	&_2D_Test::testCase2d
+};
+
+static TTestCase* StaticFragmentTestArray[] = {
+	&FragmentationCount::testCase,
+	&FragmentationCount::testCase2,
+	&SmallFrags::testCase,
+	&Fragment_1::testCase,
+	&Fragment_1::testCaseConcurrent,
+	&Fragment_2::testCase,
+	&Fragment_2::testCaseConcurrent,
+	&Fragment_3::testCase,
+	&Fragment_3::testCaseConcurrent,
+	&Fragment_4::testCase,
+	&Fragment_4::testCaseConcurrent,
+	&Fragment_5::testCase,
+	&Fragment_5::testCaseConcurrent,
+};
+
+static TTestCase* StaticBenchmarkTestArray[] = {
+	// Benchmarks are only really meaningful
+	// on UREL builds
+	&Benchmark::Frag::testCase_256K,
+	&Benchmark::Frag::testCase_8K,
+	&Benchmark::Transfer::_128K::testCase_128,
+	&Benchmark::Transfer::_128K::testCase_16,
+	&Benchmark::Transfer::_128K::testCase_4,
+	&Benchmark::Transfer::_128K::testCase_1,
+	&Benchmark::Transfer::_4Bytes::testCase,
+	&Benchmark::Transfer::_4MB::testCase,
+	&Benchmark::CompareIsrDfcCb::Dfc::_4Bytes::testCase,
+	&Benchmark::CompareIsrDfcCb::Isr::_4Bytes::testCase,
+	&Benchmark::CompareIsrDfcCb::Dfc::_4K::testCase,
+	&Benchmark::CompareIsrDfcCb::Isr::_4K::testCase,
+};
+
+static TTestCase* StaticRequestTestArray[] = {
+	&DDmaRequest_1::testCase,
+	&DDmaRequest_1::testCaseConcurrent,
+	&DDmaRequest_2::testCase,
+	&DDmaRequest_2::testCaseConcurrent,
+};
+
+static TTestCase* StaticChannelTestArray[] = {
+	&CloseApiTest::testCaseCloseApi,
+	&OpenApiTest::testCaseOpenApi,
+};
+
+static TTestCase* StaticSuspendTestArray[] = {
+	&PauseResumeApiTest::testCasePauseResume,  
+};
+
+static TTestCase* StaticQueueTestArray[] = {
+	&CancelAllTest::testCase, 
+	&IsQueueEmptyTest::testCase,	
+};
+
 //Append new test cases here
 static TTestCase* StaticTestArray[] = {
 	&Simple_1::testCase,
-	&Simple_1::testCaseConcurrent,
-	&Simple_2::testCase,
-	&Simple_2::testCaseConcurrent,
+	&Simple_1::testCaseConcurrent,	
 	&Callback::testCase,
 	&Callback::testCaseOldRequest,
 	&ISR_Reque::endOnRedo::testCase,
@@ -1291,62 +1218,67 @@
 #ifdef _DEBUG
 	&ISR_Reque::invalidAddresses::testCase, // addresses only checked in UDEB
 #endif
-	//&ISR_Reque::multipleFragments::testCase, // This error condition is currently caught by a FAULT instead of a return code
+#ifdef _REMOVEDTEST
+	// This test case is currently caught by a FAULT instead of a return code
+	// as expected. Currently, the facility to return an error code to the test
+	// framework is not yet supported.
+	&ISR_Reque::multipleFragments::testCase, 
+#endif
 	&Multipart::testCase,
 	&IsrAndDfc::DfcBeforeIsr::testCase,
 	&IsrAndDfc::IsrBeforeDfc::testCase,
 	&_2D_Test::testCase2d,
 	&FragmentationCount::testCase,
 	&FragmentationCount::testCase2,
+	&FragmentationCount::testCase3,
 	&SmallFrags::testCase,
 #ifndef _DEBUG
 	// Benchmarks are only really meaningful
 	// on UREL builds
-	&Benchmark::Frag::testCase_256k,
-	&Benchmark::Frag::testCase_8k,
+	&Benchmark::Frag::testCase_256K,
+	&Benchmark::Frag::testCase_8K,
 	&Benchmark::Transfer::_128K::testCase_128,
 	&Benchmark::Transfer::_128K::testCase_16,
 	&Benchmark::Transfer::_128K::testCase_4,
 	&Benchmark::Transfer::_128K::testCase_1,
 	&Benchmark::Transfer::_4Bytes::testCase,
-	&Benchmark::Transfer::_4Mb::testCase,
+	&Benchmark::Transfer::_4MB::testCase,
 	&Benchmark::CompareIsrDfcCb::Dfc::_4Bytes::testCase,
 	&Benchmark::CompareIsrDfcCb::Isr::_4Bytes::testCase,
 	&Benchmark::CompareIsrDfcCb::Dfc::_4K::testCase,
 	&Benchmark::CompareIsrDfcCb::Isr::_4K::testCase,
 #endif
-	&TestNewStyleFragment_1::testCase,
-	&TestNewStyleFragment_1::testCaseConcurrent,
-	&TestNewStyleFragment_2::testCase,
-	&TestNewStyleFragment_2::testCaseConcurrent,
-	//&TestNewStyleFragment_3::testCase,
-	//&TestNewStyleFragment_3::testCaseConcurrent,
-	&TestNewStyleFragment_4::testCase,
-	&TestNewStyleFragment_4::testCaseConcurrent,
-	&TestNewStyleFragment_5::testCase,
-	&TestNewStyleFragment_5::testCaseConcurrent,
-	&TestNewStyleFragment_6::testCase,
-	&TestNewStyleFragment_6::testCaseConcurrent,
-	&TestOldStyleFragment_1::testCase,
-	&TestOldStyleFragment_1::testCaseConcurrent,
-	&TestOldStyleFragment_2::testCase,
-	&TestOldStyleFragment_2::testCaseConcurrent,
-	//&TestOldStyleFragment_3::testCase,
-	//&TestOldStyleFragment_3::testCaseConcurrent,
-	&TestOldStyleFragment_4::testCase,
-	&TestOldStyleFragment_4::testCaseConcurrent,
-	&TestOldStyleFragment_5::testCase,
-	&TestOldStyleFragment_5::testCaseConcurrent,
-	&TestOldStyleFragment_6::testCase,
-	&TestOldStyleFragment_6::testCaseConcurrent,
-	&TestOldStyleDDmaRequest_1::testCase,
-	&TestOldStyleDDmaRequest_1::testCaseConcurrent,
-	&TestOldStyleDDmaRequest_2::testCase,
-	&TestOldStyleDDmaRequest_2::testCaseConcurrent,
-	&TestNewStyleDDmaRequest_1::testCase,
-	&TestNewStyleDDmaRequest_1::testCaseConcurrent,
-	&TestNewStyleDDmaRequest_2::testCase,
-	&TestNewStyleDDmaRequest_2::testCaseConcurrent,
+	&Fragment_1::testCase,
+	&Fragment_1::testCaseConcurrent,
+	&Fragment_2::testCase,
+	&Fragment_2::testCaseConcurrent,
+	&Fragment_3::testCase,
+	&Fragment_3::testCaseConcurrent,
+	&Fragment_4::testCase,
+	&Fragment_4::testCaseConcurrent,
+	&Fragment_5::testCase,
+	&Fragment_5::testCaseConcurrent,	
+	&DDmaRequest_1::testCase,
+	&DDmaRequest_1::testCaseConcurrent,
+	&DDmaRequest_2::testCase,
+	&DDmaRequest_2::testCaseConcurrent,
+	&CloseApiTest::testCaseCloseApi,
+	&OpenApiTest::testCaseOpenApi,
+	&PauseResumeApiTest::testCasePauseResume,  
+	&CancelAllTest::testCase,
+	&IsQueueEmptyTest::testCase,	
 };
 
 RPointerArray<TTestCase> TestArray(StaticTestArray, ARRAY_LENGTH(StaticTestArray));
+RPointerArray<TTestCase> TestArrayIsrAndDfc(StaticIsrAndDfcTestArray, ARRAY_LENGTH(StaticIsrAndDfcTestArray));
+RPointerArray<TTestCase> TestArraySimple(StaticSimpleTestArray, ARRAY_LENGTH(StaticSimpleTestArray));
+RPointerArray<TTestCase> TestArrayQueue(StaticQueueTestArray, ARRAY_LENGTH(StaticQueueTestArray));
+RPointerArray<TTestCase> TestArrayChannel(StaticChannelTestArray, ARRAY_LENGTH(StaticChannelTestArray));
+RPointerArray<TTestCase> TestArraySuspend(StaticSuspendTestArray, ARRAY_LENGTH(StaticSuspendTestArray));
+RPointerArray<TTestCase> TestArrayFragment(StaticFragmentTestArray, ARRAY_LENGTH(StaticFragmentTestArray));
+RPointerArray<TTestCase> TestArrayBenchmark(StaticBenchmarkTestArray, ARRAY_LENGTH(StaticBenchmarkTestArray));
+RPointerArray<TTestCase> TestArray2DTest(Static2DTestArray, ARRAY_LENGTH(Static2DTestArray));
+RPointerArray<TTestCase> TestArrayMultiPart(StaticMultipartTestArray, ARRAY_LENGTH(StaticMultipartTestArray));
+RPointerArray<TTestCase> TestArrayIsrReque(StaticIsrRequeTestArray, ARRAY_LENGTH(StaticIsrRequeTestArray));
+RPointerArray<TTestCase> TestArrayCallback(StaticCallbackTestArray, ARRAY_LENGTH(StaticCallbackTestArray));
+RPointerArray<TTestCase> TestArrayRequest(StaticRequestTestArray, ARRAY_LENGTH(StaticRequestTestArray));
--- a/kerneltest/e32test/dmav2/test_thread.cpp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/test_thread.cpp	Tue May 04 09:44:26 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
@@ -38,7 +38,6 @@
 
 TTestThread::~TTestThread()
 	{
-	//RTest::CloseHandleAndWaitForDestruction(iThread);
 	iThread.Close();
 	}
 
@@ -90,6 +89,10 @@
 	iName.Close();
 	}
 
+void CTest::SetupL()
+	{
+	}
+
 void CTest::operator()()
 	{
 	for(TInt i=0; i<iIterations; i++)
@@ -139,7 +142,7 @@
 
 	for(TInt i=0; i<aNumberOfThreads; i++)
 		{
-		//test.Next(_L("Create test thread"));
+		test.Next(_L("Create test thread"));
 		CTest* newTest = aTest.Clone();
 		test_NotNull(newTest);
 
--- a/kerneltest/e32test/dmav2/test_thread.h	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/dmav2/test_thread.h	Tue May 04 09:44:26 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
@@ -88,23 +88,24 @@
 class CTest : public CBase, public TFunctor
 	{
 public:
-	~CTest();
+	virtual ~CTest();
 
 	virtual void operator()();
 	virtual void RunTest() = 0;
 	virtual CTest* Clone() const = 0;
 
+	virtual void SetupL();
+
 	/**
 	Prints a formatted description of the test
 	*/
-	void Announce() const;
+	virtual void Announce() const;
 
 	const TDesC& Name() const;
 
 	/**
 	Should print the type of test, with no newlines.
 	eg. "Transfer", "Fragmentation"
-	TODO drop the function, just add a test type member
 	*/
 	virtual void PrintTestType() const = 0;
 
--- a/kerneltest/e32test/group/t_dma2.mmp	Thu Apr 29 11:08:53 2010 +0100
+++ b/kerneltest/e32test/group/t_dma2.mmp	Tue May 04 09:44:26 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 TARGET         t_dma2.exe
 TARGETTYPE     EXE
 SOURCEPATH	../dmav2
-SOURCE         t_dma2.cpp test_cases.cpp self_test.cpp dma_api_tests.cpp d_dma2_cmn.cpp
+SOURCE         t_dma2.cpp test_cases.cpp self_test.cpp  d_dma2_cmn.cpp
 SOURCE		   test_thread.cpp
 SOURCEPATH	../../../kernel/eka/drivers/dma
 SOURCE		dma2_shared.cpp