kerneltest/e32test/pccd/d_mmctest.cpp
changeset 279 957c583b417b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pccd/d_mmctest.cpp	Mon Oct 04 12:03:52 2010 +0100
@@ -0,0 +1,670 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This LDD provides a set of direct interface functions with the kernel 
+// MultiMediaCard Controller
+// 
+//
+
+#include <kernel/kernel.h>
+#include <drivers/mmc.h>
+#include "d_mmctest.h"
+
+const TInt KMajorVersionNumber=1;
+const TInt KMinorVersionNumber=0;
+const TInt KBuildVersionNumber=0;
+
+const TInt KStackNumber  = 0;
+
+const TInt KMaxMMCCardsPerStack = 4;
+
+// global Dfc Que
+TDynamicDfcQue* gDfcQ;
+
+class DLddFactoryMmcCntrlInterface : public DLogicalDevice
+	{
+public:
+	DLddFactoryMmcCntrlInterface();
+	virtual ~DLddFactoryMmcCntrlInterface();
+	virtual TInt Install();
+	virtual void GetCaps(TDes8 &aDes) const;
+	virtual TInt Create(DLogicalChannelBase*& aChannel); 	//overriding pure virtual
+	};
+
+class DLddMmcCntrlInterface : public DLogicalChannel
+	{
+public:
+	DLddMmcCntrlInterface();
+	~DLddMmcCntrlInterface();
+protected:
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+	virtual void HandleMsg(class TMessageBase *);
+private:
+	void DoCancel(TInt aReqNo);
+	TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2);
+	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
+	TInt PrintCardInfo();	
+private:
+    void Reset();
+    static void SessionEndCallBack(TAny *aPtr);
+    static void SessionEndDfc(TAny *aPtr);
+	static void EventCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2);
+
+private:
+    enum TPanic {EReadDes,EWriteDes,EWriteTInt,EUnknownMmcSes};
+    enum TMmcSessionCmd {EMmcSesNone,EMmcSesReadBlk,EMmcSesWriteBlk, EMmcSesReadExtCSD};
+    TInt iStackNum;
+	DMMCSocket* iSocketP;
+    DMMCStack* iStack;
+    TMMCard* iCard;
+    DMMCSession* iSession;
+    TMmcSessionCmd iMmcSessionCmd;
+    TAny* iClientDesPtr;
+	TUint32 iBlkOffet;
+	TRequestStatus* iReadWriteStatusP;
+    TMMCCallBack iSessionEndCallBack;
+	TDfc iSessionEndDfc;
+	TPBusCallBack iBusEventCallback;
+	TRequestStatus* iPowerUpStatusP;
+//	TUint8 iBuf[KDrvBufSizeInBytes];	// iBuf now uses the MMC DMA buffer, until DT issue with H4 is resolved
+	TUint8* iBuf;
+	DThread* iClient;
+	TExtendedCSD iExtendedCSD;
+    };
+
+DECLARE_STANDARD_LDD()
+	{
+	return new DLddFactoryMmcCntrlInterface;
+	}
+
+DLddFactoryMmcCntrlInterface::DLddFactoryMmcCntrlInterface()
+//
+// Constructor
+//
+	{
+
+    iParseMask=KDeviceAllowUnit;  // Pass stack number as unit
+	iUnitsMask=0xffffffff;
+	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+	}
+
+TInt DLddFactoryMmcCntrlInterface::Create(DLogicalChannelBase*& aChannel)
+//
+// Create a new DLddFactoryMmcCntrlInterface on this logical device
+//
+	{
+	aChannel=new DLddMmcCntrlInterface;
+	return aChannel ? KErrNone : KErrNoMemory;
+	}
+
+const TInt KDMmcThreadPriority = 27;
+_LIT(KDMmcThread,"DMmcTestThread");
+
+TInt DLddFactoryMmcCntrlInterface::Install()
+//
+// Install the device driver.
+//
+	{
+	// Allocate a kernel thread to run the DFC 
+	TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDMmcThreadPriority, KDMmcThread);
+
+	if (r != KErrNone)
+		return r; 	
+
+    TPtrC name=_L("MmcTest");
+	return(SetName(&name));
+	}
+
+void DLddFactoryMmcCntrlInterface::GetCaps(TDes8 &aDes) const
+//
+// Return the Pc Card Contoller Interface ldd's capabilities.
+//
+	{
+
+    TCapsMmcIfV01 b;
+	b.version=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
+	}
+
+/**
+  Destructor
+*/
+DLddFactoryMmcCntrlInterface::~DLddFactoryMmcCntrlInterface()
+	{
+	if (gDfcQ)
+		gDfcQ->Destroy();
+	}
+
+#pragma warning( disable : 4355 )	// this used in initializer list
+DLddMmcCntrlInterface::DLddMmcCntrlInterface()
+//
+// Constructor
+//
+	: iSessionEndCallBack(DLddMmcCntrlInterface::SessionEndCallBack,this),
+	  iSessionEndDfc(DLddMmcCntrlInterface::SessionEndDfc, this, 1),
+	  iBusEventCallback(DLddMmcCntrlInterface::EventCallBack, this)
+	{
+
+//	iMmcController=NULL;
+//  iStackNum=0;
+//  iStack=NULL;
+//  iCard=NULL;
+//  iSession=NULL;
+//  iMmcSessionCmd=EMmcSesNone;
+//  iClientDesPtr=NULL;
+//	iBlkOffet=0;
+
+	iClient=&Kern::CurrentThread();
+	((DObject*)iClient)->Open();	// can't fail since thread is running
+    }
+#pragma warning( default : 4355 )
+
+DLddMmcCntrlInterface::~DLddMmcCntrlInterface()
+//
+// Destructor
+//
+	{
+
+    Reset();
+	iBusEventCallback.Remove();
+	delete iSession;
+	Kern::SafeClose((DObject*&)iClient,NULL);
+    }
+
+TInt DLddMmcCntrlInterface::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer)
+//
+// Create channel.
+//
+	{    
+	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
+		return(KErrNotSupported);
+
+	//
+	// Obtain the appropriate card from the socket/stack
+	//
+	iSocketP = static_cast<DMMCSocket*>(DPBusSocket::SocketFromId(aUnit));
+	if(iSocketP == NULL)
+		return(KErrNoMemory);
+
+	iStack = static_cast<DMMCStack*>(iSocketP->Stack(KStackNumber));
+	if(iStack == NULL)
+		return(KErrNoMemory);
+
+    // Create an MMC session object
+	iSession = iStack->AllocSession(iSessionEndCallBack);
+    if (iSession==NULL)
+		return(KErrNoMemory);
+		
+    iSession->SetStack(iStack);
+   
+	TUint8* buf;
+	TInt bufLen;
+	TInt minorBufLen;
+	iStack->BufferInfo(buf, bufLen, minorBufLen);
+	iBuf = buf;
+
+	SetDfcQ(gDfcQ);
+	iMsgQ.Receive();
+	
+	iSessionEndDfc.SetDfcQ(gDfcQ);
+
+	iBusEventCallback.SetSocket(aUnit);
+	iBusEventCallback.Add();
+
+    return(KErrNone);
+	}
+
+void DLddMmcCntrlInterface::DoCancel(TInt /*aReqNo*/)
+//
+// Cancel an outstanding request.
+//
+	{
+	}
+
+void DLddMmcCntrlInterface::HandleMsg(TMessageBase* aMsg)
+    {
+    TThreadMessage& m=*(TThreadMessage*)aMsg;
+    TInt id=m.iValue;
+    
+	if (id==(TInt)ECloseMsg)
+		{
+		m.Complete(KErrNone, EFalse);
+		return;
+		}
+    else if (id==KMaxTInt)
+		{
+		// DoCancel
+		m.Complete(KErrNone,ETrue);
+		return;
+		}
+
+    if (id<0)
+		{
+		// DoRequest
+		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
+		TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
+		if (r!=KErrNone)
+	    	Kern::RequestComplete(iClient, pS, r);
+		m.Complete(KErrNone,ETrue);
+		}
+    else
+		{
+		// DoControl
+		TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
+		if(r != KErrCompletion)
+			{
+			m.Complete(r,ETrue);
+			}
+		}
+	}
+
+TInt DLddMmcCntrlInterface::PrintCardInfo()
+    {
+    if(iCard == NULL)
+        {
+        return(KErrNotReady);
+        }
+    const TCSD& csd = iCard->CSD();
+    Kern::Printf("CSD");    
+    Kern::Printf("CSDStructure():                 %u",csd.CSDStructure());
+    Kern::Printf("SpecVers():                     %u",csd.SpecVers());
+    switch (csd.MediaType())
+        {
+        case EMultiMediaROM   : Kern::Printf("Read Only Media"); break;
+        case EMultiMediaFlash : Kern::Printf("Writable Media"); break;
+        case EMultiMediaIO    : Kern::Printf("IO Media Device"); break;
+        case EMultiMediaOther : Kern::Printf("UNKNOWN Media type"); break;
+        default : Kern::Printf("Media NOT SUPPORTED");
+        }    
+    Kern::Printf("----------------------------------");
+    Kern::Printf("Reserved120():                  %u",csd.Reserved120());
+    Kern::Printf("TAAC():                         %u", csd.TAAC());
+    Kern::Printf("NSAC():                         %u", csd.NSAC());
+    Kern::Printf("TranSpeed():                    %u", csd.TranSpeed());
+    Kern::Printf("CCC():                          %u",csd.CCC());
+    Kern::Printf("ReadBlLen():                    %u", csd.ReadBlLen());
+    Kern::Printf("ReadBlPartial():                %u", (TUint)csd.ReadBlPartial());
+    Kern::Printf("WriteBlkMisalign():             %u", (TUint) csd.WriteBlkMisalign());
+    Kern::Printf("ReadBlkMisalign():              %u", (TUint) csd.ReadBlkMisalign());
+    Kern::Printf("DSRImp():                       %u", (TUint) csd.DSRImp());
+    Kern::Printf("Reserved74():                   %u", csd.Reserved74());
+    Kern::Printf("CSize():                        %u", csd.CSize());
+    Kern::Printf("VDDRCurrMin():                  %u", csd.VDDRCurrMin());
+    Kern::Printf("VDDRCurrMax():                  %u", csd.VDDRCurrMax());
+    Kern::Printf("VDDWCurrMin():                  %u", csd.VDDWCurrMin());
+    Kern::Printf("VDDWCurrMax():                  %u", csd.VDDWCurrMax());
+    Kern::Printf("CSizeMult():                    %u", csd.CSizeMult());
+    Kern::Printf("EraseGrpSize():                 %u", csd.EraseGrpSize());
+    Kern::Printf("EraseGrpMult():                 %u", csd.EraseGrpMult());
+    Kern::Printf("WPGrpSize():                    %u", csd.WPGrpSize());
+    Kern::Printf("WPGrpEnable():                  %u", csd.WPGrpEnable());            
+    Kern::Printf("DefaultECC():                   %u", csd.DefaultECC());
+    Kern::Printf("R2WFactor():                    %u", csd.R2WFactor());
+    Kern::Printf("WriteBlLen():                   %u", csd.WriteBlLen());
+    Kern::Printf("WriteBlPartial():               %u", (TUint) csd.WriteBlPartial());
+    Kern::Printf("Reserved16():                   %u", csd.Reserved16());
+    Kern::Printf("FileFormatGrp():                %u", (TUint) csd.FileFormatGrp());
+    Kern::Printf("Copy():                         %u", (TUint) csd.Copy());
+    Kern::Printf("PermWriteProtect():             %u", (TUint) csd.PermWriteProtect());
+    Kern::Printf("TmpWriteProtect():              %u", (TUint) csd.TmpWriteProtect());
+    Kern::Printf("FileFormat():                   %u", csd.FileFormat());
+    Kern::Printf("ECC():                          %u", csd.ECC());
+    Kern::Printf("CRC():                          %u", csd.CRC());
+    Kern::Printf("DeviceSize():                   %u", csd.DeviceSize());   
+    Kern::Printf("ReadBlockLength():              %u", csd.ReadBlockLength());
+    Kern::Printf("WriteBlockLength():             %u", csd.WriteBlockLength());
+    Kern::Printf("EraseSectorSize():              %u", csd.EraseSectorSize());
+    Kern::Printf("EraseGroupSize():               %u", csd.EraseGroupSize());
+    Kern::Printf("MinReadCurrentInMilliamps():    %u", csd.MinReadCurrentInMilliamps());
+    Kern::Printf("MinWriteCurrentInMilliamps():   %u", csd.MinWriteCurrentInMilliamps());
+    Kern::Printf("MaxReadCurrentInMilliamps():    %u", csd.MaxReadCurrentInMilliamps());
+    Kern::Printf("MaxWriteCurrentInMilliamps():   %u", csd.MaxWriteCurrentInMilliamps());
+    Kern::Printf("MaxTranSpeedInKilohertz():      %u", csd.MaxTranSpeedInKilohertz());
+    
+    const TExtendedCSD& extcsd = iCard->iExtendedCSD;
+    Kern::Printf("\nExtended CSD");
+    Kern::Printf("CSDStructureVer:                %u", extcsd.CSDStructureVer());
+    Kern::Printf("ExtendedCSDRev:                 %u", extcsd.ExtendedCSDRev());
+    Kern::Printf("----------------------------------");
+    Kern::Printf("SupportedCmdSet:                %u", extcsd.SupportedCmdSet());
+    Kern::Printf("SectorCount:                    %u", extcsd.SectorCount());
+    Kern::Printf("MinPerfWrite8Bit52Mhz:          %u", extcsd.MinPerfWrite8Bit52Mhz());
+    Kern::Printf("MinPerfRead8Bit52Mhz:           %u", extcsd.MinPerfRead8Bit52Mhz());
+    Kern::Printf("MinPerfRead8Bit26Mhz_4Bit52Mhz: %u", extcsd.MinPerfRead8Bit26Mhz_4Bit52Mhz());
+    Kern::Printf("MinPerfWrite4Bit26Mhz:          %u", extcsd.MinPerfWrite4Bit26Mhz());
+    Kern::Printf("MinPerfRead4Bit26Mhz:           %u", extcsd.MinPerfRead4Bit26Mhz());
+    Kern::Printf("PowerClass26Mhz360V:            0x%02X", extcsd.PowerClass26Mhz360V());
+    Kern::Printf("PowerClass52Mhz360V:            0x%02X", extcsd.PowerClass52Mhz360V());
+    Kern::Printf("PowerClass26Mhz195V:            0x%02X", extcsd.PowerClass26Mhz195V());
+    Kern::Printf("PowerClass52Mhz195V:            0x%02X", extcsd.PowerClass52Mhz195V());
+    Kern::Printf("CardType:                       %u", extcsd.CardType());
+    Kern::Printf("CmdSet:                         %u", extcsd.CmdSet());
+    Kern::Printf("CmdSetRev:                      %u", extcsd.CmdSetRev());
+    Kern::Printf("PowerClass:                     %u", extcsd.PowerClass());
+    Kern::Printf("HighSpeedTiming:                %u", extcsd.HighSpeedTiming());
+    Kern::Printf("BusWidthMode:                   %u", extcsd.BusWidthMode());
+    Kern::Printf("HighCapacityEraseGroupSize:     %u", extcsd.HighCapacityEraseGroupSize());
+    Kern::Printf("AccessSize:                     %u", extcsd.AccessSize());
+    Kern::Printf("BootInfo:                       %u", extcsd.BootInfo() );
+    Kern::Printf("BootSizeMultiple:               %u", extcsd.BootSizeMultiple() );
+    Kern::Printf("EraseTimeoutMultiple:           %u", extcsd.EraseTimeoutMultiple() );
+    Kern::Printf("ReliableWriteSector:            %u", extcsd.ReliableWriteSector() );
+    Kern::Printf("HighCapWriteProtGroupSize:      %u", extcsd.HighCapacityWriteProtectGroupSize() );
+    Kern::Printf("SleepCurrentVcc:                %u", extcsd.SleepCurrentVcc() );
+    Kern::Printf("SleepCurrentVccQ:               %u", extcsd.SleepCurrentVccQ());
+    Kern::Printf("SleepAwakeTimeout:              %u", extcsd.SleepAwakeTimeout());
+    Kern::Printf("BootConfig:                     %u", extcsd.BootConfig());
+    Kern::Printf("BootBusWidth:                   %u", extcsd.BootBusWidth());
+    Kern::Printf("EraseGroupDef:                  %u", extcsd.EraseGroupDef());
+    
+    return KErrNone;
+    }
+
+TInt DLddMmcCntrlInterface::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2)
+//
+// Most Async requests
+//
+	{
+
+    if (iMmcSessionCmd!=EMmcSesNone)
+		{
+		return(KErrInUse);
+		}
+
+    switch (aFunction)
+		{
+        case RMmcCntrlIf::EReqPwrUp:
+			{
+			if(!iSocketP->CardIsPresent())
+				{
+				Kern::RequestComplete(iClient, aStatus, KErrNotReady);
+				}
+			else if(iSocketP->State() == EPBusOn)
+				{
+				Kern::RequestComplete(iClient, aStatus, KErrNone);
+				}
+			else
+				{
+				iPowerUpStatusP = aStatus;
+				iSocketP->PowerUp();
+				}
+			break;
+			}
+        case RMmcCntrlIf::EReqReadSect:
+            {
+			if(iCard == NULL)
+				{
+				return(KErrNotReady);
+				}
+
+			//TCSD csd=iCard->CSD();
+			iReadWriteStatusP = aStatus;
+			TUint32 srcAddr=((TUint32)a1)<<KSectorSizeShift;
+			TUint readBlLen = 1 << iCard->MaxReadBlLen();
+			TUint readBlMask=(readBlLen-1);
+			iBlkOffet=srcAddr-(srcAddr&(~readBlMask));
+			iClientDesPtr=a2;
+			iMmcSessionCmd=EMmcSesReadBlk;
+			srcAddr&=(~readBlMask);
+			TMMCArgument da(srcAddr);
+			iSession->SetupCIMReadBlock(da,readBlLen,&iBuf[0]);
+			iSession->Engage();
+			break;
+            }
+        case RMmcCntrlIf::EReqWriteSect:
+            {
+			if(iCard == NULL)
+				{
+				return(KErrNotReady);
+				}
+
+			iReadWriteStatusP = aStatus;
+			TUint32 destAddr=((TUint32)a1)<<KSectorSizeShift;
+			TUint writeBlLen=1 << iCard->MaxWriteBlLen();
+			TUint writeBlMask=(writeBlLen-1);
+			iBlkOffet=destAddr-(destAddr&(~writeBlMask));
+			TPtr8* srcDes = (TPtr8*)a2;		
+			TPtr8 ptr(&iBuf[iBlkOffet],KSectorSizeInBytes,KSectorSizeInBytes);
+			TInt r = Kern::ThreadDesRead(iClient, srcDes, ptr, 0, KChunkShiftBy0);
+			if(r != KErrNone)
+				{
+				return(r);
+				}
+				
+			iMmcSessionCmd=EMmcSesWriteBlk;
+			destAddr&=(~writeBlMask);
+			iSession->SetupCIMWriteBlock(TMMCArgument(destAddr),writeBlLen,&iBuf[0]);
+			iSession->Engage();
+			break;
+			}
+
+        case RMmcCntrlIf::EReqReadExtCSD:
+            {
+			if(iCard == NULL)
+				{
+				return(KErrNotReady);
+				}
+
+			iClientDesPtr = a1;
+			iReadWriteStatusP = aStatus;
+			iMmcSessionCmd = EMmcSesReadExtCSD;
+
+			iSession->SetupDTCommand(
+				ECmdSendExtendedCSD, 
+				TMMCArgument(0),
+				KMMCExtendedCSDLength,
+				(TUint8*) &iExtendedCSD);
+
+			iSession->Engage();
+			break;
+            }
+            
+        case RMmcCntrlIf::EReqMMCInfoPrint:
+            {
+            // Print CSD & Extended CSD values
+            TInt r = PrintCardInfo();            
+            Kern::RequestComplete(iClient, aStatus, r);
+            break;
+            }
+
+        }
+	return(KErrNone);
+	}
+
+TInt DLddMmcCntrlInterface::DoControl(TInt aFunction,TAny* a1,TAny* /*a2*/)
+//
+// Mostly requests (but some kernel server async ones)
+//
+	{
+
+	TInt r=KErrNotSupported;
+	switch (aFunction)
+		{
+        case RMmcCntrlIf::ESvReset:
+            {
+            Reset();
+			r=KErrNone;
+			break;
+            }
+        case RMmcCntrlIf::ESvPwrDown:
+			{
+//		    iStack->PowerDown(); ???
+//          iMmcController->SetPowerEvent(0,EPEventPwrDownNormal,0);
+			r=KErrNone;
+			break;
+			}
+        case RMmcCntrlIf::EExecStackInfo:
+            {
+            // Determine the number of cards present
+            TUint cardsPresentMask=0x00000000;
+	        TMMCard* card;
+            for (TInt i=0;i<KMaxMMCCardsPerStack;i++)
+                {
+                card=iStack->CardP(i);
+                if (card!=NULL && card->IsPresent())
+                    cardsPresentMask|=(0x1<<i);
+                }
+			r = Kern::ThreadRawWrite(iClient,a1,&cardsPresentMask,sizeof(TUint));
+			break;
+            }
+        case RMmcCntrlIf::ESvRegisterEvent:
+            {
+			return(KErrNotSupported);
+            }
+        case RMmcCntrlIf::EExecSelectCard:
+            {
+            iCard=iStack->CardP((TUint)a1);
+            iSession->SetCard(iCard);
+			r=KErrNone;
+			break;
+            }
+        case RMmcCntrlIf::EExecCardInfo:
+            {
+            if (iCard)
+                {
+				TMmcCardInfo ci;
+	            ci.iIsReady=iCard->IsPresent();
+	            ci.iIsLocked=iCard->IsLocked();
+				TCID* cid=(TCID*)&(iCard->CID());
+				TInt i;
+				for (i=0;i<16;i++)
+					ci.iCID[i]=cid->At(i);
+				const TCSD& csd = iCard->CSD();
+				for (i=0;i<16;i++)
+					ci.iCSD[i]=csd.At(i);
+	            ci.iRCA=TUint16(iCard->RCA());
+	            ci.iMediaType=(TMmcMediaType)iCard->MediaType();
+                ci.iCardSizeInBytes=iCard->DeviceSize64();
+	            ci.iReadBlLen=csd.ReadBlockLength();
+	            ci.iWriteBlLen=csd.WriteBlockLength();
+	            ci.iReadBlPartial=csd.ReadBlPartial();
+	            ci.iWriteBlPartial=csd.WriteBlPartial();
+	            ci.iReadBlkMisalign=csd.ReadBlkMisalign();
+	            ci.iWriteBlkMisalign=csd.WriteBlkMisalign();
+                ci.iReadCurrentInMilliAmps=csd.MaxReadCurrentInMilliamps();
+                ci.iWriteCurrentInMilliAmps=csd.MaxWriteCurrentInMilliamps();
+	            ci.iSpecVers=csd.SpecVers();
+	            ci.iTAAC=csd.TAAC();
+	            ci.iNSAC=csd.NSAC();
+	            ci.iTransferSpeed=csd.TranSpeed();
+	            ci.iCommandRegister=csd.CCC();
+	            ci.iHighCapacity = iCard->IsHighCapacity();
+				r = Kern::ThreadRawWrite(iClient, a1/*TAny *aDest*/, &ci/*const TAny *aSrc*/, sizeof(TMmcCardInfo));
+                }
+            else
+                r=KErrGeneral;
+			break;
+            }
+		}
+	return(r);
+	}
+
+void DLddMmcCntrlInterface::Reset()
+//
+// Release any resources 
+//
+	{
+	iSessionEndDfc.Cancel();
+    }
+
+void DLddMmcCntrlInterface::SessionEndCallBack(TAny *aPtr)
+//
+// Session end callback
+//
+	{
+	DLddMmcCntrlInterface &mci=*(DLddMmcCntrlInterface*)aPtr;
+
+	// Signal request complete using DFC 
+	if (!mci.iSessionEndDfc.Queued())
+		mci.iSessionEndDfc.Enque();
+	}
+
+void DLddMmcCntrlInterface::SessionEndDfc(TAny *aPtr)
+//
+// Session end dfc
+//
+	{
+	DLddMmcCntrlInterface &mci=*(DLddMmcCntrlInterface*)aPtr;
+    TInt err=mci.iSession->EpocErrorCode();
+    switch (mci.iMmcSessionCmd)
+		{
+        case EMmcSesReadBlk:
+            {
+			TPtr8 ptr(&mci.iBuf[mci.iBlkOffet],KSectorSizeInBytes,KSectorSizeInBytes);
+			TPtrC8* srcDes = (TPtrC8*)mci.iClientDesPtr;
+			TInt r = Kern::ThreadDesWrite(mci.iClient,srcDes,ptr,0,mci.iClient);
+
+	    	Kern::RequestComplete(mci.iClient, mci.iReadWriteStatusP, (r == KErrNone) ? err : r);
+            break;
+            }
+        case EMmcSesWriteBlk:
+			{
+			Kern::Printf("EMmcSesWriteBlk Complete");
+	    	Kern::RequestComplete(mci.iClient, mci.iReadWriteStatusP, err);
+            break;
+			}
+		case EMmcSesReadExtCSD:
+			{
+			TPtr8 ptr((TUint8*) &mci.iExtendedCSD, KMMCExtendedCSDLength, KMMCExtendedCSDLength);
+			TPtrC8* dstDes = (TPtrC8*)mci.iClientDesPtr;
+			TInt r = Kern::ThreadDesWrite(mci.iClient, dstDes, ptr, 0,mci.iClient);
+
+	    	Kern::RequestComplete(mci.iClient, mci.iReadWriteStatusP, (r == KErrNone) ? err : r);
+			break;
+			}
+        default:
+        	break;
+		}
+	mci.iMmcSessionCmd=EMmcSesNone;
+	}
+
+void DLddMmcCntrlInterface::EventCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2)
+	{
+	DLddMmcCntrlInterface &mci=*(DLddMmcCntrlInterface*)aPtr;
+
+	if(mci.iPowerUpStatusP)
+		{
+		TInt retCode = KErrCompletion;
+
+		switch(aReason)
+			{
+			case TPBusCallBack::EPBusStateChange:
+				{
+				TPBusState newState = (TPBusState)(TInt)a1;
+				TInt errorCode = (TInt)a2;
+
+				switch(newState)
+					{
+					case EPBusCardAbsent:	retCode = KErrNotFound;		break;			
+					case EPBusOff:			retCode = errorCode;		break;
+					case EPBusPsuFault:		retCode = KErrBadPower;		break;
+					case EPBusOn:			retCode = KErrNone;			break;
+					case EPBusPowerUpPending:
+					case EPBusPoweringUp:
+					default:	
+						break;
+					}
+
+				break;
+				}
+			}
+
+		if(retCode != KErrCompletion)
+			{
+   			Kern::RequestComplete(mci.iClient, mci.iPowerUpStatusP, retCode);
+			mci.iPowerUpStatusP = NULL;
+			}
+		}
+	}
+
+