kernel/eka/drivers/medmmc/bgahsmmcptn.cpp
changeset 287 ddfd5aa0d58f
parent 254 1560c419b176
child 300 1d28c8722707
equal deleted inserted replaced
286:48e57fb1237e 287:ddfd5aa0d58f
    14 // Partition Management for Embedded MMC devices
    14 // Partition Management for Embedded MMC devices
    15 //
    15 //
    16 //
    16 //
    17 
    17 
    18 #include <emmcptn.h>
    18 #include <emmcptn.h>
       
    19 #include "mmc.h"
    19 #include "bgahsmmcptn.h"
    20 #include "bgahsmmcptn.h"
       
    21 #include "medmmc.h"
    20 #include "toc.h"
    22 #include "toc.h"
       
    23 
    21 //#define __DEBUG_PARTITIONS_
    24 //#define __DEBUG_PARTITIONS_
    22 //#define __DEBUG_CHECK_PARTITION_
    25 //#define __DEBUG_CHECK_PARTITION_
    23 const TInt    KDiskSectorShift          = 9;
       
    24 
    26 
    25 class DBB5PartitionInfo : public DEMMCPartitionInfo
    27 class DBB5PartitionInfo : public DEMMCPartitionInfo
    26 	{
    28 	{
    27 public:
    29 public:
    28 	 DBB5PartitionInfo();
    30 	 DBB5PartitionInfo();
    37 	void SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors);
    39 	void SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors);
    38 
    40 
    39 private:
    41 private:
    40 	virtual TInt ReadPartition(TUint32 aPtOffset);
    42 	virtual TInt ReadPartition(TUint32 aPtOffset);
    41 	static void SessionEndCallBack(TAny* aSelf);
    43 	static void SessionEndCallBack(TAny* aSelf);
    42 		   void DoSessionEndCallBack();
    44 	void DoSessionEndCallBack();
    43 	virtual TInt DecodePartitionInfo();
    45 	virtual TInt DecodePartitionInfo();
       
    46 	TInt GetPartitionSizeInSectors(TUint aPartition, TUint32& aSize);
       
    47 	TInt GetPartitionOffset(TUint32& aPtOffset);
       
    48 	TInt SelectNextPartition();
    44 
    49 
    45 protected:
    50 protected:
    46 	DMediaDriver*	iDriver;
    51 	DMediaDriver*	iDriver;
    47 	TPartitionInfo* iPartitionInfo;
    52 	TPartitionInfo* iPartitionInfo;
    48 	TMMCCallBack	iSessionEndCallBack;
    53 	TMMCCallBack	iSessionEndCallBack;
    51 	TMMCard*		iCard;
    56 	TMMCard*		iCard;
    52 	TUint8* 		iIntBuf;
    57 	TUint8* 		iIntBuf;
    53 	TUint32 		iPartitionAttributes[KMaxLocalDrives];
    58 	TUint32 		iPartitionAttributes[KMaxLocalDrives];
    54 	TBool           iCheckTOC;
    59 	TBool           iCheckTOC;
    55 	Toc*            iTocPtr;
    60 	Toc*            iTocPtr;
       
    61 	TUint32			iSelectedPartition;	
    56 	};
    62 	};
    57 
    63 
    58 DBB5PartitionInfo::DBB5PartitionInfo()
    64 DBB5PartitionInfo::DBB5PartitionInfo()
    59   : iSessionEndCallBack(DBB5PartitionInfo::SessionEndCallBack, this),
    65   : iSessionEndCallBack(DBB5PartitionInfo::SessionEndCallBack, this),
    60     iCheckTOC(EFalse)
    66     iCheckTOC(EFalse)
    86 
    92 
    87 	// this gets used before any access
    93 	// this gets used before any access
    88 	TInt bufLen, minorBufLen;
    94 	TInt bufLen, minorBufLen;
    89 	stack->BufferInfo(iIntBuf, bufLen, minorBufLen);
    95 	stack->BufferInfo(iIntBuf, bufLen, minorBufLen);
    90 
    96 
       
    97 	iSelectedPartition = TExtendedCSD::ESelectUserArea;
       
    98 	
    91 	return(KErrNone);
    99 	return(KErrNone);
    92 	}
   100 	}
    93 
   101 
    94 TInt DBB5PartitionInfo::PartitionInfo(TPartitionInfo& aInfo, const TMMCCallBack& aCallBack)
   102 TInt DBB5PartitionInfo::PartitionInfo(TPartitionInfo& aInfo, const TMMCCallBack& aCallBack)
    95 	{
   103 	{
    96 	iPartitionInfo = &aInfo;
   104 	iPartitionInfo = &aInfo;
       
   105 	iPartitionInfo->iPartitionCount = 0;
    97 	iCallBack = aCallBack;
   106 	iCallBack = aCallBack;
    98 
   107 
       
   108 	// Always check the user partition first
       
   109 	iSelectedPartition = TExtendedCSD::ESelectUserArea;
       
   110 	iSession->SetPartition(iSelectedPartition);
       
   111 
    99 	// Preferred partition scheme is BB5, which is located in the last block of the media.
   112 	// Preferred partition scheme is BB5, which is located in the last block of the media.
   100     const TUint32 ptiOffset = (I64LOW(iCard->DeviceSize64() >> KDiskSectorShift)) - KPIOffsetFromMediaEnd;
   113     TUint32 ptiOffset;
   101 	return ReadPartition(ptiOffset);
   114     TInt r;
   102 	}
   115     do
   103 	
   116     	{
       
   117 	    r = GetPartitionOffset(ptiOffset);
       
   118 
       
   119 	    if(r == KErrNone)
       
   120 	    	{
       
   121 		    r = ReadPartition(ptiOffset);
       
   122 		    return r;
       
   123 	    	}
       
   124 
       
   125 	    r = SelectNextPartition();
       
   126     	}
       
   127     while(r != KErrNotFound);
       
   128 
       
   129 	return r;
       
   130 	}
       
   131 	
       
   132 // retrieves size in terms of sectors
       
   133 TInt DBB5PartitionInfo::GetPartitionSizeInSectors(TUint aPartition, TUint32& aSize)
       
   134 	{
       
   135 	TInt r = KErrNone;
       
   136 	
       
   137 	TUint32 size = 0;
       
   138 	
       
   139 	const TExtendedCSD& extCsd = iCard->ExtendedCSD();
       
   140 	
       
   141 	switch(aPartition)
       
   142 		{
       
   143 		case TExtendedCSD::ESelectUserArea:
       
   144 			{
       
   145 			size = (TUint32)(iCard->DeviceSize64() / KSectorSize);
       
   146 			
       
   147 			if(extCsd.ExtendedCSDRev() >= TExtendedCSD::EExtendedCSDRev1_5)
       
   148 				{
       
   149 				TUint32 otherPartitionsSize = 
       
   150 					extCsd.GeneralPurposePartition1SizeInSectors()
       
   151 					+ extCsd.GeneralPurposePartition2SizeInSectors()
       
   152 					+ extCsd.GeneralPurposePartition3SizeInSectors()
       
   153 					+ extCsd.GeneralPurposePartition4SizeInSectors();
       
   154 					
       
   155 					__ASSERT_DEBUG(size >= otherPartitionsSize, Kern::Fault("DBB5PartitionInfo size mismatch", __LINE__));
       
   156 					size -= otherPartitionsSize;
       
   157 				}
       
   158 			}
       
   159 			break;
       
   160 		case TExtendedCSD::ESelectBootPartition1:
       
   161 		case TExtendedCSD::ESelectBootPartition2:
       
   162 			size = (extCsd.ExtendedCSDRev() < TExtendedCSD::EExtendedCSDRev1_3) ? 
       
   163 				0 : extCsd.BootSizeInSectors();
       
   164 			break;
       
   165 		case TExtendedCSD::ESelectRPMB:
       
   166 			size = (extCsd.ExtendedCSDRev() < TExtendedCSD::EExtendedCSDRev1_5) ? 
       
   167 				0 : extCsd.RpmbSizeInSectors();
       
   168 			break;
       
   169 		case TExtendedCSD::ESelectGPAPartition1:
       
   170 			size = (extCsd.ExtendedCSDRev() < TExtendedCSD::EExtendedCSDRev1_5) ? 
       
   171 				0 : extCsd.GeneralPurposePartition1SizeInSectors();
       
   172 			break;
       
   173 		case TExtendedCSD::ESelectGPAPartition2:
       
   174 			size = (extCsd.ExtendedCSDRev() < TExtendedCSD::EExtendedCSDRev1_5) ? 
       
   175 				0 : extCsd.GeneralPurposePartition2SizeInSectors();
       
   176 			break;
       
   177 		case TExtendedCSD::ESelectGPAPartition3:
       
   178 			size = (extCsd.ExtendedCSDRev() < TExtendedCSD::EExtendedCSDRev1_5) ? 
       
   179 				0 : extCsd.GeneralPurposePartition3SizeInSectors();
       
   180 			break;
       
   181 		case TExtendedCSD::ESelectGPAPartition4:
       
   182 			size = (extCsd.ExtendedCSDRev() < TExtendedCSD::EExtendedCSDRev1_5) ? 
       
   183 				0 : extCsd.GeneralPurposePartition4SizeInSectors();
       
   184 			break;
       
   185 		default:
       
   186 			// unknown partition
       
   187 			size = 0;
       
   188 			r = KErrNotSupported;
       
   189 			break;
       
   190 		}
       
   191 
       
   192 	aSize = size;	
       
   193 	return r;
       
   194 	}
       
   195 	
       
   196 TInt DBB5PartitionInfo::GetPartitionOffset(TUint32& aPtiOffset)
       
   197 	{
       
   198 	TInt r = GetPartitionSizeInSectors(iSelectedPartition, aPtiOffset);
       
   199 		
       
   200 	if((r != KErrNone) || (aPtiOffset == 0))
       
   201 		{
       
   202 		// error reading or partition not supported, skip
       
   203 		r = KErrNotSupported;
       
   204 		}
       
   205 	else
       
   206 		{			
       
   207 		// need to determine correct end of the partition
       
   208 		aPtiOffset -= KPIOffsetFromMediaEnd;
       
   209 		}
       
   210 		
       
   211 	return r;
       
   212 	}
       
   213 	
       
   214 TInt DBB5PartitionInfo::SelectNextPartition()
       
   215 	{
       
   216 	TExtendedCSD extCsd = iCard->ExtendedCSD();
       
   217 	TUint maxPartition = TExtendedCSD::ESelectUserArea;
       
   218 	
       
   219 	if(extCsd.ExtendedCSDRev() >= TExtendedCSD::EExtendedCSDRev1_5)
       
   220 		{
       
   221 		// v4.4 supports UDA, 2x BOOT, RPMB and 4x GPAP partitions
       
   222 		maxPartition = TExtendedCSD::ESelectGPAPartition4;
       
   223 		}
       
   224 #ifdef EMMC_BOOT_PARTITION_ACCESS_ENABLED
       
   225 	else if(extCsd.ExtendedCSDRev() >= TExtendedCSD::EExtendedCSDRev1_3)
       
   226 		{
       
   227 		// v4.3 supports up to two BOOT partitions
       
   228 		maxPartition = TExtendedCSD::ESelectBootPartition2;
       
   229 		}
       
   230 #endif // EMMC_BOOT_PARTITION_ACCESS_ENABLED
       
   231 
       
   232 	++iSelectedPartition;
       
   233 	
       
   234 	// skip through to GPAP1 if either the currently selected partition is RPMB or
       
   235 	// if it is one of the BOOT partitions and boot partition access is not enabled
       
   236 	if((iSelectedPartition == TExtendedCSD::ESelectRPMB)
       
   237 #ifndef EMMC_BOOT_PARTITION_ACCESS_ENABLED 
       
   238 		|| (iSelectedPartition == TExtendedCSD::ESelectBootPartition1)
       
   239 		|| (iSelectedPartition == TExtendedCSD::ESelectBootPartition2)
       
   240 #endif	   
       
   241 		)
       
   242 		{
       
   243 		iSelectedPartition = TExtendedCSD::ESelectGPAPartition1;
       
   244 		}
       
   245 
       
   246 	TInt r = KErrNone;
       
   247 	if(iSelectedPartition > maxPartition)
       
   248 		{
       
   249 		r = KErrNotFound; // no more partitions to be checked
       
   250 		}
       
   251 	else
       
   252 		{
       
   253 		iSession->SetPartition(iSelectedPartition);
       
   254 		}
       
   255 		
       
   256 	return r;	
       
   257 	}	
       
   258 	
       
   259 // returns KErrCompletion on success after having checked all partitions
   104 TInt DBB5PartitionInfo::ReadPartition(TUint32 aPtOffset)
   260 TInt DBB5PartitionInfo::ReadPartition(TUint32 aPtOffset)
   105     {
   261     {
   106 	// If media driver is persistent (see EMediaDriverPersistent)
   262 	// If media driver is persistent (see EMediaDriverPersistent)
   107 	// the card may have changed since last power down, so reset CID
   263 	// the card may have changed since last power down, so reset CID
   108 	iSession->SetCard(iCard);
   264 	iSession->SetCard(iCard);
   165 	{
   321 	{
   166 	iDriver->EndInCritical();
   322 	iDriver->EndInCritical();
   167 
   323 
   168 	TInt r = iSession->EpocErrorCode();
   324 	TInt r = iSession->EpocErrorCode();
   169 
   325 
       
   326 	
       
   327 	TInt& partitionCount = iPartitionInfo->iPartitionCount;
       
   328 
   170 	if (r == KErrNone)
   329 	if (r == KErrNone)
   171 		r = DecodePartitionInfo();
   330 		r = DecodePartitionInfo();
   172 
   331 
   173 	if (!iCheckTOC)
   332 	if (iCheckTOC)
   174 	    {        
   333 		{
   175 	    iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady);
   334 		//BB5 table not found need to check for TOC in this partition before continuing
   176 	    }
   335 		if (r!=KErrNone)
   177 	}
   336 			{
       
   337 			iDriver->PartitionInfoComplete(KErrNotReady);
       
   338 			}
       
   339 		return;
       
   340 		}
       
   341 
       
   342 
       
   343 	if(r == KErrNone)
       
   344 		{
       
   345 		// check next partition(s) for BB5
       
   346 		TUint32 ptiOffset = 0;
       
   347 	
       
   348 		r = SelectNextPartition();
       
   349 		while(r != KErrNotFound)
       
   350 			{
       
   351 			if(r == KErrNone)
       
   352 				r = GetPartitionOffset(ptiOffset);
       
   353 				
       
   354 			if(r == KErrNone)
       
   355 				{
       
   356 				r = ReadPartition(ptiOffset);
       
   357 				if(r != KErrNone)
       
   358 					break;
       
   359 
       
   360 
       
   361 				return;
       
   362 				}
       
   363 
       
   364 			r = SelectNextPartition();
       
   365 			}
       
   366 
       
   367 		
       
   368 		// end of partitions - reinterpret error code
       
   369 		if(r != KErrNotFound)
       
   370 			{
       
   371 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:dsc: ReadPartition() failed r=%d!", r));
       
   372 			r = KErrCorrupt;
       
   373 			}
       
   374 		else if(partitionCount == 0)
       
   375 			{
       
   376 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:dsc: No supported partitions found!"));
       
   377 			r = KErrCorrupt;
       
   378 			}
       
   379 		else
       
   380 			r = KErrCompletion;
       
   381 		}
       
   382 
       
   383 	// Notify medmmc that partitioninfo is complete
       
   384 	iCallBack.CallBack();
       
   385 
       
   386 	// All potential partitions checked - KErrCompletion
       
   387 	// indicates that there are no more partitions to check
       
   388 	r = (r == KErrCompletion) ? KErrNone : KErrNotReady;
       
   389 	iDriver->PartitionInfoComplete(r);
       
   390 	}
       
   391 
   178 
   392 
   179 TInt DBB5PartitionInfo::DecodePartitionInfo()
   393 TInt DBB5PartitionInfo::DecodePartitionInfo()
   180 //
   394 //
   181 // Decode partition info that was read into internal buffer
   395 // Decode partition info that was read into internal buffer
   182 //
   396 //
   183 	{
   397 	{
   184 	__KTRACE_OPT(KPBUSDRV, Kern::Printf(">Mmc:PartitionInfo()"));
   398 	__KTRACE_OPT(KPBUSDRV, Kern::Printf(">Mmc:PartitionInfo()"));
   185 	TUint partitionCount = iPartitionInfo->iPartitionCount = 0;
   399 	TInt& partitionCount = iPartitionInfo->iPartitionCount;
   186 
   400     TInt r = KErrNone;
   187 	
   401 
   188 	if (iCheckTOC)
   402 	if (iCheckTOC)
   189 	    {
   403 	    {
   190         // Try utilising the TOC (Table Of Contents) partitioning scheme 
   404         // Try utilising the TOC (Table Of Contents) partitioning scheme 
   191         const TText8* KRofsNames[KNoOfROFSPartitions] = { KTocRofs1Generic,
   405         const TText8* KRofsNames[KNoOfROFSPartitions] = { KTocRofs1Generic,
   192                                                           KTocRofs2Generic,
   406                                                           KTocRofs2Generic,
   197                                                           };
   411                                                           };
   198                                         
   412                                         
   199         STocItem item;
   413         STocItem item;
   200         iTocPtr = reinterpret_cast<Toc*>(&iIntBuf[0]);
   414         iTocPtr = reinterpret_cast<Toc*>(&iIntBuf[0]);
   201         iTocPtr->iTocStartSector = KTocStartSector;
   415         iTocPtr->iTocStartSector = KTocStartSector;
   202         TInt r = KErrNone;
       
   203 
   416 
   204 // USER Drive - Only 1        
   417 // USER Drive - Only 1        
   205         r = iTocPtr->GetItemByName(KTocUserName, item); 
   418         r = iTocPtr->GetItemByName(KTocUserName, item); 
   206         if (KErrNone == r)
   419         if (KErrNone == r)
   207             {
   420             {
   260             iPartitionInfo->iEntry[partitionCount].iPartitionLen      = (Int64) item.iSize;
   473             iPartitionInfo->iEntry[partitionCount].iPartitionLen      = (Int64) item.iSize;
   261             partitionCount++;
   474             partitionCount++;
   262             }
   475             }
   263         
   476         
   264 // SWAP Partition - Only 1        
   477 // SWAP Partition - Only 1        
   265         r = iTocPtr->GetItemByName(KTocSwap, item); 
   478         r = iTocPtr->GetItemByName(KTocSwap, item);
   266         if (KErrNone == r)
   479         if (KErrNone == r)
   267             {
   480             {
   268             __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD  :   ] (%11s) in TOC found : Start addr = 0x%X  Size = 0x%X", item.iFileName, item.iStart, item.iSize));
   481             __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD  :   ] (%11s) in TOC found : Start addr = 0x%X  Size = 0x%X", item.iFileName, item.iStart, item.iSize));
   269             iPartitionInfo->iEntry[partitionCount].iPartitionType     = KPartitionTypePagedData;           
   482             iPartitionInfo->iEntry[partitionCount].iPartitionType     = KPartitionTypePagedData;           
   270             iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart;                         
   483             iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart;                         
   281             Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[i]);
   494             Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[i]);
   282             Kern::Printf(" ");
   495             Kern::Printf(" ");
   283             }
   496             }
   284 #endif //__DEBUG_PARTITIONS_
   497 #endif //__DEBUG_PARTITIONS_
   285         
   498         
       
   499 		r = KErrNone;
   286         iCheckTOC = EFalse;
   500         iCheckTOC = EFalse;
   287 	    }
   501 	    }
   288 	else
   502 	else
   289 	    {
   503 	    {
   290         // Try utilising the BB5 partitioning scheme	
   504         // Try utilising the BB5 partitioning scheme	
   322                          (KPartitionTypeROM == partitionType) ||
   536                          (KPartitionTypeROM == partitionType) ||
   323                          (KPartitionTypePagedData == partitionType) ) )
   537                          (KPartitionTypePagedData == partitionType) ) )
   324                         {                   
   538                         {                   
   325                         iPartitionInfo->iEntry[partitionCount].iPartitionType	  = partitionType;
   539                         iPartitionInfo->iEntry[partitionCount].iPartitionType	  = partitionType;
   326                         iPartitionAttributes[partitionCount]                      = partitionTable->iPartitions[index].iPartition_attributes;
   540                         iPartitionAttributes[partitionCount]                      = partitionTable->iPartitions[index].iPartition_attributes;
       
   541 	                    static_cast<DMmcMediaDriverFlash *>(iDriver)->SetEMmcPartitionMapping(partitionCount, iSelectedPartition);
       
   542                         // ROM/ROFS partitions have a BB5 checksum header that must be offset for the Symbian OS.
       
   543 						const TUint32 KStartOffset = ((KPartitionTypeROM == partitionType) || (KPartitionTypeRofs == partitionType) || (KPartitionTypeEmpty == partitionType)) ? KBB5HeaderSizeInSectors : 0;
   327                         
   544                         
   328                         // ROM/ROFS partitions have a BB5 checksum header that must be offset for the Symbian OS.
   545                         iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = ((Int64) partitionTable->iPartitions[index].iStart_sector + KStartOffset) << KDiskSectorShift;
   329                         const TUint32 KstartOffset = ((KPartitionTypeROM == partitionType) || (KPartitionTypeRofs == partitionType) || (KPartitionTypeEmpty == partitionType)) ? KBB5HeaderSizeInSectors : 0;
   546                         iPartitionInfo->iEntry[partitionCount].iPartitionLen      = ((Int64) partitionTable->iPartitions[index].iSize - KStartOffset) << KDiskSectorShift;
   330                         
       
   331                         iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = ((Int64) partitionTable->iPartitions[index].iStart_sector + KstartOffset) << KDiskSectorShift;
       
   332                         iPartitionInfo->iEntry[partitionCount].iPartitionLen      = ((Int64) partitionTable->iPartitions[index].iSize - KstartOffset) << KDiskSectorShift;
       
   333         
   547         
   334                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount));
   548                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount));
   335                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount));
   549                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount));
   336                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector ));
   550                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector ));
   337                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift)));
   551                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift)));
   338                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize ));
   552                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize ));
   339                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift));
   553                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift));
   340                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType));
   554                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType));
   341                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount]));
   555                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount]));
       
   556 						__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionMapping.: 0x%x", static_cast<DMmcMediaDriverFlash *>(iDriver)->GetEMmcPartitionMapping(partitionCount)));
   342                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf(" "));
   557                     	__KTRACE_OPT(KPBUSDRV, Kern::Printf(" "));
   343         
   558         
   344                         partitionCount++;
   559                         partitionCount++;
   345                         }
   560                         }
   346                     }
   561                     }
   359 	
   574 	
   360 	// Validate partition address boundaries
   575 	// Validate partition address boundaries
   361 	if(partitionCount == 0)
   576 	if(partitionCount == 0)
   362 		{
   577 		{
   363 		__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: No supported partitions found!"));
   578 		__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: No supported partitions found!"));
   364 		return KErrCorrupt;
   579 		// No Supported partitions found on this physical partition
   365 		}
   580 		return KErrNone;
   366 #ifdef __DEBUG_CHECK_PARTITION_	
   581 		}
   367 	else
   582 		
   368 		{
   583 #ifdef __DEBUG_CHECK_PARTITION_			
   369 		// at least one entry for a supported partition found
   584 	// Validate partition address boundaries
   370 		const TInt64 deviceSize = iCard->DeviceSize64();
   585 	TUint32 eMmcPartitionSizeInSectors = 0;
       
   586 	if(r == KErrNone)
       
   587 		{
       
   588 		// At least one entry for a supported partition found
       
   589 		r = GetPartitionSizeInSectors(iSelectedPartition, eMmcPartitionSizeInSectors);
       
   590 		
       
   591 		if(r != KErrNone)
       
   592 			{
       
   593 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Could not retrieve size for eMMC partition 0x%02X", iSelectedPartition));
       
   594 			r = KErrCorrupt;
       
   595 			}
       
   596 		}
       
   597 		
       
   598 	if(r == KErrNone)
       
   599 		{
       
   600 		TUint64 eMmcPartitionSize = eMmcPartitionSizeInSectors * KSectorSize;
       
   601 		
   371 		TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1];
   602 		TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1];
   372 
   603 	
   373 		// Check that the card address space boundary is not exceeded by the last partition
   604 		// Check that the eMmcPartition address space boundary is not exceeded by the last partition
   374 		if(part.iPartitionBaseAddr + part.iPartitionLen > deviceSize)
   605 		if(part.iPartitionBaseAddr + part.iPartitionLen > eMmcPartitionSize)
   375 			{
   606 			{
   376 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: MBR partition exceeds card memory space"));
   607 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Partition #%d exceeds eMmc address space", partitionCount));
   377 			return KErrCorrupt;
   608 			r = KErrCorrupt;
   378 			}
   609 			}
   379 
   610 		}
   380 		// Go through all partition entries and check boundaries
   611 		
   381 		for(TInt i = partitionCount - 1; i > 0; i--)
   612 	if(r == KErrNone)
       
   613 		{
       
   614 		// Go through all BB5 partition entries on this eMMC partition and check boundaries
       
   615 		for(TInt i = partitionCount - 1; i > iPartitionInfo->iPartitionCount; i--)
   382 			{
   616 			{
   383 			const TPartitionEntry& curr = iPartitionInfo->iEntry[i];
   617 			const TPartitionEntry& curr = iPartitionInfo->iEntry[i];
   384 			TPartitionEntry& prev = iPartitionInfo->iEntry[i-1];
   618 			TPartitionEntry& prev = iPartitionInfo->iEntry[i-1];
   385 
   619 
   386 			// Check if partitions overlap
   620 			// Check if partitions overlap
   387 			if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen))
   621 			if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen))
   388 				{
   622 				{
   389 				__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Overlapping partitions - check #%d", i));
   623 				__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Overlapping partitions - check #%d", i));
   390 				return KErrCorrupt;
   624 				r = KErrCorrupt;
   391 				}
   625 				}
   392 			}
   626 			}
   393 		}
   627 		}
   394 #endif // _DEBUG_CHECK_PARTITION_
   628 #endif // _DEBUG_CHECK_PARTITION_
   395 
   629 		
   396 	iPartitionInfo->iPartitionCount = partitionCount;
   630 	if(r == KErrNone)
   397 	iPartitionInfo->iMediaSizeInBytes = iCard->DeviceSize64();
   631 		{
   398 
   632 		iPartitionInfo->iPartitionCount = partitionCount;
   399 	//Notify medmmc that partitioninfo is complete.
   633 		iPartitionInfo->iMediaSizeInBytes = iCard->DeviceSize64();
   400 	iCallBack.CallBack();
   634 		}
   401 
   635 
   402 	__KTRACE_OPT(KPBUSDRV, Kern::Printf("<Mmc:PartitionInfo (C:%d)", partitionCount));
   636 	__KTRACE_OPT(KPBUSDRV, Kern::Printf("<Mmc:PartitionInfo (C:%d)", partitionCount));
       
   637 	return r;
       
   638 	}
       
   639 
       
   640 
       
   641 // End - DBB5PartitionInfo
       
   642 
       
   643 
       
   644 EXPORT_C DEMMCPartitionInfo* CreateEmmcPartitionInfo()
       
   645 	{
       
   646 	return new DBB5PartitionInfo;
       
   647 	}
       
   648 
       
   649 DECLARE_STANDARD_EXTENSION()
       
   650 	{
   403 	return KErrNone;
   651 	return KErrNone;
   404 	}
   652 	}
   405 
   653 
   406 
       
   407 // End - DBB5PartitionInfo
       
   408 
       
   409 
       
   410 EXPORT_C DEMMCPartitionInfo* CreateEmmcPartitionInfo()
       
   411 	{
       
   412 	return new DBB5PartitionInfo;
       
   413 	}
       
   414 
       
   415 DECLARE_STANDARD_EXTENSION()
       
   416 	{
       
   417 	return KErrNone;
       
   418 	}
       
   419 
       
   420 //	End of File
   654 //	End of File
   421 
   655