First public contribution.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\drivers\pbus\mmc\mmccd_init.cpp
18 #include <drivers/mmccd_ifc.h>
19 #include <drivers/pbusmedia.h>
25 Starts the sequence of operations that creates the platform specific objects,
26 registers the socket, and initialises the stack.
28 The function is called in the Variant DLL's entry point code, i.e. when
29 the kernel extension is initialised.
31 Note that the Variant DLL is a kernel extension.
33 @return KErrNone if creation and initialisation is successful;
34 one of the other system wide error codes otherwise.
36 @see TMMCardControllerInterface::NewStack()
37 @see TMMCardControllerInterface::NewMediaChange()
38 @see TMMCardControllerInterface::NewVcc()
39 @see TMMCardControllerInterface::Init()
40 @see TMMCardControllerInterface::IsMMCStack()
41 @see TMMCardControllerInterface::MediaChangeID()
42 @see TMMCardControllerInterface::VccID()
44 EXPORT_C TInt TMMCardControllerInterface::Create()
46 // Allocate any resources. Only done once on kernel initialization so don't
47 // worry about cleanup if it fails.
51 __KTRACE_OPT(KPBUS1,Kern::Printf(">TMMCardControllerInterface::Create"));
53 // Create the password store (a single password store
54 // is allocated for the use of all MMC stacks
56 TMMCPasswordStore* theMmcPasswordStore = (TMMCPasswordStore*)LocDrv::PasswordStore();
57 if(theMmcPasswordStore == NULL)
59 theMmcPasswordStore = new TMMCPasswordStore();
60 if(theMmcPasswordStore)
62 if((r = theMmcPasswordStore->Init()) == KErrNone)
63 r = LocDrv::RegisterPasswordStore(theMmcPasswordStore);
66 delete theMmcPasswordStore;
84 for (i=0; i<KMaxPBusSockets && r==KErrNone; i++)
86 if (IsMMCSocket(i,mdi))
88 __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d is MMC card",i));
90 // Allocate a new socket
91 DMMCSocket* pS = NewSocket(i, theMmcPasswordStore);
99 // Allocate a variant specific stack object via the interface
100 DMMCStack* pStack=NewStack(i, pS);
109 TInt mcid=MediaChangeID(i);
110 __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Media Change %d",i,mcid));
111 DMMCMediaChange* pM=(DMMCMediaChange*)TheMediaChanges[mcid];
114 __KTRACE_OPT(KPBUS1,Kern::Printf("New Media Change"));
115 pM=NewMediaChange(mcid);
121 TheMediaChanges[mcid]=pM;
122 __KTRACE_OPT(KPBUS1,Kern::Printf("Media Change %d at %08x",mcid,pM));
129 __KTRACE_OPT(KPBUS1,Kern::Printf("Media Change %d already exists at %08x",mcid,pM));
133 __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Vcc %d",i,vcc));
134 DMMCPsu* pV=(DMMCPsu*)TheVccs[vcc];
137 __KTRACE_OPT(KPBUS1,Kern::Printf("New Vcc"));
146 // Assign Socket here such that iDFc can be obtained
149 __KTRACE_OPT(KPBUS1,Kern::Printf("Vcc %d at %08x",vcc,pV));
156 __KTRACE_OPT(KPBUS1,Kern::Printf("Vcc %d already exists at %08x, mcid=%d",vcc,pV,pV->iMediaChangeNum));
157 // DISALLOW SHARED PSUs UNTIL SOMEONE NEEDS THEM
158 // if (pV->iMediaChangeNum!=mcid)
165 DMMCPsu* pVCore=(DMMCPsu*)TheVccCores[vcc];
166 // N.B. Assume paired vcc & vccQ unit are numbered identically!
167 pVCore=NewVccCore(vcc,mcid);
170 TheVccCores[vcc]=pVCore;
171 __KTRACE_OPT(KPBUS1,Kern::Printf("VccCore %d at %08x",vcc,pVCore));
173 // Assign Socket here such that iDFcQ can be obtained
180 // VccCore must issue sleep instead of power down
181 pVCore->iPwrDownCheckFn = DMMCPsu::SleepCheck;
183 //else do nothing doesn't matter if its not supported
185 r=pS->Create(mdi.iDeviceName);
189 pS->iMediaChangeNumber=mcid;
194 pS->iVccCore = pVCore;
201 r = RegisterMediaDevices(i);
205 __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Created OK",i));
208 __KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d not MMC card",i));
211 __KTRACE_OPT(KPBUS1,Kern::Printf("<TMMCardControllerInterface::Create, ret %d",r));
215 EXPORT_C TInt TMMCardControllerInterface::RegisterMediaDevices(TInt aSocket)
217 Registers the media devices for the specified socket.
218 By default, All MMC derivatives register at least an MMC driver
224 SMediaDeviceInfo mdi;
226 if (IsMMCSocket(aSocket, mdi) == EFalse)
227 return(KErrNotSupported);
229 DMMCSocket* pS = (DMMCSocket*) TheSockets[aSocket];
231 return(KErrNoMemory);
234 pS->iStack->MachineInfo(mi);
236 // There may be more than one physical card slot for this socket/stack;
237 // if this is the case, then we have to create a separate DPBusPrimaryMedia
238 // for each one. This is the only way to get the local media sub-system to iterate
239 // through the installed set of media drivers repeatedly for each card slot
240 // (rather than once for the entire stack). We also need to share the number of
241 // drives/partitions (SMediaDeviceInfo.iDriveCount) and the number of media
242 // (SMediaDeviceInfo.iNumMedia) equally between the slots...
243 __ASSERT_ALWAYS(mdi.iDriveCount >= mi.iTotalSockets, DMMCSocket::Panic(DMMCSocket::EMMCInvalidNumberOfCardSlots) );
244 __ASSERT_ALWAYS(mdi.iNumMedia >= mi.iTotalSockets, DMMCSocket::Panic(DMMCSocket::EMMCInvalidNumberOfCardSlots) );
246 TInt physicalCardSlots = mi.iTotalSockets;
247 TInt drivesPerSlot = mdi.iDriveCount / physicalCardSlots;
248 TInt numMediaPerSlot = mdi.iNumMedia / physicalCardSlots;
249 TInt driveListIndex = 0;
251 #if !defined(__WINS__)
252 DMMCStack::TDemandPagingInfo demandPagingInfo;
253 demandPagingInfo.iPagingDriveList = NULL;
254 demandPagingInfo.iDriveCount = 0;
255 TBool demandPagingSupported =
256 pS->iStack->DemandPagingInfo(demandPagingInfo) == KErrNone ? (TBool)ETrue : (TBool)EFalse;
261 for (TInt i=0; i<physicalCardSlots ; i++)
263 DPBusPrimaryMedia* pMedia = new DPBusPrimaryMedia(pS);
265 return(KErrNoMemory);
266 // store the slot number in DPBusPrimaryMedia so that it can
267 // subsequently be passed to the media driver.
268 pMedia->iSlotNumber = i;
270 err = LocDrv::RegisterMediaDevice(
273 mdi.iDriveList+driveListIndex,
280 #if !defined(__WINS__)
281 if (demandPagingSupported && demandPagingInfo.iSlotNumber == i)
283 err = LocDrv::RegisterPagingDevice(
285 demandPagingInfo.iPagingDriveList,
286 demandPagingInfo.iDriveCount,
287 demandPagingInfo.iPagingType,
288 demandPagingInfo.iReadShift,
289 demandPagingInfo.iNumPages);
291 // Ignore error if demand paging not supported by kernel
292 if (err == KErrNotSupported)
299 if (mi.iFlags & TMMCMachineInfo::ESupportsDMA)
301 err = LocDrv::RegisterDmaDevice(pMedia,
302 KMMCardHighCapBlockSize,
303 pS->MaxDataTransferLength(),
310 driveListIndex+= drivesPerSlot;