--- /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;
+ }
+