kernel/eka/drivers/medmmc/emmcptn.cpp
changeset 47 46fffbe7b5a7
parent 44 36bfc973b146
equal deleted inserted replaced
46:0bf4040442f9 47:46fffbe7b5a7
    14 // Partition Management for Embedded MMC devices
    14 // Partition Management for Embedded MMC devices
    15 // 
    15 // 
    16 //
    16 //
    17 
    17 
    18 #include <drivers/emmcptn.h>
    18 #include <drivers/emmcptn.h>
       
    19 #include "OstTraceDefinitions.h"
       
    20 #ifdef OST_TRACE_COMPILER_IN_USE
       
    21 #include "locmedia_ost.h"
       
    22 #ifdef __VC32__
       
    23 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
       
    24 #endif
       
    25 #include "emmcptnTraces.h"
       
    26 #endif
       
    27 
    19 
    28 
    20 const TInt KDiskSectorShift=9;
    29 const TInt KDiskSectorShift=9;
    21 
    30 
    22 class DLegacyEMMCPartitionInfo : public DEMMCPartitionInfo
    31 class DLegacyEMMCPartitionInfo : public DEMMCPartitionInfo
    23 	{
    32 	{
    48 	};
    57 	};
    49 
    58 
    50 DLegacyEMMCPartitionInfo::DLegacyEMMCPartitionInfo()
    59 DLegacyEMMCPartitionInfo::DLegacyEMMCPartitionInfo()
    51   : iSessionEndCallBack(DLegacyEMMCPartitionInfo::SessionEndCallBack, this)
    60   : iSessionEndCallBack(DLegacyEMMCPartitionInfo::SessionEndCallBack, this)
    52 	{
    61 	{
       
    62 	OstTraceFunctionEntry0( DLEGACYEMMCPARTITIONINFO_DLEGACYEMMCPARTITIONINFO_ENTRY );
    53 	}
    63 	}
    54 
    64 
    55 DLegacyEMMCPartitionInfo::~DLegacyEMMCPartitionInfo()
    65 DLegacyEMMCPartitionInfo::~DLegacyEMMCPartitionInfo()
    56 	{
    66 	{
       
    67 	OstTraceFunctionEntry0( DLEGACYEMMCPARTITIONINFO_DESTRUCTOR_ENTRY );
    57 	delete iSession;
    68 	delete iSession;
       
    69 	OstTraceFunctionExit0( DLEGACYEMMCPARTITIONINFO_DESTRUCTOR_EXIT );
    58 	}
    70 	}
    59 
    71 
    60 TInt DLegacyEMMCPartitionInfo::Initialise(DMediaDriver* aDriver)
    72 TInt DLegacyEMMCPartitionInfo::Initialise(DMediaDriver* aDriver)
    61 	{
    73 	{
       
    74 	OstTraceFunctionEntry1( DLEGACYEMMCPARTITIONINFO_INITIALISE_ENTRY, this );
    62 	iDriver = aDriver;
    75 	iDriver = aDriver;
    63 
    76 
    64 	DMMCSocket* socket = ((DMMCSocket*)((DPBusPrimaryMedia*)(iDriver->iPrimaryMedia))->iSocket);
    77 	DMMCSocket* socket = ((DMMCSocket*)((DPBusPrimaryMedia*)(iDriver->iPrimaryMedia))->iSocket);
    65 	if(socket == NULL)
    78 	if(socket == NULL)
    66 		return(KErrNoMemory);
    79 	    {
       
    80 		OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_INITIALISE_EXIT1, this, KErrNoMemory );
       
    81 		return KErrNoMemory;
       
    82 	    }
    67 
    83 
    68 	DMMCStack* stack = socket->Stack(0);
    84 	DMMCStack* stack = socket->Stack(0);
    69 	iCard = stack->CardP(((DPBusPrimaryMedia*)(iDriver->iPrimaryMedia))->iSlotNumber);
    85 	iCard = stack->CardP(((DPBusPrimaryMedia*)(iDriver->iPrimaryMedia))->iSlotNumber);
    70 	
    86 	
    71 	iSession = stack->AllocSession(iSessionEndCallBack);
    87 	iSession = stack->AllocSession(iSessionEndCallBack);
    72 	if (iSession == NULL)
    88 	if (iSession == NULL)
    73 		return(KErrNoMemory);
    89 		return KErrNoMemory;
    74 
    90 
    75 	iSession->SetStack(stack);
    91 	iSession->SetStack(stack);
    76 	iSession->SetCard(iCard);
    92 	iSession->SetCard(iCard);
    77 
    93 
    78 	// this gets used before any access
    94 	// this gets used before any access
    79 	TInt bufLen, minorBufLen;
    95 	TInt bufLen, minorBufLen;
    80 	stack->BufferInfo(iIntBuf, bufLen, minorBufLen);
    96 	stack->BufferInfo(iIntBuf, bufLen, minorBufLen);
    81 
    97 
    82 	return(KErrNone);
    98 	OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_INITIALISE_EXIT2, this, KErrNone );
       
    99 	return KErrNone;
    83 	}
   100 	}
    84 
   101 
    85 TInt DLegacyEMMCPartitionInfo::PartitionInfo(TPartitionInfo& anInfo, const TMMCCallBack& aCallBack)
   102 TInt DLegacyEMMCPartitionInfo::PartitionInfo(TPartitionInfo& anInfo, const TMMCCallBack& aCallBack)
    86 	{
   103 	{
       
   104 	OstTraceFunctionEntry1( DLEGACYEMMCPARTITIONINFO_PARTITIONINFO_ENTRY, this );
    87 	iPartitionInfo = &anInfo;
   105 	iPartitionInfo = &anInfo;
    88 	iCallBack = aCallBack;
   106 	iCallBack = aCallBack;
    89 	// If media driver is persistent (see EMediaDriverPersistent), 
   107 	// If media driver is persistent (see EMediaDriverPersistent), 
    90 	// the card may have changed since last power down, so reset CID
   108 	// the card may have changed since last power down, so reset CID
    91 	iSession->SetCard(iCard);
   109 	iSession->SetCard(iCard);
    97 		r = iSession->Engage();
   115 		r = iSession->Engage();
    98 
   116 
    99 	if(r != KErrNone)
   117 	if(r != KErrNone)
   100 		iDriver->EndInCritical();
   118 		iDriver->EndInCritical();
   101 	
   119 	
   102 	return(r);
   120 	OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_PARTITIONINFO_EXIT, this, r );
       
   121 	return r;
   103 	}
   122 	}
   104 
   123 
   105 TInt DLegacyEMMCPartitionInfo::PartitionCaps(TLocDrv& aDrive, TDes8& aInfo)
   124 TInt DLegacyEMMCPartitionInfo::PartitionCaps(TLocDrv& aDrive, TDes8& aInfo)
   106 	{
   125 	{
       
   126 	 OstTraceFunctionEntry1( DLEGACYEMMCPARTITIONINFO_PARTITIONCAPS_ENTRY, this );
   107 	 TLocalDriveCapsV6Buf& Info = static_cast< TLocalDriveCapsV6Buf&> (aInfo);
   127 	 TLocalDriveCapsV6Buf& Info = static_cast< TLocalDriveCapsV6Buf&> (aInfo);
   108 	
   128 	
   109 	// is this query for the swap partition ?
   129 	// is this query for the swap partition ?
   110 	if (aDrive.iPartitionType == KPartitionTypePagedData)
   130 	if (aDrive.iPartitionType == KPartitionTypePagedData)
   111 		{
   131 		{
   127 		Info().iFileSystemId = KDriveFileNone;
   147 		Info().iFileSystemId = KDriveFileNone;
   128 		Info().iMediaAtt&= ~KMediaAttFormattable;
   148 		Info().iMediaAtt&= ~KMediaAttFormattable;
   129 		Info().iMediaAtt|= KMediaAttWriteProtected;
   149 		Info().iMediaAtt|= KMediaAttWriteProtected;
   130 		}
   150 		}
   131 	
   151 	
       
   152 	OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_PARTITIONCAPS_EXIT, this, KErrNone );
   132 	return KErrNone;
   153 	return KErrNone;
   133 	}
   154 	}
   134 
   155 
   135 void DLegacyEMMCPartitionInfo::SessionEndCallBack(TAny* aSelf)
   156 void DLegacyEMMCPartitionInfo::SessionEndCallBack(TAny* aSelf)
   136 	{
   157 	{
       
   158 	OstTraceFunctionEntry0( DLEGACYEMMCPARTITIONINFO_SESSIONENDCALLBACK_ENTRY );
   137 	DLegacyEMMCPartitionInfo& self = *static_cast<DLegacyEMMCPartitionInfo*>(aSelf);
   159 	DLegacyEMMCPartitionInfo& self = *static_cast<DLegacyEMMCPartitionInfo*>(aSelf);
   138 	self.DoSessionEndCallBack();
   160 	self.DoSessionEndCallBack();
       
   161 	OstTraceFunctionExit0( DLEGACYEMMCPARTITIONINFO_SESSIONENDCALLBACK_EXIT );
   139 	}
   162 	}
   140 
   163 
   141 void DLegacyEMMCPartitionInfo::DoSessionEndCallBack()
   164 void DLegacyEMMCPartitionInfo::DoSessionEndCallBack()
   142 	{
   165 	{
       
   166 	OstTraceFunctionEntry1( DLEGACYEMMCPARTITIONINFO_DOSESSIONENDCALLBACK_ENTRY, this );
   143 	iDriver->EndInCritical();
   167 	iDriver->EndInCritical();
   144 
   168 
   145 	TInt r = iSession->EpocErrorCode();
   169 	TInt r = iSession->EpocErrorCode();
   146 
   170 
   147 	if (r == KErrNone)
   171 	if (r == KErrNone)
   148 		r = DecodePartitionInfo();
   172 		r = DecodePartitionInfo();
   149 
   173 
   150 	iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady);
   174 	iDriver->PartitionInfoComplete(r == KErrNone ? r : KErrNotReady);
       
   175 	OstTraceFunctionExit1( DLEGACYEMMCPARTITIONINFO_DOSESSIONENDCALLBACK_EXIT, this );
   151 	}
   176 	}
   152 
   177 
   153 TInt DLegacyEMMCPartitionInfo::DecodePartitionInfo()
   178 TInt DLegacyEMMCPartitionInfo::DecodePartitionInfo()
   154 //
   179 //
   155 // decode partition info that was read into internal buffer 
   180 // decode partition info that was read into internal buffer 
   156 //
   181 //
   157 	{
   182 	{
       
   183 	OstTraceFunctionEntry1( DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_ENTRY, this );
   158 	TUint partitionCount=iPartitionInfo->iPartitionCount=0;
   184 	TUint partitionCount=iPartitionInfo->iPartitionCount=0;
   159 	TInt defaultPartitionNumber=-1;
   185 	TInt defaultPartitionNumber=-1;
   160 	TMBRPartitionEntry* pe;
   186 	TMBRPartitionEntry* pe;
   161 	const TUint KMBRFirstPartitionOffsetAligned = KMBRFirstPartitionOffset & ~3;
   187 	const TUint KMBRFirstPartitionOffsetAligned = KMBRFirstPartitionOffset & ~3;
   162 	TInt i;
   188 	TInt i;
   163 
   189 
   164 	// Read of the first sector successful so check for a Master Boot Record
   190 	// Read of the first sector successful so check for a Master Boot Record
   165 	if (*(TUint16*)(&iIntBuf[KMBRSignatureOffset])!=0xAA55)
   191 	if (*(TUint16*)(&iIntBuf[KMBRSignatureOffset])!=0xAA55)
       
   192 	    {
   166 		// If no valid signature give up now, No way to re-format an internal drive correctly
   193 		// If no valid signature give up now, No way to re-format an internal drive correctly
       
   194 		OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_EXIT1, this, KErrCorrupt );
   167 		return KErrCorrupt;
   195 		return KErrCorrupt;
       
   196 	    }
   168 
   197 
   169 	__ASSERT_COMPILE(KMBRFirstPartitionOffsetAligned + KMBRMaxPrimaryPartitions * sizeof(TMBRPartitionEntry) <= KMBRSignatureOffset);
   198 	__ASSERT_COMPILE(KMBRFirstPartitionOffsetAligned + KMBRMaxPrimaryPartitions * sizeof(TMBRPartitionEntry) <= KMBRSignatureOffset);
   170 
   199 
   171 	memmove(&iIntBuf[0], &iIntBuf[2],
   200 	memmove(&iIntBuf[0], &iIntBuf[2],
   172 		KMBRFirstPartitionOffsetAligned + KMBRMaxPrimaryPartitions * sizeof(TMBRPartitionEntry)); 
   201 		KMBRFirstPartitionOffsetAligned + KMBRMaxPrimaryPartitions * sizeof(TMBRPartitionEntry)); 
   196 		// FAT partition ?
   225 		// FAT partition ?
   197 		else if (pe->IsValidDosPartition() || pe->IsValidFAT32Partition() || pe->IsValidExFATPartition())
   226 		else if (pe->IsValidDosPartition() || pe->IsValidFAT32Partition() || pe->IsValidExFATPartition())
   198 			{
   227 			{
   199 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   228 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   200 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: FAT partition found at sector #%u", pe->iFirstSector));
   229 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: FAT partition found at sector #%u", pe->iFirstSector));
       
   230 			OstTrace1(TRACE_INTERNALS, DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_FAT, "FAT partition found at sector #%x", pe->iFirstSector);
   201 			partitionCount++;
   231 			partitionCount++;
   202 			}
   232 			}
   203 
   233 
   204 		else if (pe->iPartitionType == KPartitionTypeROM)
   234 		else if (pe->iPartitionType == KPartitionTypeROM)
   205 			{
   235 			{
   207 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   237 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   208 			partitionEntry.iPartitionType = pe->iPartitionType;
   238 			partitionEntry.iPartitionType = pe->iPartitionType;
   209 			partitionCount++;				 
   239 			partitionCount++;				 
   210 
   240 
   211 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: KPartitionTypeROM found at sector #%u", pe->iFirstSector));
   241 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: KPartitionTypeROM found at sector #%u", pe->iFirstSector));
       
   242 			OstTrace1(TRACE_INTERNALS, DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_ROM, "KPartitionTypeROM found at sector #%x", pe->iFirstSector);
   212 			}
   243 			}
   213 
   244 
   214 		// ROFS partition ?
   245 		// ROFS partition ?
   215 		else if (pe->iPartitionType == KPartitionTypeRofs)
   246 		else if (pe->iPartitionType == KPartitionTypeRofs)
   216 			{
   247 			{
   218 // Don't expose this for normal operation only boot?			
   249 // Don't expose this for normal operation only boot?			
   219 			TPartitionEntry& partitionEntry = iPartitionInfo->iEntry[partitionCount];
   250 			TPartitionEntry& partitionEntry = iPartitionInfo->iEntry[partitionCount];
   220 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   251 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   221 			partitionEntry.iPartitionType = pe->iPartitionType;
   252 			partitionEntry.iPartitionType = pe->iPartitionType;
   222 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: KPartitionTypeRofs found at sector #%u", pe->iFirstSector));
   253 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: KPartitionTypeRofs found at sector #%u", pe->iFirstSector));
       
   254 			OstTrace1(TRACE_INTERNALS, DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_ROFS, "KPartitionTypeRofs found at sector #%x", pe->iFirstSector);
   223 			partitionCount++;
   255 			partitionCount++;
   224 			}
   256 			}
   225  
   257  
   226 		// Swap partition ?
   258 		// Swap partition ?
   227 		else if (pe->iPartitionType == KPartitionTypePagedData)
   259 		else if (pe->iPartitionType == KPartitionTypePagedData)
   228 			{
   260 			{
   229 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: KPartitionTypePagedData found at sector #%u", pe->iFirstSector));
   261 			__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: KPartitionTypePagedData found at sector #%u", pe->iFirstSector));
   230 
   262 			OstTrace1(TRACE_INTERNALS, DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_PAGED, "KPartitionTypeRofs found at sector #%x", pe->iFirstSector);
   231 			TPartitionEntry& partitionEntry = iPartitionInfo->iEntry[partitionCount];
   263 			TPartitionEntry& partitionEntry = iPartitionInfo->iEntry[partitionCount];
   232 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   264 			SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors);
   233 			partitionEntry.iPartitionType = pe->iPartitionType;
   265 			partitionEntry.iPartitionType = pe->iPartitionType;
   234 			partitionCount++;
   266 			partitionCount++;
   235 			}
   267 			}
   243 		TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1];
   275 		TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1];
   244 		// Check that the card address space boundary is not exceeded by the last partition
   276 		// Check that the card address space boundary is not exceeded by the last partition
   245 		if(part.iPartitionBaseAddr + part.iPartitionLen > deviceSize)
   277 		if(part.iPartitionBaseAddr + part.iPartitionLen > deviceSize)
   246 			{
   278 			{
   247 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: MBR partition exceeds card memory space"));
   279 			__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: MBR partition exceeds card memory space"));
       
   280 			OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_EXIT2, this, KErrCorrupt );
   248 			return KErrCorrupt;
   281 			return KErrCorrupt;
   249 			}
   282 			}
   250 		
   283 		
   251 		// More than one partition. Go through all of them
   284 		// More than one partition. Go through all of them
   252 		if (partitionCount > 0)
   285 		if (partitionCount > 0)
   257 				TPartitionEntry& prev = iPartitionInfo->iEntry[i-1];
   290 				TPartitionEntry& prev = iPartitionInfo->iEntry[i-1];
   258 				// Check if partitions overlap
   291 				// Check if partitions overlap
   259 				if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen))
   292 				if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen))
   260 					{
   293 					{
   261 					__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Overlapping partitions"));
   294 					__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Overlapping partitions"));
       
   295 					OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_EXIT3, this, KErrCorrupt );
   262 					return KErrCorrupt;
   296 					return KErrCorrupt;
   263 					}
   297 					}
   264 				}
   298 				}
   265 			}
   299 			}
   266 		}
   300 		}
   267 
   301 
   268 	if (defaultPartitionNumber==(-1) && partitionCount==0)
   302 	if (defaultPartitionNumber==(-1) && partitionCount==0)
   269 		{
   303 		{
   270 		__KTRACE_OPT(KPBUSDRV, Kern::Printf("No Valid Partitions Found!"));
   304 		__KTRACE_OPT(KPBUSDRV, Kern::Printf("No Valid Partitions Found!"));
       
   305 		OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_EXIT4, this, KErrCorrupt );
   271 		return KErrCorrupt;
   306 		return KErrCorrupt;
   272 		}
   307 		}
   273 
   308 
   274 	iPartitionInfo->iPartitionCount=partitionCount;
   309 	iPartitionInfo->iPartitionCount=partitionCount;
   275 	iPartitionInfo->iMediaSizeInBytes=iCard->DeviceSize64();
   310 	iPartitionInfo->iMediaSizeInBytes=iCard->DeviceSize64();
   281 #endif
   316 #endif
   282 
   317 
   283 	//Notify medmmc that partitioninfo is complete.
   318 	//Notify medmmc that partitioninfo is complete.
   284 	iCallBack.CallBack();
   319 	iCallBack.CallBack();
   285 	
   320 	
   286 	return(KErrNone);
   321 	OstTraceFunctionExitExt( DLEGACYEMMCPARTITIONINFO_DECODEPARTITIONINFO_EXIT5, this, KErrNone );
       
   322 	return KErrNone;
   287 	}
   323 	}
   288 
   324 
   289 
   325 
   290 void DLegacyEMMCPartitionInfo::SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors)
   326 void DLegacyEMMCPartitionInfo::SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors)
   291 //
   327 //
   292 // auxiliary static function to record partition information in TPartitionEntry object
   328 // auxiliary static function to record partition information in TPartitionEntry object
   293 //
   329 //
   294 	{
   330 	{
       
   331 	OstTraceFunctionEntryExt( DLEGACYEMMCPARTITIONINFO_SETPARTITIONENTRY_ENTRY, this );
   295 	aEntry->iPartitionBaseAddr=aFirstSector;
   332 	aEntry->iPartitionBaseAddr=aFirstSector;
   296 	aEntry->iPartitionBaseAddr<<=KDiskSectorShift;
   333 	aEntry->iPartitionBaseAddr<<=KDiskSectorShift;
   297 	aEntry->iPartitionLen=aNumSectors;
   334 	aEntry->iPartitionLen=aNumSectors;
   298 	aEntry->iPartitionLen<<=KDiskSectorShift;
   335 	aEntry->iPartitionLen<<=KDiskSectorShift;
   299 	aEntry->iPartitionType=KPartitionTypeFAT12;
   336 	aEntry->iPartitionType=KPartitionTypeFAT12;
       
   337 	OstTraceFunctionExit1( DLEGACYEMMCPARTITIONINFO_SETPARTITIONENTRY_EXIT, this );
   300 	}
   338 	}
   301 
   339 
   302 // End - DLegacyEMMCPartitionInfo
   340 // End - DLegacyEMMCPartitionInfo
   303 
   341 
   304 
   342 
   305 EXPORT_C DEMMCPartitionInfo* CreateEmmcPartitionInfo()
   343 EXPORT_C DEMMCPartitionInfo* CreateEmmcPartitionInfo()
   306 	{
   344 	{
       
   345 	OstTraceFunctionEntry0( _CREATEEMMCPARTITIONINFO_ENTRY );
   307 	return new DLegacyEMMCPartitionInfo;
   346 	return new DLegacyEMMCPartitionInfo;
   308 	}
   347 	}
   309 
   348 
   310 DECLARE_STANDARD_EXTENSION()
   349 DECLARE_STANDARD_EXTENSION()
   311 	{
   350 	{