os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/mmccd_init.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\drivers\pbus\mmc\mmccd_init.cpp
    15 // 
    16 //
    17 
    18 #include <drivers/mmccd_ifc.h>
    19 #include <drivers/pbusmedia.h>
    20 
    21 
    22 
    23 
    24 /**
    25 Starts the sequence of operations that creates the platform specific objects,
    26 registers the socket, and initialises the stack.
    27 
    28 The function is called in the Variant DLL's entry point code, i.e. when
    29 the kernel extension is initialised.
    30 
    31 Note that the Variant DLL is a kernel extension.
    32 
    33 @return KErrNone if creation and initialisation is successful;
    34         one of the other system wide error codes otherwise.
    35         
    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()
    43 */	 
    44 EXPORT_C TInt TMMCardControllerInterface::Create()
    45 //
    46 // Allocate any resources. Only done once on kernel initialization so don't
    47 // worry about cleanup if it fails.
    48 //
    49 	{
    50 	TInt r=KErrNone;
    51 	__KTRACE_OPT(KPBUS1,Kern::Printf(">TMMCardControllerInterface::Create"));
    52 
    53 	// Create the password store (a single password store
    54 	//  is allocated for the use of all MMC stacks
    55 
    56 	TMMCPasswordStore* theMmcPasswordStore = (TMMCPasswordStore*)LocDrv::PasswordStore();
    57 	if(theMmcPasswordStore == NULL)
    58 		{
    59 		theMmcPasswordStore = new TMMCPasswordStore();
    60 		if(theMmcPasswordStore)
    61 			{
    62 			if((r = theMmcPasswordStore->Init()) == KErrNone)
    63 				r = LocDrv::RegisterPasswordStore(theMmcPasswordStore);					
    64 
    65 			if(r != KErrNone)
    66 				delete theMmcPasswordStore;
    67 			}
    68 		else
    69 			{
    70 			r = KErrNoMemory;
    71 			}
    72 		}
    73 
    74 	if(r!= KErrNone)
    75 		return r;
    76 
    77 	r = Init();
    78 	if (r != KErrNone)
    79 		return r;
    80 
    81 
    82 	SMediaDeviceInfo mdi;
    83 	TInt i;
    84 	for (i=0; i<KMaxPBusSockets && r==KErrNone; i++)
    85 		{
    86 		if (IsMMCSocket(i,mdi))
    87 			{
    88 			__KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d is MMC card",i));
    89 
    90 			// Allocate a new socket
    91 			DMMCSocket* pS = NewSocket(i, theMmcPasswordStore);
    92 			if (!pS)
    93 				{
    94 				r=KErrNoMemory;
    95 				break;
    96 				}
    97 			TheSockets[i]=pS;
    98 
    99 			// Allocate a variant specific stack object via the interface
   100 			DMMCStack* pStack=NewStack(i, pS);
   101 			if (!pStack)
   102 				{
   103 				r=KErrNoMemory;
   104 				break;
   105 				}
   106 
   107 			pS->iStack=pStack;
   108 
   109 			TInt mcid=MediaChangeID(i);
   110 			__KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Media Change %d",i,mcid));
   111 			DMMCMediaChange* pM=(DMMCMediaChange*)TheMediaChanges[mcid];
   112 			if (!pM)
   113 				{
   114 				__KTRACE_OPT(KPBUS1,Kern::Printf("New Media Change"));
   115 				pM=NewMediaChange(mcid);
   116 				if (!pM)
   117 					{
   118 					r=KErrNoMemory;
   119 					break;
   120 					}
   121 				TheMediaChanges[mcid]=pM;
   122 				__KTRACE_OPT(KPBUS1,Kern::Printf("Media Change %d at %08x",mcid,pM));
   123 				r=pM->Create();
   124 				if (r!=KErrNone)
   125 					break;
   126 				}
   127 			else
   128 				{
   129 				__KTRACE_OPT(KPBUS1,Kern::Printf("Media Change %d already exists at %08x",mcid,pM));
   130 				++pM->iReplyCount;
   131 				}
   132 			TInt vcc=VccID(i);
   133 			__KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Vcc %d",i,vcc));
   134 			DMMCPsu* pV=(DMMCPsu*)TheVccs[vcc];
   135 			if (!pV)
   136 				{
   137 				__KTRACE_OPT(KPBUS1,Kern::Printf("New Vcc"));
   138 				pV=NewVcc(vcc,mcid);
   139 				if (!pV)
   140 					{
   141 					r=KErrNoMemory;
   142 					break;
   143 					}
   144 				TheVccs[vcc]=pV;
   145 				
   146 				// Assign Socket here such that iDFc can be obtained
   147 				pV->iSocket=pS;
   148 				
   149 				__KTRACE_OPT(KPBUS1,Kern::Printf("Vcc %d at %08x",vcc,pV));
   150 				r=pV->Create();
   151 				if (r!=KErrNone)
   152 					break;
   153 				}
   154 			else 
   155 				{
   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)
   159 //					{
   160 					r=KErrInUse;
   161 //					break;
   162 //					}
   163 				}
   164 			
   165 			DMMCPsu* pVCore=(DMMCPsu*)TheVccCores[vcc];
   166 			// N.B. Assume paired vcc & vccQ unit are numbered identically!
   167 			pVCore=NewVccCore(vcc,mcid);
   168 			if (pVCore)
   169 				{
   170 				TheVccCores[vcc]=pVCore;
   171 				__KTRACE_OPT(KPBUS1,Kern::Printf("VccCore %d at %08x",vcc,pVCore));
   172 				
   173 				// Assign Socket here such that iDFcQ can be obtained
   174 				pVCore->iSocket=pS;
   175 				
   176 				r=pVCore->Create();
   177 				if (r!=KErrNone)
   178 					break;
   179 				
   180 				// VccCore must issue sleep instead of power down 
   181 				pVCore->iPwrDownCheckFn = DMMCPsu::SleepCheck;				
   182 				}
   183 			//else do nothing doesn't matter if its not supported
   184 			
   185 			r=pS->Create(mdi.iDeviceName);
   186 			if (r!=KErrNone)
   187 				break;
   188 
   189 			pS->iMediaChangeNumber=mcid;
   190 			pS->iMediaChange=pM;
   191 			pS->iVcc=pV;
   192 			if (pVCore)
   193 				{
   194 				pS->iVccCore = pVCore;
   195 				}
   196 
   197 			r=pS->Init();
   198 			if (r!=KErrNone)		
   199 				break;
   200 
   201 			r = RegisterMediaDevices(i);
   202 			if(r != KErrNone)
   203 			   break;
   204 			
   205 			__KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d Created OK",i));
   206 			}
   207 		else
   208 			__KTRACE_OPT(KPBUS1,Kern::Printf("Socket %d not MMC card",i));
   209 		}
   210 		
   211 	__KTRACE_OPT(KPBUS1,Kern::Printf("<TMMCardControllerInterface::Create, ret %d",r));
   212 	return r;
   213 	}
   214 
   215 EXPORT_C TInt TMMCardControllerInterface::RegisterMediaDevices(TInt aSocket)
   216 /**
   217 Registers the media devices for the specified socket.
   218 By default, All MMC derivatives register at least an MMC driver
   219 @internal
   220 */
   221 	{
   222 	TInt err = KErrNone;
   223 	
   224 	SMediaDeviceInfo mdi;
   225 
   226 	if (IsMMCSocket(aSocket, mdi) == EFalse)
   227 		return(KErrNotSupported);
   228 		
   229 	DMMCSocket* pS = (DMMCSocket*) TheSockets[aSocket];
   230 	if(pS == NULL)
   231 		return(KErrNoMemory);
   232 
   233 	TMMCMachineInfo mi;
   234 	pS->iStack->MachineInfo(mi);
   235 	
   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) );
   245 
   246 	TInt physicalCardSlots = mi.iTotalSockets;
   247 	TInt drivesPerSlot = mdi.iDriveCount / physicalCardSlots;
   248 	TInt numMediaPerSlot = mdi.iNumMedia / physicalCardSlots;
   249 	TInt driveListIndex = 0;
   250 
   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;
   257 
   258 #endif // __WINS__
   259 
   260 
   261 	for (TInt i=0; i<physicalCardSlots ; i++)	
   262 		{
   263 		DPBusPrimaryMedia* pMedia = new DPBusPrimaryMedia(pS);
   264 		if (pMedia == NULL)
   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;
   269 
   270 		err = LocDrv::RegisterMediaDevice(
   271 				mdi.iDevice,
   272 				drivesPerSlot,
   273 				mdi.iDriveList+driveListIndex,
   274 				pMedia,
   275 				numMediaPerSlot,
   276 				*mdi.iDeviceName);
   277 		if (err != KErrNone)
   278 			break;
   279 
   280 #if !defined(__WINS__)
   281 		if (demandPagingSupported && demandPagingInfo.iSlotNumber == i)
   282 			{
   283 			err = LocDrv::RegisterPagingDevice(
   284 				pMedia, 
   285 				demandPagingInfo.iPagingDriveList,
   286 				demandPagingInfo.iDriveCount,
   287 				demandPagingInfo.iPagingType,
   288 				demandPagingInfo.iReadShift,
   289 				demandPagingInfo.iNumPages);
   290 
   291 			// Ignore error if demand paging not supported by kernel
   292 			if (err == KErrNotSupported)
   293 				err = KErrNone;
   294 
   295 			if (err != KErrNone)
   296 				break;
   297 			}
   298 
   299 		if (mi.iFlags & TMMCMachineInfo::ESupportsDMA)
   300 			{
   301 			err = LocDrv::RegisterDmaDevice(pMedia,
   302 											KMMCardHighCapBlockSize, 
   303 											pS->MaxDataTransferLength(), 
   304 											pS->DmaAlignment());
   305 			if (err != KErrNone)
   306 				break;
   307 			}
   308 #endif // __WINS__
   309 
   310 		driveListIndex+= drivesPerSlot;
   311 		}
   312 	
   313 	return(err);
   314 	}