diff -r 000000000000 -r 96e5fb8b040d kernel/eka/drivers/pbus/mmc/mmccd_init.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/drivers/pbus/mmc/mmccd_init.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,314 @@ +// Copyright (c) 1995-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: +// e32\drivers\pbus\mmc\mmccd_init.cpp +// +// + +#include +#include + + + + +/** +Starts the sequence of operations that creates the platform specific objects, +registers the socket, and initialises the stack. + +The function is called in the Variant DLL's entry point code, i.e. when +the kernel extension is initialised. + +Note that the Variant DLL is a kernel extension. + +@return KErrNone if creation and initialisation is successful; + one of the other system wide error codes otherwise. + +@see TMMCardControllerInterface::NewStack() +@see TMMCardControllerInterface::NewMediaChange() +@see TMMCardControllerInterface::NewVcc() +@see TMMCardControllerInterface::Init() +@see TMMCardControllerInterface::IsMMCStack() +@see TMMCardControllerInterface::MediaChangeID() +@see TMMCardControllerInterface::VccID() +*/ +EXPORT_C TInt TMMCardControllerInterface::Create() +// +// Allocate any resources. Only done once on kernel initialization so don't +// worry about cleanup if it fails. +// + { + TInt r=KErrNone; + __KTRACE_OPT(KPBUS1,Kern::Printf(">TMMCardControllerInterface::Create")); + + // Create the password store (a single password store + // is allocated for the use of all MMC stacks + + TMMCPasswordStore* theMmcPasswordStore = (TMMCPasswordStore*)LocDrv::PasswordStore(); + if(theMmcPasswordStore == NULL) + { + theMmcPasswordStore = new TMMCPasswordStore(); + if(theMmcPasswordStore) + { + if((r = theMmcPasswordStore->Init()) == KErrNone) + r = LocDrv::RegisterPasswordStore(theMmcPasswordStore); + + if(r != KErrNone) + delete theMmcPasswordStore; + } + else + { + r = KErrNoMemory; + } + } + + if(r!= KErrNone) + return r; + + r = Init(); + if (r != KErrNone) + return r; + + + SMediaDeviceInfo mdi; + TInt i; + for (i=0; iiStack=pStack; + + TInt mcid=MediaChangeID(i); + __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Media Change %d",i,mcid)); + DMMCMediaChange* pM=(DMMCMediaChange*)TheMediaChanges[mcid]; + if (!pM) + { + __KTRACE_OPT(KPBUS1,Kern::Printf("New Media Change")); + pM=NewMediaChange(mcid); + if (!pM) + { + r=KErrNoMemory; + break; + } + TheMediaChanges[mcid]=pM; + __KTRACE_OPT(KPBUS1,Kern::Printf("Media Change %d at %08x",mcid,pM)); + r=pM->Create(); + if (r!=KErrNone) + break; + } + else + { + __KTRACE_OPT(KPBUS1,Kern::Printf("Media Change %d already exists at %08x",mcid,pM)); + ++pM->iReplyCount; + } + TInt vcc=VccID(i); + __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Vcc %d",i,vcc)); + DMMCPsu* pV=(DMMCPsu*)TheVccs[vcc]; + if (!pV) + { + __KTRACE_OPT(KPBUS1,Kern::Printf("New Vcc")); + pV=NewVcc(vcc,mcid); + if (!pV) + { + r=KErrNoMemory; + break; + } + TheVccs[vcc]=pV; + + // Assign Socket here such that iDFc can be obtained + pV->iSocket=pS; + + __KTRACE_OPT(KPBUS1,Kern::Printf("Vcc %d at %08x",vcc,pV)); + r=pV->Create(); + if (r!=KErrNone) + break; + } + else + { + __KTRACE_OPT(KPBUS1,Kern::Printf("Vcc %d already exists at %08x, mcid=%d",vcc,pV,pV->iMediaChangeNum)); +// DISALLOW SHARED PSUs UNTIL SOMEONE NEEDS THEM +// if (pV->iMediaChangeNum!=mcid) +// { + r=KErrInUse; +// break; +// } + } + + DMMCPsu* pVCore=(DMMCPsu*)TheVccCores[vcc]; + // N.B. Assume paired vcc & vccQ unit are numbered identically! + pVCore=NewVccCore(vcc,mcid); + if (pVCore) + { + TheVccCores[vcc]=pVCore; + __KTRACE_OPT(KPBUS1,Kern::Printf("VccCore %d at %08x",vcc,pVCore)); + + // Assign Socket here such that iDFcQ can be obtained + pVCore->iSocket=pS; + + r=pVCore->Create(); + if (r!=KErrNone) + break; + + // VccCore must issue sleep instead of power down + pVCore->iPwrDownCheckFn = DMMCPsu::SleepCheck; + } + //else do nothing doesn't matter if its not supported + + r=pS->Create(mdi.iDeviceName); + if (r!=KErrNone) + break; + + pS->iMediaChangeNumber=mcid; + pS->iMediaChange=pM; + pS->iVcc=pV; + if (pVCore) + { + pS->iVccCore = pVCore; + } + + r=pS->Init(); + if (r!=KErrNone) + break; + + r = RegisterMediaDevices(i); + if(r != KErrNone) + break; + + __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Created OK",i)); + } + else + __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d not MMC card",i)); + } + + __KTRACE_OPT(KPBUS1,Kern::Printf("iStack->MachineInfo(mi); + + // There may be more than one physical card slot for this socket/stack; + // if this is the case, then we have to create a separate DPBusPrimaryMedia + // for each one. This is the only way to get the local media sub-system to iterate + // through the installed set of media drivers repeatedly for each card slot + // (rather than once for the entire stack). We also need to share the number of + // drives/partitions (SMediaDeviceInfo.iDriveCount) and the number of media + // (SMediaDeviceInfo.iNumMedia) equally between the slots... + __ASSERT_ALWAYS(mdi.iDriveCount >= mi.iTotalSockets, DMMCSocket::Panic(DMMCSocket::EMMCInvalidNumberOfCardSlots) ); + __ASSERT_ALWAYS(mdi.iNumMedia >= mi.iTotalSockets, DMMCSocket::Panic(DMMCSocket::EMMCInvalidNumberOfCardSlots) ); + + TInt physicalCardSlots = mi.iTotalSockets; + TInt drivesPerSlot = mdi.iDriveCount / physicalCardSlots; + TInt numMediaPerSlot = mdi.iNumMedia / physicalCardSlots; + TInt driveListIndex = 0; + +#if !defined(__WINS__) + DMMCStack::TDemandPagingInfo demandPagingInfo; + demandPagingInfo.iPagingDriveList = NULL; + demandPagingInfo.iDriveCount = 0; + TBool demandPagingSupported = + pS->iStack->DemandPagingInfo(demandPagingInfo) == KErrNone ? (TBool)ETrue : (TBool)EFalse; + +#endif // __WINS__ + + + for (TInt i=0; iiSlotNumber = i; + + err = LocDrv::RegisterMediaDevice( + mdi.iDevice, + drivesPerSlot, + mdi.iDriveList+driveListIndex, + pMedia, + numMediaPerSlot, + *mdi.iDeviceName); + if (err != KErrNone) + break; + +#if !defined(__WINS__) + if (demandPagingSupported && demandPagingInfo.iSlotNumber == i) + { + err = LocDrv::RegisterPagingDevice( + pMedia, + demandPagingInfo.iPagingDriveList, + demandPagingInfo.iDriveCount, + demandPagingInfo.iPagingType, + demandPagingInfo.iReadShift, + demandPagingInfo.iNumPages); + + // Ignore error if demand paging not supported by kernel + if (err == KErrNotSupported) + err = KErrNone; + + if (err != KErrNone) + break; + } + + if (mi.iFlags & TMMCMachineInfo::ESupportsDMA) + { + err = LocDrv::RegisterDmaDevice(pMedia, + KMMCardHighCapBlockSize, + pS->MaxDataTransferLength(), + pS->DmaAlignment()); + if (err != KErrNone) + break; + } +#endif // __WINS__ + + driveListIndex+= drivesPerSlot; + } + + return(err); + }