diff -r 2b433474f2ba -r 957c583b417b kerneltest/e32test/pccd/d_mmctest.cpp --- /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 +#include +#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(DPBusSocket::SocketFromId(aUnit)); + if(iSocketP == NULL) + return(KErrNoMemory); + + iStack = static_cast(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)<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)<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;iCardP(i); + if (card!=NULL && card->IsPresent()) + cardsPresentMask|=(0x1<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; + } + } + } + +