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