kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/regifc.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/regifc.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,897 @@
+// Copyright (c) 2003-2009 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:
+//
+
+#include <drivers/sdio/sdiocard.h>
+#include "utraceepbussdio.h"
+#include <drivers/sdio/regifc.h>
+#include <drivers/sdio/cisreader.h>
+
+
+
+EXPORT_C DSDIORegisterInterface::DSDIORegisterInterface(TSDIOCard* aCardP, TUint8 aFunctionNumber) :
+/**
+@publishedPartner
+@released
+
+Contructs a DSDIORegisterInterface with the specified function number.
+
+@param aCardP Pointer to the TSDIOCard object that owns the function.
+@param aFunctionNumber The number of the function upon which the register interface operates.
+*/
+	DSDIOSession(iSessionEndCallBack, aFunctionNumber),
+	iSessionEndCallBack(DSDIORegisterInterface::SessionEndCallBack,this),
+	iSessionEndDfc(DSDIORegisterInterface::SessionEndDfc,this,1),
+	iSessionErr(KErrNone),
+	iMutexLock(NULL),
+	iIsSync(ETrue)
+	{
+	TRACE3(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceConstructor, reinterpret_cast<TUint32>(this), reinterpret_cast<TUint32>(aCardP), aFunctionNumber); // @SymTraceDataPublishedTvk
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	iTraceData = new TTraceData;
+#endif
+	
+	Init(aCardP);	
+
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceConstructorReturning, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+	}
+
+
+EXPORT_C DSDIORegisterInterface::DSDIORegisterInterface(TSDIOCard* aCardP, TUint8 aFunctionNumber, DMutex* aMutexLock) :
+/**
+@publishedPartner
+@released
+
+Contructs a DSDIORegisterInterface with the specified function number.
+
+@param aCardP Pointer to the TSDIOCard object that owns the function.
+@param aFunctionNumber The number of the function upon which the register interface operates.
+@param aMutexLock Pointer to the mutex used to ensure exclusive access to the register interface.
+*/
+	DSDIOSession(iSessionEndCallBack, aFunctionNumber),
+	iSessionEndCallBack(DSDIORegisterInterface::SessionEndCallBack,this),
+	iSessionEndDfc(DSDIORegisterInterface::SessionEndDfc,this,1),
+	iSessionErr(KErrNone),
+	iMutexLock(aMutexLock),
+	iIsSync(ETrue)
+	{
+	TRACE3(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceConstructor, reinterpret_cast<TUint32>(this), reinterpret_cast<TUint32>(aCardP), aFunctionNumber); // @SymTraceDataPublishedTvk
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	iTraceData = new TTraceData;
+#endif
+
+	Init(aCardP);
+
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceConstructorReturning, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+	}
+
+
+EXPORT_C DSDIORegisterInterface::~DSDIORegisterInterface()
+/**
+Destroys the DSDIORegisterInterface instance.
+*/
+	{
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceDestructor, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	delete iTraceData;
+#endif
+
+	StackP()->MMCSocket()->EndInCritical();
+	iSessionEndDfc.Cancel();
+
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceDestructorReturning, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+	}
+
+
+void DSDIORegisterInterface::Init(TSDIOCard* aCardP)
+/**
+Initialise the DSDIORegisterInterface instance.
+*/
+	{
+	DMMCStack* stackP = aCardP->iStackP;
+
+	SetCallback(iSessionEndCallBack);
+	SetCard(aCardP);
+	SetStack(stackP);
+
+	iSessionEndDfc.SetDfcQ(&stackP->MMCSocket()->iDfcQ);
+	}
+
+
+inline TBool DSDIORegisterInterface::ValidAddress(TUint32 aAddress) const 
+/**
+Validates that the address is within range
+@return EFalse if the address is out of range
+*/
+	{
+	return((aAddress &~ KSdioCmdAddressMask) == 0);
+	}
+	
+	
+EXPORT_C TInt DSDIORegisterInterface::Read8(TUint32 aReg, TUint8* aReadDataP)
+/**
+@publishedPartner
+@released
+
+Reads a single 8-bit value from the specified register.
+
+@param aReg Source register address
+@param aReadDataP Destination address
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG(aReadDataP != NULL, DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceRead, reinterpret_cast<TUint32>(this), 1); // @SymTraceDataPublishedTvk
+	
+	if(!ValidAddress(aReg))
+		return(KErrArgument);
+	
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP)
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE0(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIORead)); // @SymTraceDataInternalTechnology
+	if (iTraceData)
+		iTraceData->Set(aReadDataP, 1);
+#endif
+	
+	SetupCIMIoRead(aReg, aReadDataP);
+	
+	TInt err = EngageSdio();
+	
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceReadReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}
+
+EXPORT_C TInt DSDIORegisterInterface::Write8(TUint32 aReg, TUint8 aWriteVal)
+/**
+@publishedPartner
+@released
+
+Writes a single 8-bit value to the specified register.  
+
+@param aReg Destination register address.
+@param aWriteVal 8-Bit value to write.
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	return Write8(aReg, aWriteVal, NULL);
+	}
+
+EXPORT_C TInt DSDIORegisterInterface::Write8(TUint32 aReg, TUint8 aWriteVal, TUint8* aReadDataP)
+/**
+@publishedPartner
+@released
+
+Writes a single 8-bit value to the specified register.  If the optional parameter aReadData is 
+not NULL, a read-after-write operation shall be performed.
+
+@param aReg Destination register address.
+@param aWriteVal 8-Bit value to write.
+@param aReadDataP If specified, a read-after-write operation is performed and stored here.
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceWrite, reinterpret_cast<TUint32>(this), 1); // @SymTraceDataPublishedTvk
+
+	if(!ValidAddress(aReg))
+		return(KErrArgument);
+	
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIOWrite, &aWriteVal, 1)); // @SymTraceDataInternalTechnology
+	if (iTraceData)
+		iTraceData->Set(aReadDataP, 1);
+#endif
+	
+	SetupCIMIoWrite(aReg, aWriteVal, aReadDataP);
+	TInt err = EngageSdio();
+	
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceWriteReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}
+
+EXPORT_C TInt DSDIORegisterInterface::Modify8(TUint32 aReg, TUint8 aSet, TUint8 aClr)
+/**
+@publishedPartner
+@released
+
+Performs a bitwise read-modify-write operation on the specified register.  
+
+@param aReg Destination register address
+@param aSet Bitmask of values to Set
+@param aClr Bitmask of values to Clear
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	return Modify8(aReg, aSet, aClr, NULL);
+	}
+
+EXPORT_C TInt DSDIORegisterInterface::Modify8(TUint32 aReg, TUint8 aSet, TUint8 aClr, TUint8* aReadDataP)
+/**
+@publishedPartner
+@released
+
+Performs a bitwise read-modify-write operation on the specified register.  If the optional 
+parameter aReadData is not NULL, a read-after-write operation shall be performed.
+
+@param aReg Destination register address
+@param aSet Bitmask of values to Set
+@param aClr Bitmask of values to Clear
+@param aReadDataP If specified, a read-after-write operation is performed and stored here.
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG((aSet & aClr) == 0, DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceModify, reinterpret_cast<TUint32>(this), 1); // @SymTraceDataPublishedTvk
+	
+	if(!ValidAddress(aReg))
+		return(KErrArgument);
+	
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE2(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIOModified, static_cast<TUint32>(aSet), static_cast<TUint32>(aClr))); // @SymTraceDataInternalTechnology
+	if (iTraceData)
+		iTraceData->Clear();
+#endif
+
+	SetupCIMIoModify(aReg, aSet, aClr, aReadDataP);
+	TInt err = EngageSdio();
+	
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceModifyReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}
+
+EXPORT_C TInt DSDIORegisterInterface::ReadMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen)
+/**
+@publishedPartner
+@released
+
+Reads aLen bytes starting from the specified register offset. 
+The destinatation address will be automatically incremented.  
+
+@param aReg Source register address
+@param aDataP Destination address
+@param aLen The number of bytes to transfer
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	return ReadMultiple8(aReg, aDataP, aLen, ETrue);
+	}
+
+EXPORT_C TInt DSDIORegisterInterface::ReadMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen, TBool aAutoInc)
+/**
+@publishedPartner
+@released
+
+Reads aLen bytes starting from the specified register offset. The parameter aAutoInc allows 
+auto-increment of the source address to be disabled if, for example, reading from a FIFO on the card.
+
+@param aReg Source register address
+@param aDataP Destination address
+@param aLen The number of bytes to transfer
+@param aAutoInc Specify ETrue to auto-increment the source address
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG(aDataP != NULL, DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceReadMultiple, reinterpret_cast<TUint32>(this), aLen); // @SymTraceDataPublishedTvk
+	
+	if(!ValidAddress(aReg) || aLen == 0)
+		return(KErrArgument);
+		
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE0(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIORead)); // @SymTraceDataInternalTechnology
+	if (iTraceData)
+		iTraceData->Set(aDataP, aLen);
+#endif
+
+	SetupCIMIoReadMultiple(aReg, aLen, aDataP, aAutoInc);
+	TInt err = EngageSdio();
+
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceReadMultipleReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+
+	return err;
+	}
+	
+EXPORT_C TInt DSDIORegisterInterface::ReadMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen)
+/**
+@publishedPartner
+@released
+
+Reads aLen bytes starting from the specified register offset. 
+Transfers are performed utilising DMA, this is dependent on platform support.
+The destinatation address will be automatically incremented.
+
+@param aReg         Source register address
+@param aChunk       Chunk which hosts the destination buffer
+@param aOffset      The offset from the start of the chunk, to the start of the destination buffer
+@param aLen         The number of bytes to transfer
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	return ReadMultiple8(aReg, aChunk, aOffset, aLen, ETrue); 
+	}	
+
+EXPORT_C TInt DSDIORegisterInterface::ReadMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen, TBool aAutoInc)
+/**
+@publishedPartner
+@released
+
+Reads aLen bytes starting from the specified register offset. The aAutoInc parameter allows 
+auto-increment of the source address to be disabled if, for example, reading from a FIFO on the card.
+Transfers are performed utilising DMA, this is dependent on platform support.
+
+@param aReg         Source register address
+@param aChunk       Chunk which hosts the destination buffer
+@param aOffset      The offset from the start of the chunk, to the start of the destination buffer
+@param aLen         The number of bytes to transfer
+@param aAutoInc     Specify ETrue to auto-increment the source address
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG(aChunk != NULL, DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceReadMultipleChunk, reinterpret_cast<TUint32>(this), aLen); // @SymTraceDataPublishedTvk
+	
+	if(!ValidAddress(aReg) || aLen == 0 || (aChunk->Size() < (TInt)aLen))
+		return(KErrArgument);
+		
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE0(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIORead)); // @SymTraceDataInternalTechnology
+	if (iTraceData)
+		iTraceData->Set(aChunk, aOffset, aLen);
+#endif
+	
+	SetupCIMIoReadMultiple(aReg, aLen, (TUint8*)aOffset, aAutoInc);
+	
+    SetupCIMIoChunkParams(aChunk);
+	
+	TInt err = EngageSdio();
+		
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceReadMultipleChunkReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}	
+
+EXPORT_C TInt DSDIORegisterInterface::WriteMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen)
+/**
+@publishedPartner
+@released
+
+This function writes aLen bytes starting at the specified register. 
+The destinatation address will be automatically incremented.
+
+@param aReg Destination register address
+@param aDataP Source address of data to be written
+@param aLen The number of bytes to transfer
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	return WriteMultiple8(aReg, aDataP, aLen, ETrue);
+	}			
+
+EXPORT_C TInt DSDIORegisterInterface::WriteMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen, TBool aAutoInc)
+/**
+@publishedPartner
+@released
+
+This function writes aLen bytes starting at the specified register. The optional parameter aAutoInc 
+allows auto-increment of the destination address to be disabled if, for example, writing to a FIFO on the card.
+
+@param aReg Destination register address
+@param aDataP Source address of data to be written
+@param aLen The number of bytes to transfer
+@param aAutoInc Specify ETrue to auto-increment the destination address
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG(aDataP != NULL, DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceWriteMultiple, reinterpret_cast<TUint32>(this), aLen); // @SymTraceDataPublishedTvk
+	
+	if(!ValidAddress(aReg) || aLen == 0)
+		return(KErrArgument);
+			
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIOWrite, aDataP, aLen)); // @SymTraceDataInternalTechnology
+	if (iTraceData)
+		iTraceData->Set(NULL, 0);
+#endif
+	
+	SetupCIMIoWriteMultiple(aReg, aLen, aDataP, aAutoInc);
+	TInt err = EngageSdio();
+
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceWriteMultipleReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}			
+
+EXPORT_C TInt DSDIORegisterInterface::WriteMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen)
+/**
+@publishedPartner
+@released
+
+This function writes aLen bytes starting at the specified register. 
+Transfers are performed utilising DMA, this is dependent on platform support.
+The destinatation address will be automatically incremented.
+
+@param aReg         Destination register address
+@param aChunk       Chunk which hosts the source buffer
+@param aOffset      The offset from the start of the chunk, to the start of the source buffer
+@param aLen         The number of bytes to transfer
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	return WriteMultiple8(aReg, aChunk, aOffset, aLen, ETrue);
+	}	
+
+EXPORT_C TInt DSDIORegisterInterface::WriteMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen, TBool aAutoInc)
+/**
+@publishedPartner
+@released
+
+This function writes aLen bytes starting at the specified register. The optional parameter aAutoInc 
+allows auto-increment of the destination address to be disabled if, for example, writing to a FIFO on the card.
+Transfers are performed utilising DMA, this is dependent on platform support.
+
+@param aReg         Destination register address
+@param aChunk       Chunk which hosts the source buffer
+@param aOffset      The offset from the start of the chunk, to the start of the source buffer
+@param aLen         The number of bytes to transfer
+@param aAutoInc     Specify ETrue to auto-increment the destination address
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG(aChunk != NULL, DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceWriteMultipleChunk, reinterpret_cast<TUint32>(this), aLen); // @SymTraceDataPublishedTvk
+	
+	if(!ValidAddress(aReg) || aLen == 0 || (aChunk->Size() < (TInt)aLen) )
+		return(KErrArgument);
+			
+	Lock();
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP)
+	if (iTraceData)
+		iTraceData->Set(aChunk, aOffset, aLen);
+	TraceChunk(UTraceModuleEPBusSDIO::ESDIOWrite);
+#endif
+	
+	SetupCIMIoWriteMultiple(aReg, aLen, (TUint8*)aOffset, aAutoInc);
+	
+	SetupCIMIoChunkParams(aChunk);
+	
+	TInt err = EngageSdio();
+
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceWriteMultipleChunkReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}	
+
+TInt DSDIORegisterInterface::SetBusWidth(TInt aBusWidth)
+/**
+Set the bus width
+
+@param aBusWidth    The desired bus width, usually 1 or 4
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	__ASSERT_DEBUG((aBusWidth == 1 || aBusWidth == 4), DSDIORegisterInterface::Panic(DSDIORegisterInterface::EBadParameter));
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceSetBusWidth, reinterpret_cast<TUint32>(this), aBusWidth); // @SymTraceDataPublishedTvk
+	
+	Lock();
+
+	SetupCIMIoSetBusWidth(aBusWidth);
+	TInt err = EngageSdio();
+
+	Unlock();
+
+	TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceSetBusWidthReturning, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+	
+	return err;
+	}
+
+EXPORT_C TBool DSDIORegisterInterface::SetAsync(TMMCCallBack& aCallback)
+/**
+Allows the synchronous nature of the DSDIORegInterface class to be disabled, using the specified callback 
+function to indicate completion instead of waiting on a semaphore. 
+
+Intended for use by device drivers that may be able to do useful work while waiting for completion of an 
+operation, this is similar to using the DSDIOSession class directly but provides encapsulation of the setting 
+the command arguments and submission of the session of the stack.
+
+@param aCallback Callback function used to indicate Asynchronous Completion
+
+@return ETrue if successful, otherwise EFalse.
+*/
+	{
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceSetAsync, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+
+	Lock();	// Shall remain locked for the duration of the session
+
+	iIsSync = EFalse;
+	iClientCallback = aCallback;
+
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceSetAsyncReturning, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+	
+	return(ETrue);
+	}
+
+EXPORT_C TBool DSDIORegisterInterface::SetSync()
+/**
+Allows the synchronous nature of the DSDIORegInterface class to be enabled, using an internal semaphore 
+to signal completion instead of relying on the asynchronous nature of the session.
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceSetSync, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+
+	Lock();
+	
+	iIsSync = ETrue;
+	Unlock();
+
+	TRACE1(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceSetSyncReturning, reinterpret_cast<TUint32>(this)); // @SymTraceDataPublishedTvk
+	
+	return(ETrue);
+	}
+
+void DSDIORegisterInterface::SessionEndCallBack(TAny *aSelfP)
+/**
+Session end callback
+*/
+	{
+	SYMBIAN_TRACE_SDIO_VERBOSE_ONLY(Printf(TTraceContext(EInternals), ">RegIfc:SesCB")); // @SymTraceDataInternalTechnology
+
+	DSDIORegisterInterface &self = *(DSDIORegisterInterface*)aSelfP;
+	
+	// Clear any Shared Chunk information
+	self.ClearCIMIoChunkParams();
+
+	if(self.iIsSync)
+		{
+		if (!self.iSessionEndDfc.Queued())
+			{
+			self.iSessionEndDfc.Enque();
+			}
+		}
+	else
+		{
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+		self.DumpOpComplete();
+#endif
+
+		TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceOpComplete, reinterpret_cast<TUint32>(aSelfP), 0); // @SymTraceDataPublishedTvk
+
+		self.iClientCallback.CallBack();
+		self.Unlock();
+		}
+	}
+
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+void DSDIORegisterInterface::DumpOpComplete()
+/**
+The read/write operation has completed, for a read operation output the data that has been read
+*/
+	{
+	SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE1(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIOOperationComplete, iTraceData->TickCount())); // @SymTraceDataInternalTechnology
+
+	if (iTraceData)
+		{
+		if (iTraceData->Chunk())
+			TraceChunk(UTraceModuleEPBusSDIO::ESDIOReadComplete);
+		else if (iTraceData->Ptr())
+			SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE(TTraceContext(EDump), UTraceModuleEPBusSDIO::ESDIOReadComplete, iTraceData->Ptr(), iTraceData->Length())); // @SymTraceDataInternalTechnology
+		}
+	}
+
+/**
+Dump the read/write data for a chunk
+*/
+void DSDIORegisterInterface::TraceChunk(TUint32 aTrace)
+	{
+	if (iTraceData && iTraceData->Chunk())
+		{
+		TInt r = KErrNone;
+		TLinAddr kernAddr;
+		TUint32  mapAttr;
+		TUint32  physAddr;
+
+        TUint32 pageSize = Kern::RoundToPageSize(1);
+        
+        // calculate number of possible physical pages
+        // +1 for rounding & +1 for physical page spanning 
+        TUint32 totalPages = (iTraceData->Length() / pageSize) + 2;
+        
+        // Allocate array for list of physical pages
+        TUint32* physicalPages = new TPhysAddr[totalPages];
+        if(!physicalPages)
+            {
+            return;
+            }
+
+        // Query Physical Structure of chunk
+		r = Kern::ChunkPhysicalAddress(iTraceData->Chunk(), iTraceData->Offset(), iTraceData->Length(), kernAddr, mapAttr, physAddr, physicalPages);
+	
+		if(KErrNone == r)
+			{
+			SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE(TTraceContext(EDump), aTrace, reinterpret_cast<TUint8*>(kernAddr), iTraceData->Length())); // @SymTraceDataInternalTechnology
+  			}
+#ifndef __FRAGMENTED_RAM_SUPPORT
+		else
+			{
+			// Do nothing
+			}            
+#else
+		else if(r==1)
+			{
+			TUint32 lenToOutput = pageSize - (iTraceData->Offset() % pageSize);
+			TUint8* addr = reinterpret_cast<TUint8*>(kernAddr);
+		
+			SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE(TTraceContext(EDump), aTrace, addr, lenToOutput)); // @SymTraceDataInternalTechnology
+			aLen -= lenToOutput;
+			
+			for(TUint i=1; i < totalPages; i++)
+	            {
+	            lenToOutput = aLen > pageSize ? pageSize : aLen;
+				SYMBIAN_TRACE_SDIO_DUMP_ONLY(TRACE(TTraceContext(EDump), aTrace, physicalPages[i], lenToOutput)); // @SymTraceDataInternalTechnology
+				aLen -= lenToOutput;
+	            }
+			}        
+#endif
+
+		delete [] physicalPages;	
+		}
+	}
+
+#endif
+
+void DSDIORegisterInterface::SessionEndDfc(TAny *aSelfP)
+/**
+Session end DFC
+*/
+	{
+	DSDIORegisterInterface* pSelf = static_cast<DSDIORegisterInterface*>(aSelfP);
+	pSelf->DoSessionEndDfc();
+	}
+
+void DSDIORegisterInterface::DoSessionEndDfc()
+/**
+When a session has been completed, extract any error codes
+and signal completion of the current operation
+*/
+	{
+	iSessionErr = EpocErrorCode();
+	NKern::FSSignal(&iSem);
+	}
+
+
+TInt DSDIORegisterInterface::EngageSdio()
+/**
+Performs the operation, using a semaphore to create synchronous behaviour
+
+@return KErrNone if successful, otherwise a standard Symbian OS error code.
+*/
+	{
+	TInt err = KErrNone;
+
+	SYMBIAN_TRACE_SDIO_VERBOSE_ONLY(Printf(TTraceContext(EInternals), "DSDIORegisterInterface::EngageSdio, engaging the SDIO card")); // @SymTraceDataInternalTechnology
+	
+	// Determine if there are any outstanding critical
+	// events (power down, media change etc..)
+	err = StackP()->MMCSocket()->InCritical();
+	if (err == KErrNone)
+		{
+		// Engage the session and wait on the response
+		
+		// set the current thread as the owner - need to do this
+		// before the event can be signalled (which can happen in Engage())
+		if (iIsSync)
+			{
+			// check semaphore has not been signalled already (should never happen).
+			__ASSERT_ALWAYS(iSem.iCount == 0, DSDIORegisterInterface::Panic(DSDIORegisterInterface::ESemAlreadySignalled));
+			NKern::FSSetOwner(&iSem, NULL);
+			}
+
+		err = Engage();
+		if(err == KErrNone && iIsSync)
+			{
+			NKern::FSWait(&iSem);
+			
+			err = iSessionErr;
+			
+			if(CardP()->IsPresent() == EFalse)
+				{
+				err = KErrNotFound;
+				}
+#if defined(SYMBIAN_TRACE_SDIO_DUMP) 
+			DumpOpComplete();
+#endif
+			}
+
+		if (iIsSync)
+			TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIORegisterInterfaceOpComplete, reinterpret_cast<TUint32>(this), err); // @SymTraceDataPublishedTvk
+		}
+	else
+		{
+		if(!Kern::PowerGood())
+			{
+			err = KErrAbort;
+			}
+
+		if(CardP()->IsReady() == EFalse)
+			{
+			err = KErrNotReady;
+			}
+		}
+
+	StackP()->MMCSocket()->EndInCritical();
+
+	return(err);
+	}
+
+void DSDIORegisterInterface::Lock()
+/**
+Lock the interface
+*/
+	{
+	if(iMutexLock)
+		{
+		NKern::ThreadEnterCS();
+		__ASSERT_CRITICAL
+		Kern::MutexWait(*iMutexLock);
+		}
+	}
+
+void DSDIORegisterInterface::Unlock()
+/**
+Unlock the interface
+*/
+	{
+	if(iMutexLock)
+		{
+		Kern::MutexSignal(*iMutexLock);
+		NKern::ThreadLeaveCS();
+		}
+	}
+
+void DSDIORegisterInterface::Panic(DSDIORegisterInterface::TPanic aPanic)
+/**
+Register Interface Panic
+*/
+	{
+	Kern::Fault("SDIO_REGIFC", aPanic);
+	}
+
+
+void DSDIORegisterInterface::TTraceData::Clear()
+/**
+Clear the trace data
+*/
+	{
+	iData.iPtr = NULL;
+	iLength = 0;
+	iChunk = NULL;
+	iStartTickCount = NKern::FastCounter();
+	}
+
+void DSDIORegisterInterface::TTraceData::Set(TUint8* aPtr, TUint32 aLength)
+/**
+Set the trace data for a byte buffer
+*/
+	{
+	iData.iPtr = aPtr;
+	iLength = aLength;
+	iChunk = NULL;
+	iStartTickCount = NKern::FastCounter();
+	}
+
+void DSDIORegisterInterface::TTraceData::Set(DChunk* aChunk, TUint32 aOffset, TUint32 aLength)
+/**
+Set the trace data for a DChunk buffer
+*/
+	{
+	iChunk = aChunk;
+	iData.iOffset = aOffset;
+	iLength = aLength;
+	iStartTickCount = NKern::FastCounter();
+	}
+
+DChunk*	DSDIORegisterInterface::TTraceData::Chunk() const
+/**
+Return the chunk
+*/
+	{
+	return iChunk;
+	}
+
+TUint8* DSDIORegisterInterface::TTraceData::Ptr() const
+/**
+Return the byte buffer
+*/
+	{
+	return iData.iPtr;
+	}
+
+TUint32	DSDIORegisterInterface::TTraceData::Offset() const
+/**
+Return the chunk offset
+*/
+	{
+	return iData.iOffset;
+	}
+
+TUint32 DSDIORegisterInterface::TTraceData::Length() const
+/**
+Return the data buffer length
+*/
+	{
+	return iLength;
+	}
+
+TUint32 DSDIORegisterInterface::TTraceData::TickCount() const
+/**
+Return the Tick count since the trace data was set
+*/
+	{
+	return NKern::FastCounter() - iStartTickCount;
+	}
+