diff -r 000000000000 -r cec860690d41 haitest/bspsvs/suite/bsp/mmc/ldd/src/d_mmcsdif.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/haitest/bspsvs/suite/bsp/mmc/ldd/src/d_mmcsdif.cpp Tue Feb 02 01:39:10 2010 +0200 @@ -0,0 +1,703 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include +#include + +#include "mmcldd.h" +#include "d_mmcsdif.h" + + + +const TInt KMajorVersionNumber=1; +const TInt KMinorVersionNumber=0; +const TInt KBuildVersionNumber=0; + +// global Dfc Que +TDynamicDfcQue* gDfcQ; + + + +DECLARE_STANDARD_LDD() + { + return new DLddFactoryMmcCntrlInterface; + } + +/** + * DLddFactoryMmcCntrlInterface constructor + * + * @return N/A + * + * @leave N/A + */ +DLddFactoryMmcCntrlInterface::DLddFactoryMmcCntrlInterface() + { + iParseMask=KDeviceAllowUnit; // Pass stack number as unit + iUnitsMask=0xffffffff; + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +/** + * Create logical channel + * + * @param DLogicalChannelBase*& aChannel - logical channel + * + * @return TInt the error code + * + * @leave N/A + */ +TInt DLddFactoryMmcCntrlInterface::Create(DLogicalChannelBase*& aChannel) + { + aChannel = new DLddMmcCntrlInterface; + return aChannel ? KErrNone : KErrNoMemory; + } + +const TInt KDMmcThreadPriority = 27; +_LIT(KDMmcThread,"DMMCSDThread"); + + +/** + * Install driver + * + * @return TInt the error code + * + * @leave N/A + */ +TInt DLddFactoryMmcCntrlInterface::Install() + { + // Allocate a kernel thread to run the DFC + TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDMmcThreadPriority, KDMmcThread); + + if (r != KErrNone) + return r; + __KTRACE_OPT(KHARDWARE,MMCSDLOG("installing driver name from factory")); + return SetName(&KLddName); + } + +/** + * Get the Pc Card Contoller Interface ldd's version info + * + * @param TDes8 &aDes - Buffer to contain version info + * + * @return N/A + * + * @leave N/A + */ +void DLddFactoryMmcCntrlInterface::GetCaps(TDes8 &aDes) const + { + TCapsMmcIfV01 b; + b.version=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + aDes.FillZ(aDes.MaxLength()); + aDes.Copy((TUint8 *)&b,Min(aDes.MaxLength(),sizeof(b))); + } + +/** + * Destructor + * + * @return N/A + * + * @leave N/A + */ +DLddFactoryMmcCntrlInterface::~DLddFactoryMmcCntrlInterface() + { + if (gDfcQ) + gDfcQ->Destroy(); + } + +/** + * DLddMmcCntrlInterface constructor + * + * @return N/A + * + * @leave N/A + */ +DLddMmcCntrlInterface::DLddMmcCntrlInterface() + { + iClient = &Kern::CurrentThread(); + ((DObject*)iClient)->Open(); // can't fail since thread is running + } + +/** + * Destructor + * + * @return N/A + * + * @leave N/A + */ +DLddMmcCntrlInterface::~DLddMmcCntrlInterface() + { + Kern::SafeClose((DObject*&)iClient,NULL); + iAsyncList.ResetAndDestroy(); + } + +/** + * Create driver ojects + * + * @param TInt aUnit - Socket ID + * @param const TDesC8* aInfo - Buffer for logging + * @param const TVersion& aVer - Current version + * + * @return TInt the error code + * + * @leave N/A + */ +TInt DLddMmcCntrlInterface::DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) + return(KErrNotSupported); + + MMCSDLOG2("DLddMmcCntrlInterface::DoCreate called aInfo(%S)", aInfo); + + // create the socket - there is only a DMMCSocket + iSocket = static_cast(DPBusSocket::SocketFromId(aUnit)); + if(!iSocket) + return(KErrNoMemory); + + //Obtain the appropriate card from the stack + iStack = static_cast(iSocket->Stack(KStackNo)); + if(iStack == NULL) + return(KErrNoMemory); + + //Obtain the appropriate card power supply + iPsu=static_cast(iSocket->iVcc); + if (iPsu==NULL) + return(KErrNoMemory); + + //Obtain the appropriate card Media change + iMediaChange=static_cast(iSocket->iMediaChange); + if (iMediaChange==NULL) + return(KErrNoMemory); + + SetDfcQ(gDfcQ); + iMsgQ.Receive(); + + iUnit = aUnit; // save the unit - needed for regitering callbacks for subsequent bus events + + return(KErrNone); + } + +/** + * Request cancelled callback + * + * @param TInt sReqNo - Request Number + * + * @return N/A + * + * @leave N/A + */ +void DLddMmcCntrlInterface::DoCancel(TInt /*aReqNo*/) + { + } + +/** + * Handle kernel side message + * + * @param TMessageBase* aMsg - The kernel side message + * + * @return N/A + * + * @leave N/A + */ +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); + } + } + } + +/** + * Do a kernel side request + * + * @param TInt aFunction - Request Function ID + * @param TRequestStatus* aStatus - Request Status + * @param TAny* a1 - Given parameter + * @param TAny* a2 - Given parameter + * + * @return TInt the error code + * + * @leave N/A + */ +TInt DLddMmcCntrlInterface::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny *a2) + { + + TTCFunctionId fid = TTCFunctionId(aFunction); + switch(fid.TestType()) + { + case EMmcTestSocket: + return SocketDoRequest(aStatus, a1, a2, aFunction); + + case EMmcTestStack: + case EMmcTestPsu: + case EMmcTestMediaChange: + case EMmcGeneralTest: + default: + break; + }; + + switch(fid.FunctionId()) + { + case RMMCSDTestControllerInterface::EReadSector: + { + // read sector a1 is block number, a2 is client descriptor + // data will be written back to upon completion + MMCSDLOG3("RMMCSDTestControllerInterface::EReadSector a1(%d) a2(%x)", (TUint32)a1, a2); + if(!iCard) + { + MMCSDLOG("RMMCSDTestControllerInterface::EReadSector NULL card\n"); + return KErrNotReady; + } + + DMmcSessionAsyncRequest* request = CreateAsyncSessionRequest(EMmcSesReadBlk, aStatus); + + TUint32 srcAddr=((TUint32)a1)<MaxReadBlLen(); + TUint readBlMask=(readBlLen-1); + request->iBlkOffet=srcAddr-(srcAddr&(~readBlMask)); + request->iClientDesPtr = a2; + srcAddr &= (~readBlMask); + + MMCSDLOG("RMMCSDTestControllerInterface::EReadSector #2"); + TMMCArgument da(srcAddr); + + request->Session().SetupCIMReadBlock(da,readBlLen,&(request->iBuf[0])); + request->Session().Engage(); + + MMCSDLOG("RMMCSDTestControllerInterface::EReadSector #3"); + break; + } + case RMMCSDTestControllerInterface::EWriteSector: + { + MMCSDLOG3("RMMCSDTestControllerInterface::EWriteSector a1(%d) a2(%x) #1", (TUint32)a1, a2); + if(!iCard) + { + MMCSDLOG("RMMCSDTestControllerInterface::EWriteSector NULL card\n"); + return KErrNotReady; + } + + TUint32 destAddr=((TUint32)a1)<MaxWriteBlLen(); + + DMmcSessionAsyncRequest* request = CreateAsyncSessionRequest(EMmcSesWriteBlk, aStatus); + + TUint writeBlMask=(writeBlLen-1); + request->iBlkOffet=destAddr-(destAddr&(~writeBlMask)); + TPtr8* srcDes = (TPtr8*)a2; + TPtr8 ptr(&(request->iBuf[request->iBlkOffet]),KSectorSizeInBytes,KSectorSizeInBytes); + TInt r = Kern::ThreadDesRead(iClient, srcDes, ptr, 0, KChunkShiftBy0); + if(r != KErrNone) + { + return(r); + } + + destAddr&=(~writeBlMask); + request->Session().SetupCIMWriteBlock(TMMCArgument(destAddr),writeBlLen,&(request->iBuf[0])); + request->Session().Engage(); + + MMCSDLOG("RMMCSDTestControllerInterface::EWriteSector #4"); + break; + } + } + return(KErrNone); + } + +/** + * Do a kernel side control + * + * @param TInt aFunction - Request Function ID + * @param TAny* a1 - Given parameter + * @param TAny* a2 - Given parameter + * + * @return TInt the error code + * + * @leave N/A + */ +TInt DLddMmcCntrlInterface::DoControl(TInt aFunction,TAny* a1,TAny* a2) + { + TInt r = KErrNotSupported; + TTCFunctionId fid = TTCFunctionId(aFunction); + MMCSDLOG4("DLddMmcCntrlInterface::DoControl aFunction(%d) \ + fid.FunctionId()(%d) fid.TestType(%d)" + , aFunction, fid.FunctionId(), fid.TestType()); + + switch(fid.TestType()) + { + case EMmcTestStack: + return StackDoControl(aFunction, a1, a2); + case EMmcTestSocket: + return SocketDoControl(aFunction, a1, a2); + case EMmcTestPsu: + return PsuDoControl(aFunction, a1, a2); + case EMmcTestMediaChange: + return MediaChangeDoControl(aFunction, a1, a2); + case EMmcGeneralTest: + default: + break; + }; + + switch (fid.FunctionId()) + { + case RMMCSDTestControllerInterface::EReadCSD: + { + iCSD = iCard->CSD(); + { + TCSDInfo csdInfo(iCSD); + r = Kern::ThreadRawWrite(iClient, a1, &csdInfo, sizeof(csdInfo)); + } + } + break; + + case RMMCSDTestControllerInterface::EReadExtCSD: + { + iExtendedCSD = iCard->ExtendedCSD(); + TExtendedCSDInfo extendedCSDInfo(iExtendedCSD); + r = Kern::ThreadRawWrite(iClient, a1, &extendedCSDInfo, sizeof(extendedCSDInfo)); + } + break; + + case RMMCSDTestControllerInterface::ECardInfo: + { + TMMCCardInfo cardInfo; + cardInfo.SetCardInfo(*iCard); + r = Kern::ThreadRawWrite(iClient, a1, &cardInfo, sizeof(cardInfo)); + } + break; + + case RMMCSDTestControllerInterface::ECard: + { + r = Kern::ThreadRawWrite(iClient, a1, &iCard, sizeof(iCard)); + } + break; + + case RMMCSDTestControllerInterface::ECardIsPresent: + { + TBool isPresent = iCard->IsPresent(); + r = Kern::ThreadRawWrite(iClient, a1, &isPresent, sizeof(isPresent)); + } + break; + + case RMMCSDTestControllerInterface::ECardIsReady: + { + TBool isReady = iCard->IsReady(); + r = Kern::ThreadRawWrite(iClient, a1, &isReady, sizeof(isReady)); + } + break; + + case RMMCSDTestControllerInterface::ECardIsLocked: + { + TBool isLocked = iCard->IsLocked(); + r = Kern::ThreadRawWrite(iClient, a1, &isLocked, sizeof(isLocked)); + } + break; + + default: + { + MMCSDLOG2("DLddMmcCntrlInterface::DoControl - Invalid FunctionId()(%d)", fid.FunctionId()); + } + break; + } + + + return (r); + } + +/** + * Check if a request status exists + * + * @param TRequestStatus* aStatus - Request Status + * + * @return TBool A request status exists + * + * @leave N/A + */ +TBool DLddMmcCntrlInterface::RequestStatusExists(TRequestStatus* aStatus) + { + + // check whether this request status already exists in the async request list + for(int i=0;iStatus(%x)", i, iAsyncList[i]->Status()); + + if(iAsyncList[i]->Status() == aStatus) + { + MMCSDLOG3("WaRNING - adding duplicate TRequestStatus index[%d] aStatus(%x)", i, aStatus); + return ETrue; + } + } + + return EFalse; + } + +/** + * Create Asynchronous Session Request + * + * @param TMmcAsyncCmd aFunctionId - Request Function ID + * @param TRequestStatus* aStatus - Request Status + * + * @return DMmcSessionAsyncRequest* Poniter to the created session request object + * + * @leave N/A + */ +DMmcSessionAsyncRequest* DLddMmcCntrlInterface::CreateAsyncSessionRequest(TMmcAsyncCmd aFunctionId, TRequestStatus* aStatus) + { + + MMCSDLOG3("DLddMmcCntrlInterface::CreateAsyncRequest aStatus(%x) num requests in list (%d)", + aStatus, iAsyncList.Count()); + + // create an async request & append to async request list + DMmcSessionAsyncRequest* request = new DMmcSessionAsyncRequest(aFunctionId, aStatus, *this, gDfcQ, *iStack, *iCard); + iAsyncList.Append(request); + MMCSDLOG4("DLddMmcCntrlInterface::CreateAsyncSessionRequest created OK Status(%x) functionID(%d) aFunctionId(%d)", + request->Status(), request->FunctionId(), aFunctionId); + return request; + } + +/** + * Create Asynchronous Bus Event Request + * + * @param TMmcAsyncCmd aFunctionId - Request Function ID + * @param TRequestStatus* aStatus - Request Status + * @param TInt aUnit - Socket ID + * + * @return DBusEventRequest* Poniter to the created bus event request object + * + * @leave N/A + */ +DBusEventRequest* DLddMmcCntrlInterface::CreateAsyncBusEventRequest(TMmcAsyncCmd aFunctionId, TRequestStatus* aStatus, TInt aUnit) + { + MMCSDLOG3("DLddMmcCntrlInterface::CreateAsyncBusEventRequest aStatus(%x) num requests in list (%d)", + aStatus, iAsyncList.Count()); + + MMCSDLOG4("gDfcQ(%x), iStack(%x), iCard(%x)", gDfcQ, iStack, iCard); + + // create an async request & append toS async request list + DBusEventRequest* request = new DBusEventRequest(aFunctionId, aStatus, *this, aUnit, gDfcQ, *iStack, *iCard); + iAsyncList.Append(request); + MMCSDLOG4("DLddMmcCntrlInterface::CreateAsyncBusEventRequest created OK Status(%x) functionID(%d) aFunctionId(%d)", + request->Status(), request->FunctionId(), aFunctionId); + return request; + + } + +/** + * Clears an asynchronous Request from list + * + * @param DLddAsyncRequest* aRequest - Pointer to the request + * + * @return N/A + * + * @leave N/A + */ +void DLddMmcCntrlInterface::ClearRequest(DLddAsyncRequest* aRequest) + { + if(!aRequest) + { + MMCSDLOG("ERROR IN DLddMmcCntrlInterface::ClearRequest NULL request"); + return; + } + + TInt i = iAsyncList.Find(aRequest); + if(i >= 0) + { + iAsyncList.Remove(i); + } + else + { + MMCSDLOG2("ERROR IN DLddMmcCntrlInterface::ClearRequest err(%d)", i); + } + + delete aRequest; + + } + +/** + * Callback when request has completed + * + * @param DLddAsyncRequest& aRequest - The completed request + * + * @return N/A + * + * @leave N/A + */ +void DLddMmcCntrlInterface::Notify(DLddAsyncRequest& aRequest) // callback from DLddAsyncRequest + { + MMCSDLOG("DLddMmcCntrlInterface::Notify called"); + TRequestStatus* status = aRequest.Status(); + switch (aRequest.FunctionId()) + { + case DLddMmcCntrlInterface::EMmcSesReadBlk: + { + DMmcSessionAsyncRequest& request = (DMmcSessionAsyncRequest&) aRequest; + MMCSDLOG("DLddMmcCntrlInterface::ReadBlockComplete"); + TInt r = KErrNone; + if (request.iClientDesPtr) // have we supplied descriptor to hold returned data + { + TPtr8 ptr(&(request.iBuf[request.iBlkOffet]), KSectorSizeInBytes, KSectorSizeInBytes); + TPtrC8* srcDes = (TPtrC8*)request.iClientDesPtr; + r = Kern::ThreadDesWrite(iClient, srcDes, ptr, 0, iClient); + if(r != KErrNone) + { + MMCSDLOG2("ERROR DLddMmcCntrlInterface::ReadBlockComplete Kern::ThreadDesWrite returned r(%d)", r); + } + } + else + { + MMCSDLOG("ERROR DLddMmcCntrlInterface::ReadExtCSDComplete - No pointer provided to hold returned data"); + Kern::PanicCurrentThread(_L("PBUS-MMC"), 0); + } + Kern::RequestComplete(iClient, status, (r == KErrNone) ? aRequest.Error() : r); + } + break; + + case DLddMmcCntrlInterface::EMmcSesWriteBlk: + { + MMCSDLOG("DLddMmcCntrlInterface::WriteBlockComplete)"); + TRequestStatus* status = aRequest.Status(); + Kern::RequestComplete(iClient, status, aRequest.Error()); + } + break; + + case DLddMmcCntrlInterface::EMmcSesReadCSD: + { + DMmcSessionAsyncRequest& request = (DMmcSessionAsyncRequest&) aRequest; + MMCSDLOG("DLddMmcCntrlInterface::ReadCSDComplete"); + TInt r = KErrNone; + if (request.iClientDesPtr) // have we supplied pointer to hold returned data + { + { + TCSDInfo csdInfo(iCSD); + r = Kern::ThreadRawWrite(iClient, request.iClientDesPtr, &csdInfo, sizeof(csdInfo)); + } + if(r != KErrNone) + { + MMCSDLOG2("ERROR DLddMmcCntrlInterface::ReadCSDComplete Kern::ThreadRawWrite returned r(%d)", r); + } + } + else + { + MMCSDLOG("ERROR DLddMmcCntrlInterface::ReadExtCSDComplete - No pointer provided to hold returned data"); + Kern::PanicCurrentThread(_L("PBUS-MMC"), 0); + } + Kern::RequestComplete(iClient, status, (r == KErrNone) ? aRequest.Error() : r); + } + break; + + case DLddMmcCntrlInterface::EMmcSesReadExtCSD: + { + DMmcSessionAsyncRequest& request = (DMmcSessionAsyncRequest&) aRequest; + MMCSDLOG("DLddMmcCntrlInterface::ReadExtCSDComplete"); + TInt r = KErrNone; + if (request.iClientDesPtr) // have we supplied pointer to hold returned data + { + TExtendedCSDInfo extendedCSDInfo(iExtendedCSD); + r = Kern::ThreadRawWrite(iClient, request.iClientDesPtr, &extendedCSDInfo, sizeof(extendedCSDInfo)); + if(r != KErrNone) + { + MMCSDLOG2("ERROR DLddMmcCntrlInterface::ReadExtCSDComplete Kern::ThreadRawWrite returned r(%d)", r); + } + } + else + { + MMCSDLOG("ERROR DLddMmcCntrlInterface::ReadExtCSDComplete - No pointer provided to hold returned data"); + Kern::PanicCurrentThread(_L("PBUS-MMC"), 0); + } + Kern::RequestComplete(iClient, status, (r == KErrNone) ? aRequest.Error() : r); + } + break; + + case DLddMmcCntrlInterface::EMMcSocketPowerUp: + { + DBusEventRequest& request = (DBusEventRequest&) aRequest; + TInt retCode = KErrNone; + + MMCSDLOG2("DLddMmcCntrlInterface::EMMcSocketPowerUp ret code = %d", aRequest.Error()); + MMCSDLOG2("DLddMmcCntrlInterface::EMMcSocketPowerUp request.BusState() = %d", request.BusState()); + MMCSDLOG2("DLddMmcCntrlInterface::EMMcSocketPowerUp request.BusError() = %d", request.BusError()); + + switch(aRequest.Error()) + { + case TPBusCallBack::EPBusStateChange: + { + TPBusState newState = request.BusState(); + retCode = request.BusError(); + + if (retCode == KErrNone) + { + switch(newState) + { + case EPBusCardAbsent: retCode = KErrNotFound; break; + case EPBusPsuFault: retCode = KErrBadPower; break; + case EPBusOff: + case EPBusOn: + case EPBusPowerUpPending: + case EPBusPoweringUp: + default: + break; + } + } + + break; + } + } + + Kern::RequestComplete(iClient, status, retCode); + } + break; + + default: + MMCSDLOG("#######################################################################"); + MMCSDLOG("## UNHANDLED END DFC DLddAsyncRequest DLddMmcCntrlInterface::Notify ##"); + MMCSDLOG2("## aRequest.FunctionId(%d) ##", aRequest.FunctionId()); + MMCSDLOG("#######################################################################"); + Kern::PanicCurrentThread(_L("PBUS-MMC"), 0); + break; + }; + + ClearRequest(&aRequest); + + } +