kerneltest/e32test/pccd/t_mmcdrv.cpp
changeset 0 a41df078684a
child 6 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1996-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 // e32test\pccd\t_mmcdrv.cpp
       
    15 // Test the MultiMediaCard (MMC) media driver
       
    16 // Spare Test case Numbers 0513-0519
       
    17 // 
       
    18 //
       
    19 
       
    20 #include "../mmu/d_sharedchunk.h"
       
    21 #include <e32test.h>
       
    22 #include <e32svr.h>
       
    23 #include <e32hal.h>
       
    24 #include <e32uid.h>
       
    25 #include <f32fsys.h>
       
    26 #include <e32def.h>
       
    27 #include <e32def_private.h>
       
    28 
       
    29 const TInt KDiskSectorSize=512;
       
    30 const TInt KDiskSectorShift=9;
       
    31 const TUint KDiskSectorMask=0xFFFFFE00;
       
    32 const TInt KSectBufSizeInSectors=8;
       
    33 const TInt KSectBufSizeInBytes=(KSectBufSizeInSectors<<KDiskSectorShift);
       
    34 const TInt KRdWrBufLen=(KSectBufSizeInBytes+KDiskSectorSize); // 4.5K - exceeds driver local buffer size
       
    35 
       
    36 const TInt KShortFormatInSectors=1;
       
    37 const TInt KShortFormatInBytes=(KShortFormatInSectors<<KDiskSectorShift);
       
    38 const TInt KLongFormatInSectors=KSectBufSizeInSectors+1;	// 4.5K - exceeds driver local buffer size
       
    39 const TInt KLongFormatInBytes=(KLongFormatInSectors<<KDiskSectorShift);
       
    40 
       
    41 const TInt KVeryLongSectBufSizeInSectors=4096;												// ..2M
       
    42 const TInt KVeryLongSectBufSizeInBytes=(KVeryLongSectBufSizeInSectors<<KDiskSectorShift);	//
       
    43 const TInt KVeryLongRdWrBufLen=(KVeryLongSectBufSizeInBytes+KDiskSectorSize);				// 2M + 0.5K
       
    44 
       
    45 const TInt KHeapSize=0x4000;
       
    46 
       
    47 const TInt64 KDefaultRandSeed = MAKE_TINT64(0x501a501a, 0x501a501a);
       
    48 
       
    49 #define TEST_DOOR_CLOSE 	0					// see comment in E32Main()
       
    50 
       
    51 
       
    52 class TMMCDrive : public TBusLocalDrive
       
    53 	{
       
    54 public:
       
    55 	enum TTestMode
       
    56 		{
       
    57 		ETestPartition,
       
    58 		ETestWholeMedia,
       
    59 		ETestSharedMemory,
       
    60 		ETestSharedMemoryCache,
       
    61 		ETestSharedMemoryFrag,
       
    62 		ETestSharedMemoryFragCache,
       
    63 		EMaxTestModes
       
    64 		};
       
    65 public:
       
    66 	TMMCDrive();
       
    67 	
       
    68 	TInt Read(TInt64 aPos, TInt aLength, TDes8& aTrg);
       
    69 	TInt Write(TInt64 aPos, const TDesC8& aSrc);
       
    70 
       
    71 	TInt SetTestMode(TTestMode aTestMode);
       
    72 	TTestMode TestMode();
       
    73 
       
    74 	void SetSize(TInt64 aDriveSize, TInt64 aMediaSize);
       
    75 	TInt64 Size();
       
    76 private:
       
    77 	TTestMode iTestMode;
       
    78 
       
    79 	TInt64 iDriveSize;
       
    80 	TInt64 iMediaSize;
       
    81 	};
       
    82 
       
    83 // Serial numbers for 'special case' test cards (ie - those with known problems)
       
    84 class TKnownCardTypes
       
    85 	{
       
    86 public:
       
    87 	enum TCardType
       
    88 		{
       
    89 		EStandardCard = 0,
       
    90 		EBuffalloMiniSD_32M_ERASE,
       
    91 		EBuffalloMiniSD_64M_ERASE,
       
    92 		EBuffalloMiniSD_128M_ERASE,
       
    93 		EBuffalloMiniSD_256M_ERASE,
       
    94 		EBuffalloMiniSD_512M_ERASE,
       
    95 		EBuffalloMiniSD_512M,
       
    96 		EIntegralHSSD_2G,
       
    97 		ESanDiskMmcMobile_1GB
       
    98 		};
       
    99 
       
   100 	TKnownCardTypes(TCardType aCardType, const TText8* aSerialNumber) 
       
   101 		: iCardType(aCardType), iSerialNumber(aSerialNumber) {};
       
   102 
       
   103 	TCardType iCardType;
       
   104 	const TText8* iSerialNumber;
       
   105 	};
       
   106 
       
   107 LOCAL_D TKnownCardTypes KnownCardTypes[] = 	
       
   108 	{
       
   109 	//** The Following Buffalo Cards all have a known Mis-Implementation
       
   110 	// When requesting Erase the area to be erase is specified in terms of a start (CMD32) and stop (CMD33) blocks
       
   111 	// Specification states that CMD33 refers to the end block in terms of the first byte of that block
       
   112 	// the Buffallo implementation requires that the last byte of the block is specified.
       
   113 	
       
   114 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_32M_ERASE,  _S8("936300c70e150d003630333046445004")),
       
   115 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_64M_ERASE,  _S8("d96600456d120a003732343046445004")),
       
   116 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_128M_ERASE, _S8("f964000d13150c003630333046445004")),
       
   117 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_256M_ERASE, _S8("4d66004c68120a003732343046445004")),
       
   118 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M_ERASE, _S8("db6500824e0010013236333243454228")),
       
   119 	
       
   120 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_32M_ERASE,  _S8("df6400e60d150d003630333046445004")),
       
   121 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_64M_ERASE,  _S8("296600386d120a003732343046445004")),
       
   122 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_128M_ERASE, _S8("b16400f512150c003630333046445004")),
       
   123 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_256M_ERASE, _S8("435600cc390000000000004453474b13")),
       
   124 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M_ERASE, _S8("ed6300de700000000000004453474b13")),
       
   125 	//***********************************************************************************************//
       
   126 	
       
   127 	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M, _S8("0d56004e2d0000000000004453474b13")),
       
   128 	TKnownCardTypes(TKnownCardTypes::EIntegralHSSD_2G,     _S8("37570058073099114732304453000027")),
       
   129 	TKnownCardTypes(TKnownCardTypes::ESanDiskMmcMobile_1GB,_S8("956a1c00001810303030303030000015"))
       
   130 	};
       
   131 
       
   132 
       
   133 LOCAL_D RTest test(_L("T_MMCDRV"));
       
   134 LOCAL_D RTest nTest(_L("This thread doesn't disconnect"));
       
   135 LOCAL_D TBool ChangeFlag;
       
   136 LOCAL_D TBool SecThreadChangeFlag;
       
   137 
       
   138 
       
   139 LOCAL_D TPtr8 wrBuf(NULL, KVeryLongRdWrBufLen);
       
   140 LOCAL_D TPtr8 rdBuf(NULL, KVeryLongRdWrBufLen);
       
   141 LOCAL_D HBufC8* wrBufH = NULL;
       
   142 LOCAL_D HBufC8* rdBufH = NULL;
       
   143 
       
   144 LOCAL_D TInt DriveNumber = -1; // Local Drive number
       
   145 LOCAL_D TInt RFsDNum = -1;	// File Server Drive number
       
   146 LOCAL_D TMMCDrive TheMmcDrive;
       
   147 LOCAL_D TLocalDriveCapsV5Buf DriveCaps;
       
   148 LOCAL_D TKnownCardTypes::TCardType CardType;
       
   149 LOCAL_D TBool IsReadOnly;
       
   150 
       
   151 LOCAL_D RSharedChunkLdd Ldd;
       
   152 LOCAL_D RChunk TheChunk;
       
   153 LOCAL_D TInt PageSize;
       
   154 const TUint ChunkSize    = 0x201000;	//2MB+4096bytes > than largest transfer
       
   155 
       
   156 const TInt	 KSingSectorNo=1;
       
   157 const TInt64 KTwoGigbytes = 0x80000000;
       
   158 
       
   159 TBool mediaChangeSupported=EFalse; // ???
       
   160 TBool ManualMode=EFalse;
       
   161 
       
   162 // Wrappers for the test asserts
       
   163 GLREF_C void TestIfError( TInt aValue, TInt aLine, const TText* aFile );
       
   164 GLREF_C void TestIfErrorMsg( TInt aValue, TInt aLine, const TText* aFile, const TDesC& aMessageOnError );
       
   165 GLREF_C void TestEqual( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile );
       
   166 GLREF_C void TestEqualMsg( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile, const TDesC& aMessageOnError );
       
   167 GLREF_C void TestEitherEqual( TInt aValue, TInt aExpected1, TInt aExpected2, TInt aLine, const TText* aFile );
       
   168 GLREF_C void TestRange( TInt aValue, TInt aMin, TInt Max, TInt aLine, const TText* aFile );
       
   169 
       
   170 #define TEST_FOR_ERROR2( r, l, f )	TestIfError( r, l, _S(f) )
       
   171 #define TEST_FOR_ERROR_ERRMSG2( r, l, f, m )	TestIfErrorMsg( r, l, _S(f), m )
       
   172 #define TEST_FOR_VALUE2( r, e, l, f )	TestEqual( r, e, l, _S(f) )
       
   173 #define TEST_FOR_VALUE_ERRMSG2( r, e, l, f, m )	TestEqualMsg( r, e, l, _S(f), m )
       
   174 #define TEST_FOR_EITHER_VALUE2( r, e1, e2, l, f )	TestEitherEqual( r, e1, e2, l, _S(f) )
       
   175 #define TEST_FOR_RANGE2( r, min, max, l, f )	TestRange( r, min, max, l, _S(f) )
       
   176 
       
   177 #define TEST_FOR_ERROR( r )	TEST_FOR_ERROR2( r, __LINE__, __FILE__ )
       
   178 #define TEST_FOR_ERROR_ERRMSG( r, m )	TEST_FOR_ERRORMSG2( r, __LINE__, __FILE__, m )
       
   179 #define TEST_FOR_VALUE( r, expected )	TEST_FOR_VALUE2( r, expected, __LINE__, __FILE__ )
       
   180 #define TEST_FOR_VALUE_ERRMSG( r, expected, m )	TEST_FOR_VALUE_ERRMSG2( r, expected, __LINE__, __FILE__, m )
       
   181 #define TEST_FOR_EITHER_VALUE( r, expected1, expected2 )	TEST_FOR_EITHER_VALUE2( r, expected1, expected2, __LINE__, __FILE__ )
       
   182 #define TEST_FOR_RANGE( r, min, max )	TEST_FOR_RANGE2( r, min, max, __LINE__, __FILE__ )
       
   183 
       
   184 GLDEF_C void TestIfError( TInt aValue, TInt aLine, const TText* aFile )
       
   185 	{
       
   186 	if( aValue < 0 )
       
   187 		{
       
   188 		_LIT( KErrorTestFailMsg, "ERROR %d\n\r" );
       
   189 		test.Printf( KErrorTestFailMsg, aValue );
       
   190 		test.operator()( EFalse, aLine, (const TText*)(aFile) );
       
   191 		}
       
   192 	}
       
   193 
       
   194 GLDEF_C void TestIfErrorMsg( TInt aValue, TInt aLine, const TText* aFile, const TDesC& aMessageOnError )
       
   195 	{
       
   196 	if( aValue < 0 )
       
   197 		{
       
   198 		_LIT( KErrorTestFailMsg, "ERROR %d %S\n\r" );
       
   199 		test.Printf( KErrorTestFailMsg, aValue, &aMessageOnError );
       
   200 		test.operator()( EFalse, aLine, (const TText*)(aFile) );
       
   201 		}
       
   202 	}
       
   203 
       
   204 
       
   205 GLDEF_C void TestEqual( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile )
       
   206 	{
       
   207 	if( aExpected != aValue )
       
   208 		{
       
   209 		_LIT( KEqualTestFailMsg, "ERROR %d expected %d\n\r" );
       
   210 		test.Printf( KEqualTestFailMsg, aValue, aExpected );
       
   211 		test.operator()( EFalse, aLine, (const TText*)(aFile) );
       
   212 		}
       
   213 	}
       
   214 
       
   215 GLDEF_C void TestEqualMsg( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile, const TDesC& aMessageOnError )
       
   216 	{
       
   217 	if( aExpected != aValue )
       
   218 		{
       
   219 		_LIT( KEqualTestFailMsg, "ERROR %d expected %d %S\n\r" );
       
   220 		test.Printf( KEqualTestFailMsg, aValue, aExpected, &aMessageOnError );
       
   221 		test.operator()( EFalse, aLine, (const TText*)(aFile) );
       
   222 		}
       
   223 	}
       
   224 
       
   225 GLDEF_C void TestEitherEqual( TInt aValue, TInt aExpected1, TInt aExpected2, TInt aLine, const TText* aFile )
       
   226 	{
       
   227 	if( (aExpected1 != aValue) && (aExpected2 != aValue) )
       
   228 		{
       
   229 		_LIT( KEqualTestFailMsg, "ERROR %d expected %d or %d\n\r" );
       
   230 		test.Printf( KEqualTestFailMsg, aValue, aExpected1, aExpected2 );
       
   231 		test.operator()( EFalse, aLine, (const TText*)(aFile) );
       
   232 		}
       
   233 	}
       
   234 
       
   235 GLDEF_C void TestRange( TInt aValue, TInt aMin, TInt aMax, TInt aLine, const TText* aFile )
       
   236 	{
       
   237 	if( (aValue < aMin) || (aValue > aMax) )
       
   238 		{
       
   239 		_LIT( KRangeTestFailMsg, "ERROR 0x%x expected 0x%x..0x%x\n\r" );
       
   240 		test.Printf( KRangeTestFailMsg, aValue, aMin, aMax );
       
   241 		test.operator()( EFalse, aLine, (const TText*)(aFile) );
       
   242 		}
       
   243 	}
       
   244 
       
   245 ////
       
   246 
       
   247 TMMCDrive::TMMCDrive()
       
   248   : iTestMode(ETestPartition),
       
   249     iDriveSize(0),
       
   250     iMediaSize(0)
       
   251 	{
       
   252 	}
       
   253 
       
   254 TInt TMMCDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg)
       
   255 	{
       
   256 	if(iTestMode == ETestWholeMedia)
       
   257 		{
       
   258 		return TBusLocalDrive::Read(aPos, aLength, &aTrg, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
       
   259 		}
       
   260 	else if(iTestMode != ETestPartition && aLength <= (TInt)ChunkSize)
       
   261 		{
       
   262 		TPtr8 wholeBufPtr(TheChunk.Base(),aLength);
       
   263 	
       
   264 		TInt r = TBusLocalDrive::Read(aPos, aLength, wholeBufPtr);
       
   265 	
       
   266 		aTrg.Copy(wholeBufPtr);
       
   267 		return r;
       
   268 		}
       
   269 	
       
   270 	return TBusLocalDrive::Read(aPos, aLength, aTrg);
       
   271 	}
       
   272 
       
   273 TInt TMMCDrive::Write(TInt64 aPos,const TDesC8& aSrc)
       
   274 	{
       
   275 	if(iTestMode == ETestWholeMedia)
       
   276 		{
       
   277 		return TBusLocalDrive::Write(aPos, aSrc.Length(), &aSrc, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
       
   278 		}
       
   279 	else if(iTestMode != ETestPartition && aSrc.Length() <= (TInt)ChunkSize)
       
   280 		{		
       
   281 		TPtr8 wholeBufPtr(TheChunk.Base(),aSrc.Length());
       
   282 		wholeBufPtr.Copy(aSrc);
       
   283 	
       
   284 		TInt r = TBusLocalDrive::Write(aPos, wholeBufPtr);
       
   285 		
       
   286 		return r;
       
   287 		}
       
   288 		
       
   289 	return TBusLocalDrive::Write(aPos, aSrc);
       
   290 	}
       
   291 
       
   292 TInt TMMCDrive::SetTestMode(TTestMode aTestMode)
       
   293 	{
       
   294 	switch (aTestMode) 
       
   295 		{
       
   296 		case ETestWholeMedia   : 		test.Printf(_L("\nTesting Whole Media\n")); break;
       
   297 		case ETestPartition    : 		test.Printf(_L("\nTesting Partition\n")); break;
       
   298 		case ETestSharedMemory : 		test.Printf(_L("\nTesting Shared Memory\n")); break;
       
   299 		case ETestSharedMemoryCache : 	test.Printf(_L("\nTesting Shared Memory (Caching)\n")); break;
       
   300 		case ETestSharedMemoryFrag : 	test.Printf(_L("\nTesting Shared Memory (Fragmented)\n")); break;
       
   301 		default :           			test.Printf(_L("\nTesting Shared Memory (Fragmented/Caching)\n")); break;
       
   302 		}
       
   303 
       
   304 	if(aTestMode == ETestWholeMedia && iMediaSize == 0)
       
   305 		{
       
   306 		test.Printf(_L("...not supported"));
       
   307 		return KErrNotSupported;
       
   308 		}
       
   309 
       
   310 	iTestMode = aTestMode;
       
   311 	return KErrNone;
       
   312 	}
       
   313 
       
   314 TMMCDrive::TTestMode TMMCDrive::TestMode()
       
   315 	{
       
   316 	return iTestMode;
       
   317 	}
       
   318 
       
   319 void TMMCDrive::SetSize(TInt64 aDriveSize, TInt64 aMediaSize)
       
   320 	{
       
   321 	iDriveSize = aDriveSize;
       
   322 	iMediaSize = aMediaSize;
       
   323 	}
       
   324 
       
   325 TInt64 TMMCDrive::Size()
       
   326 	{
       
   327 	switch (iTestMode)
       
   328 		{
       
   329 		case ETestWholeMedia : return iMediaSize;
       
   330 		default 			 : return iDriveSize;
       
   331 		}
       
   332 	}
       
   333 
       
   334 //////
       
   335 
       
   336 GLDEF_C void DumpBuffer( const TDesC8& aBuffer )
       
   337 	/**
       
   338 	 * Dump the content of aBuffer in hex
       
   339 	 */
       
   340 	{
       
   341 	static const TText hextab[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
       
   342 										'A', 'B', 'C', 'D', 'E', 'F' };
       
   343 	const TInt KBytesPerLine = 32;
       
   344 	const TInt KCharsPerLine = KBytesPerLine * 2;
       
   345 
       
   346 	TInt remaining = aBuffer.Length();
       
   347 	TUint8* pSrc = const_cast<TUint8*>(aBuffer.Ptr());
       
   348 
       
   349 	TBuf<KCharsPerLine> line;
       
   350 	line.SetLength( KCharsPerLine );	// don't need to print trailing space
       
   351 	TInt bytesPerLine = KBytesPerLine;
       
   352 	TInt lineOffs = 0;
       
   353 	while( remaining )
       
   354 		{
       
   355 		if( remaining < KBytesPerLine )
       
   356 			{
       
   357 			bytesPerLine = remaining;
       
   358 			line.SetLength( (bytesPerLine*2) );
       
   359 			}
       
   360 		TUint16* pDest = const_cast<TUint16*>(line.Ptr());
       
   361 		remaining -= bytesPerLine;
       
   362 		for( TInt i = bytesPerLine; i > 0; --i )
       
   363 			{
       
   364 			TUint8 c = *pSrc++;
       
   365 			*pDest++ = hextab[c >> 4];
       
   366 			*pDest++ = hextab[c & 0xF];
       
   367 			}
       
   368 		_LIT( KFmt, "%06x: %S\n\r" );
       
   369 		test.Printf( KFmt, lineOffs, &line );
       
   370 		lineOffs += bytesPerLine;
       
   371 		}
       
   372 	}
       
   373 
       
   374 
       
   375 GLDEF_C TBool CompareBuffers( const TDesC8& aBuf1, const TDesC8& aBuf2 )
       
   376 	{
       
   377 	TInt count = 32;
       
   378 	if (aBuf1.Length() < count) 
       
   379 		count = aBuf1.Length();
       
   380 
       
   381 	
       
   382 	for (TInt i = 0; i < (aBuf1.Length()-count); i+= count)
       
   383 		{
       
   384 		if( aBuf1.Mid(i,count).Compare(aBuf2.Mid(i,count)) != 0)
       
   385 			{
       
   386 			// now need to find where mismatch ends
       
   387 			TInt j =i;
       
   388 			for (; j <= (aBuf1.Length()-count); j+= count)
       
   389 				{
       
   390 				if( aBuf1.Mid(j,count).Compare(aBuf2.Mid(j,count)) == 0) break;
       
   391 				}
       
   392 			test.Printf(_L("buf1 len: %d, buf2 len: %d\n"),aBuf1.Length(),aBuf2.Length());
       
   393 			test.Printf( _L("Buffer mismatch @%d to %d (%d Bytes)\n\r"),i,j, (j-i) );
       
   394 			test.Printf( _L("buffer 1 ------------------\n\r") );
       
   395 			DumpBuffer( aBuf1.Mid(i,(j-i)) );
       
   396 			test.Printf( _L("buffer 2 ------------------\n\r") );
       
   397 			DumpBuffer( aBuf2.Mid(i,(j-i)) );
       
   398 			test.Printf(_L("buf1 len: %d, buf2 len: %d\n"),aBuf1.Length(),aBuf2.Length());
       
   399 			test.Printf( _L("Buffer mismatch @%d to %d (%d Bytes)\n\r"),i,j, (j-i) );
       
   400 			return EFalse;
       
   401 			}
       
   402 		}
       
   403 	return ETrue;
       
   404 	}
       
   405 
       
   406 
       
   407 void singleSectorRdWrTest(TInt aSectorOffset,TInt aLen)
       
   408 //
       
   409 // Perform a write / read test on a single sector (KSingSectorNo). Verify that the
       
   410 // write / read back is successful and that the rest of the sector is unchanged.
       
   411 //
       
   412 	{
       
   413 
       
   414 	TBuf8<KDiskSectorSize> saveBuf;
       
   415 	test.Start(_L("Single sector write/read test"));
       
   416 	test(aSectorOffset+aLen<=KDiskSectorSize);
       
   417 
       
   418 	// Now save state of sector before we write to it
       
   419 	TInt secStart=(KSingSectorNo<<KDiskSectorShift);
       
   420 	test(TheMmcDrive.Read(secStart,KDiskSectorSize,saveBuf)==KErrNone);
       
   421 
       
   422 	// Write zero's to another sector altogether (to ensure drivers 
       
   423 	// local buffer hasn't already got test pattern we expect).
       
   424 	wrBuf.Fill(0,KDiskSectorSize);
       
   425 	test(TheMmcDrive.Write((KSingSectorNo+4)<<KDiskSectorShift,wrBuf)==KErrNone);
       
   426 
       
   427 	// Write / read back sector in question
       
   428 	wrBuf.SetLength(aLen);
       
   429 	for (TInt i=0;i<aLen;i++)
       
   430 		wrBuf[i]=(TUint8)(0xFF-i);
       
   431 	test(TheMmcDrive.Write((secStart+aSectorOffset),wrBuf)==KErrNone);
       
   432 	rdBuf.Fill(0,aLen);
       
   433 	test(TheMmcDrive.Read((secStart+aSectorOffset),aLen,rdBuf)==KErrNone);
       
   434 	test(CompareBuffers(rdBuf, wrBuf));
       
   435 	//test(rdBuf.Compare(wrBuf)==0);
       
   436 
       
   437 	// Now check the rest of the sector is unchanged
       
   438 	rdBuf.Fill(0,KDiskSectorSize);
       
   439 	test(TheMmcDrive.Read(secStart,KDiskSectorSize,rdBuf)==KErrNone);
       
   440 	saveBuf.Replace(aSectorOffset,aLen,wrBuf);
       
   441 	test(CompareBuffers(rdBuf, saveBuf));
       
   442 	test.End();
       
   443 	}
       
   444 
       
   445 const TInt KMultSectorNo=2; 
       
   446 
       
   447 void MultipleSectorRdWrTestMB(TInt aFirstSectorOffset, TInt aLen, TBool aWrMB, TBool aRdMB)
       
   448 //
       
   449 // Perform a write / read test over multiple sectors (starting within sector KMultSectorNo).
       
   450 // Verify that the write / read back is successful and that the remainder of the first and
       
   451 // last sectors are not affected.
       
   452 //
       
   453 	{
       
   454 
       
   455 	TBuf8<KDiskSectorSize> saveBuf1;
       
   456 	TBuf8<KDiskSectorSize> saveBuf2;
       
   457 
       
   458 	test.Printf(_L("   MBW[%d] : MBR[%d]\n\r"), aWrMB, aRdMB);
       
   459 	
       
   460 	test(aFirstSectorOffset<KDiskSectorSize&&aLen<=KVeryLongRdWrBufLen);
       
   461 
       
   462 	// If not starting on sector boundary then save 1st sector to check rest of 1st sector is unchanged
       
   463 	TInt startSecPos=(KMultSectorNo<<KDiskSectorShift);
       
   464 	if (aFirstSectorOffset!=0)
       
   465 		test(TheMmcDrive.Read(startSecPos,KDiskSectorSize,saveBuf1)==KErrNone);
       
   466 
       
   467 	// If not ending on sector boundary then save last sector to check rest of last sector is unchanged
       
   468 	TInt endOffset=(aFirstSectorOffset+aLen)&(~KDiskSectorMask);
       
   469 	TInt endSecPos=((startSecPos+aFirstSectorOffset+aLen)&KDiskSectorMask);
       
   470 	if (endOffset)
       
   471 		{
       
   472 		test(TheMmcDrive.Read(endSecPos,KDiskSectorSize,saveBuf2)==KErrNone);
       
   473 		}
       
   474 
       
   475 	// Write zero's to another sector altogether (to ensure drivers 
       
   476 	// local buffer hasn't already got test pattern we expect).
       
   477 	wrBuf.Fill(0,KSectBufSizeInBytes);
       
   478 	test(TheMmcDrive.Write((endSecPos+(2*KDiskSectorSize)),wrBuf)==KErrNone);
       
   479 	
       
   480 	TInt i;
       
   481 
       
   482 	wrBuf.SetLength(aLen);
       
   483 	for (i=0;i<aLen;i++)
       
   484 		{
       
   485 		wrBuf[i]=(TUint8)(0xFF-i);
       
   486 		}
       
   487 
       
   488 	if(aWrMB)
       
   489 		{
       
   490 		test(TheMmcDrive.Write((startSecPos+aFirstSectorOffset),wrBuf)==KErrNone);
       
   491 		}
       
   492 	else
       
   493 		{
       
   494 		for (i=0;i<aLen;i+=512)
       
   495 			{
       
   496 			TInt thisLen = (aLen-i) < 512 ? (aLen-i) : 512;
       
   497 			TPtrC8 sectorWr(wrBuf.Mid(i, thisLen).Ptr(), thisLen);
       
   498 			test(TheMmcDrive.Write((startSecPos+aFirstSectorOffset+i), sectorWr)==KErrNone);
       
   499 			}
       
   500 		}
       
   501 
       
   502 	rdBuf.Fill(0,aLen);
       
   503 	rdBuf.SetLength(aLen);
       
   504 
       
   505 	if(aRdMB)
       
   506 		{
       
   507 		test(TheMmcDrive.Read((startSecPos+aFirstSectorOffset),aLen,rdBuf) == KErrNone);
       
   508 		}
       
   509 	else
       
   510 		{
       
   511 		for (i=0;i<aLen;i+=512)
       
   512 			{
       
   513 			TInt thisLen = (aLen-i) < 512 ? (aLen-i) : 512;
       
   514 			TPtr8 sectorRd(((TUint8*)(rdBuf.Ptr()))+i, thisLen, thisLen);
       
   515 			test(TheMmcDrive.Read((startSecPos+aFirstSectorOffset+i), thisLen, sectorRd) == KErrNone);
       
   516 			}
       
   517 		}
       
   518 
       
   519 	test(CompareBuffers(rdBuf, wrBuf));
       
   520 
       
   521 	// Check rest of first sector involved is unchanged (if offset specified)
       
   522 	if (aFirstSectorOffset!=0)
       
   523 		{
       
   524 		rdBuf.Fill(0,KDiskSectorSize);
       
   525 		test(TheMmcDrive.Read(startSecPos,KDiskSectorSize,rdBuf)==KErrNone);
       
   526 		wrBuf.SetLength(KDiskSectorSize-aFirstSectorOffset);
       
   527 		saveBuf1.Replace(aFirstSectorOffset,(KDiskSectorSize-aFirstSectorOffset),wrBuf);
       
   528 		test(rdBuf.Compare(saveBuf1)==0);
       
   529 		}
       
   530 
       
   531 	// Check rest of last sector involved is unchanged (if not ending on sector boundary)
       
   532 	if (endOffset)
       
   533 		{
       
   534 		rdBuf.Fill(0,KDiskSectorSize);
       
   535 		test(TheMmcDrive.Read(endSecPos,KDiskSectorSize,rdBuf)==KErrNone);
       
   536 		wrBuf.SetLength(aLen);
       
   537 		wrBuf.Delete(0,aLen-endOffset);
       
   538 		saveBuf2.Replace(0,endOffset,wrBuf);
       
   539 		test(CompareBuffers(rdBuf, saveBuf2));
       
   540 		}
       
   541 	}
       
   542 
       
   543 void MultipleSectorRdWrTest(TInt aFirstSectorOffset,TInt aLen, TBool aMBOnly = EFalse)
       
   544 //
       
   545 // Perform a write / read test over multiple sectors (starting within sector KMultSectorNo).
       
   546 // Verify that the write / read back is successful and that the remainder of the first and
       
   547 // last sectors are not affected.
       
   548 //
       
   549 	{
       
   550 	test.Start(_L("Multiple sector write/read test"));
       
   551 
       
   552 	if(!aMBOnly)
       
   553 		{
       
   554 		MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, EFalse, EFalse);
       
   555 		MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, EFalse, ETrue);
       
   556 		MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, ETrue,  EFalse);
       
   557 		}
       
   558 
       
   559 	MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, ETrue,  ETrue);
       
   560 
       
   561 	test.End();
       
   562 	}
       
   563 
       
   564 LOCAL_C TInt dontDisconnectThread(TAny*)
       
   565 	{
       
   566 
       
   567 	TBusLocalDrive anotherMmcDrive;
       
   568 	nTest.Title();
       
   569 
       
   570 	nTest.Start(_L("Connect to internal drive"));
       
   571 	anotherMmcDrive.Connect(DriveNumber,SecThreadChangeFlag);
       
   572 
       
   573 	nTest.Next(_L("Capabilities"));
       
   574 	TLocalDriveCapsV2 info;
       
   575 	TPckg<TLocalDriveCapsV2> infoPckg(info);
       
   576 	nTest(anotherMmcDrive.Caps(infoPckg)==KErrNone);
       
   577 	nTest(info.iType==EMediaHardDisk);
       
   578 
       
   579 	nTest.End();
       
   580 	return(KErrNone);
       
   581 	}
       
   582 
       
   583 LOCAL_C void ProgressBar(TInt64 aPos,TInt64 anEndPos,TInt anXPos)
       
   584 //
       
   585 // Display progress of local drive operation on screen (1-16 dots)
       
   586 //
       
   587 	{
       
   588 	static TInt64 prev;
       
   589 	TInt64 curr;
       
   590 	if ((curr=(aPos-1)/(anEndPos>>4))>prev)
       
   591 		{ // Update progress bar
       
   592 		test.Console()->SetPos(anXPos);
       
   593 		for (TInt64 i=curr;i>=0;i--)
       
   594 			test.Printf(_L("."));
       
   595 		}
       
   596 	prev=curr;
       
   597 	}
       
   598 
       
   599 
       
   600 /**
       
   601 @SYMTestCaseID PBASE-T_MMCDRV-0510
       
   602 @SYMTestCaseDesc Test Write/Read during media Change
       
   603 @SYMTestPriority High
       
   604 
       
   605 @SYMTestActions
       
   606 		a.) Test Read during a Media Change
       
   607 		b.) Test Write during a Media Change
       
   608 
       
   609 @SYMTestExpectedResults All tests must pass
       
   610 */
       
   611 LOCAL_C void TestHugeReadWrite(TBool aIsRead, TInt aLen)
       
   612 //
       
   613 // Writes aLen bytes to the MMC drive.  Gives user enough time to flip the media
       
   614 // change switch.  Request should abort with KErrNotReady on write command, but nothing
       
   615 // on read command.
       
   616 // Each read or write is started from sector KMultSectNo (2).
       
   617 // The media change operation only works when the switch is moved from the closed position
       
   618 // to the open position.
       
   619 // 
       
   620 	{
       
   621 	test.Start(_L("TestHugeReadWrite: media change during I/O test."));
       
   622 	test.Printf(_L("aIsRead = %x, aLen = %x.\n"), aIsRead, aLen);
       
   623 
       
   624 	HBufC8 *buf = HBufC8::New(aLen);
       
   625 	test(buf != NULL);
       
   626 
       
   627 	TInt startSectPos = KMultSectorNo << KDiskSectorShift;
       
   628 	if (aIsRead)
       
   629 		{
       
   630 		test.Printf(_L("Launching %08x byte read at %08x.\n"), aLen, startSectPos);
       
   631 		test.Printf(_L("Move media change from closed to open position before finished.\n"));
       
   632 		TPtr8 ptr(buf->Des());
       
   633 		TInt r = TheMmcDrive.Read(startSectPos, aLen, ptr);
       
   634 		test.Printf(_L("r = %d.\n"), r);
       
   635 		test(r == KErrNone);
       
   636 		}
       
   637 	else
       
   638 		{
       
   639 		buf->Des().Fill(0xff, aLen);
       
   640 		test.Printf(_L("Launching %08x byte write at %08x.\n"), aLen, startSectPos);
       
   641 		test.Printf(_L("Move media change from closed to open position before finished.\n"));
       
   642 		TInt r = TheMmcDrive.Write(startSectPos, *buf);
       
   643 		test.Printf(_L("r = %d.\n"), r);
       
   644 		test(r == KErrNotReady);
       
   645 		}
       
   646 	
       
   647 	test.Printf(_L("Pausing for 5 seconds to move media change switch back to closed.\n"));
       
   648 	User::After(5 * 1000 * 1000);
       
   649 	delete buf;
       
   650 	test.End();
       
   651 	}
       
   652 
       
   653 
       
   654 LOCAL_C void FillBufferWithPattern(TDes8 &aBuf)
       
   655 //
       
   656 // Fills aBuf with cycling hex digits up to aBuf.Length().
       
   657 //
       
   658 	{
       
   659 	TInt len = aBuf.Length() & ~3;
       
   660 	for (TInt i = 0; i < len; i+=4)
       
   661 		{
       
   662 		*((TUint32*) &aBuf[i]) = i;
       
   663 		}
       
   664 	}
       
   665 
       
   666 
       
   667 LOCAL_C void WriteAndReadBack(TInt64 aStartPos, const TDesC8 &aWrBuf)
       
   668 //
       
   669 // This function tests the multiple block reads when aWrBuf is sufficiently large.
       
   670 //
       
   671 	{
       
   672 	test.Start(_L("WriteAndReadBack"));
       
   673 
       
   674 	TInt r;										// general error values
       
   675 
       
   676 	// Allocate a same size buffer to read back into and compare with.
       
   677 	HBufC8 *rdBuf = aWrBuf.Alloc();
       
   678 	test(rdBuf != NULL);
       
   679 	TPtr8 rdPtr(rdBuf->Des());
       
   680 	
       
   681 	test.Next(_L("wrb: writing"));
       
   682 	r = TheMmcDrive.Write(aStartPos, aWrBuf);
       
   683 	test.Printf(_L("\nwrb:r=%d"), r);
       
   684 	test(r == KErrNone);
       
   685 
       
   686 	test.Printf(_L("\n"));
       
   687 	test.Next(_L("wrb: reading"));
       
   688 	r = TheMmcDrive.Read(aStartPos, rdPtr.Length(), rdPtr);
       
   689 	test.Printf(_L("rb:r=%d"), r);
       
   690 	test(r == KErrNone);
       
   691 
       
   692 	// Compare the pattern that has just been read back with the original.
       
   693 	test.Printf(_L("\n"));
       
   694 	test.Next(_L("wrb: comparing"));
       
   695 	test.Printf(
       
   696 		_L("rdPtr.Length() = %04x, aWrBuf.Length() = %04x"),
       
   697 		rdPtr.Length(), aWrBuf.Length());
       
   698 	test(rdPtr == aWrBuf);
       
   699 
       
   700 #if 0											// extra debug when buffers not compare.
       
   701 	for (TInt j = 0; j < rdPtr.Length(); j++)
       
   702 		{
       
   703 		test.Printf(_L("%d: w%02x r%02x"), j, aWrBuf[j], rdBuf[j]);
       
   704 
       
   705 		if (rdPtr[j] != aWrBuf[j])
       
   706 			{
       
   707 			test.Printf(_L("buffer mismatch at %04x: %02x v %02x"), j, rdPtr[j], aWrBuf[j]);
       
   708 			test(EFalse);
       
   709 			}
       
   710 		}
       
   711 #endif
       
   712 
       
   713 	test.Printf(_L("\n"));
       
   714 	delete rdBuf;
       
   715 	test.End();
       
   716 	}
       
   717 
       
   718 /**
       
   719 @SYMTestCaseID PBASE-T_MMCDRV-0169
       
   720 @SYMTestCaseDesc Test Multiple Block Reads
       
   721 @SYMTestPriority High
       
   722 
       
   723 @SYMTestActions
       
   724 		a.) Test Multiple Block Reads at the internal buffer size
       
   725 		b.) Test Multiple Block Reads greater than the internal buffer size
       
   726 
       
   727 @SYMTestExpectedResults All tests must pass
       
   728 
       
   729 @TODO: increase Buffer size to match current reference platform (128KB)
       
   730 */
       
   731 LOCAL_C void TestMultipleBlockReads()
       
   732 	{
       
   733 	// Test multiple block reads.
       
   734 	static TBuf8<256 * 1024> rw_wrBuf;
       
   735 
       
   736 	rw_wrBuf.SetLength(rw_wrBuf.MaxLength());
       
   737 	FillBufferWithPattern(rw_wrBuf);
       
   738 
       
   739 	test.Next(_L("Testing multiple block reads at internal buffer size"));
       
   740 	rw_wrBuf.SetLength(8 * KDiskSectorSize);
       
   741 	WriteAndReadBack(KMultSectorNo << KDiskSectorShift, rw_wrBuf);
       
   742 
       
   743 	test.Next(_L("Testing multiple block reads at gt internal buffer size"));
       
   744 	rw_wrBuf.SetLength(10 * KDiskSectorSize);
       
   745 	WriteAndReadBack(KMultSectorNo << KDiskSectorShift, rw_wrBuf);
       
   746 
       
   747 	test.Next(_L("Testing unaligned large block read "));
       
   748 	rw_wrBuf.SetLength(rw_wrBuf.MaxLength());
       
   749 	WriteAndReadBack((KMultSectorNo << KDiskSectorShift) + 128, rw_wrBuf);
       
   750 	}
       
   751 
       
   752 
       
   753 /**
       
   754 @SYMTestCaseID PBASE-T_MMCDRV-0558
       
   755 @SYMTestCaseDesc Test Long Read/Write Boundaries
       
   756 @SYMTestPriority High
       
   757 
       
   758 @SYMTestActions  
       
   759 	
       
   760   Perform and Write/Read/Verify for the given length (L) of data across the following boundaries.
       
   761   Depending on the length provided, this will also perform a partial write/read at the end sector.
       
   762 
       
   763 									 -------------------
       
   764 									| Start	|	End		|
       
   765 									|-------------------|
       
   766 									| 0		|	L		|
       
   767 									| 507	|	L-507	|
       
   768 									| 10	|	L		|
       
   769 									| 0		|	L-3		|
       
   770 									| 27	|	L-512	|
       
   771 									| 0		|	L-509	|
       
   772 									| 3		|	L-3		|
       
   773 									 -------------------
       
   774 
       
   775   For each combination, the write/read/verify operations are performed in the following sequence:
       
   776 
       
   777 	a: Write and Read in single 512-byte blocks.
       
   778 	b: Write in a single operation (multiple blocks), Read in 512-Byte blocks.
       
   779 	c: Write in 512-Byte blocks, Read in a single operation (multiple-blocks).
       
   780 	d: Write and Read in a single operation (multiple-blocks).
       
   781 
       
   782   In the cases where a partial read/write operation occurs (ie - the start and/or end position don't lie within
       
   783   a sector boundary), the original contents of the start and/or end sectors are read and stored at the start of
       
   784   the test, and compared with the contents of the sectors at the end of the test to ensure that unwritten data within
       
   785   the sectors remain unaffected.
       
   786   
       
   787 @SYMTestExpectedResults All tests must pass
       
   788 
       
   789 @SYMPREQ1389 REQ6951 Double Buffering and SD Switch
       
   790 */
       
   791 	
       
   792 LOCAL_C void TestLongReadWriteBoundaries(TUint aLen, TBool aMBOnly = EFalse)
       
   793 	{
       
   794 	TBuf<64> b;
       
   795 
       
   796 	b.Format(_L("MMC drive: Very long RdWr(1) (%dbytes at %d)"),aLen,0);
       
   797 	test.Next(b);
       
   798 	MultipleSectorRdWrTest(0, aLen, aMBOnly); // Exceeds driver's buffer, starts/ends on sector boundary
       
   799 
       
   800 	b.Format(_L("MMC drive: Very long RdWr(2) (%dbytes at %d)"),(aLen-KDiskSectorSize+5),507);
       
   801 	test.Next(b);
       
   802 	MultipleSectorRdWrTest(507, (aLen-KDiskSectorSize+5), aMBOnly); // Exceeds driver's buffer, ends on sector boundary
       
   803 
       
   804 	b.Format(_L("MMC drive: Very long RdWr(3) (%dbytes at %d)"),aLen,10);
       
   805 	test.Next(b);
       
   806 	MultipleSectorRdWrTest(10, aLen, aMBOnly); // Exceeds driver's buffer, starts/ends off sector boundary
       
   807 
       
   808 	b.Format(_L("MMC drive: Very long RdWr(4) (%dbytes at %d)"),(aLen-3),0);
       
   809 	test.Next(b);
       
   810 	MultipleSectorRdWrTest(0, aLen-3, aMBOnly); // Exceeds driver's buffer, starts on sector boundary
       
   811 
       
   812 	b.Format(_L("MMC drive: Very long RdWr(5) (%dbytes at %d)"),(aLen-KDiskSectorSize),27);
       
   813 	test.Next(b);
       
   814 	MultipleSectorRdWrTest(27, (aLen-KDiskSectorSize), aMBOnly); // Exceeds driver's buffer (due to start offset), starts/ends off sector boundary
       
   815 
       
   816 	b.Format(_L("MMC drive: Very long RdWr(6) (%dbytes at %d)"),(aLen-KDiskSectorSize-3),0);
       
   817 	test.Next(b);
       
   818 	MultipleSectorRdWrTest(0, aLen-KDiskSectorSize-3, aMBOnly); // Equals driver's buffer, starts on sector boundary
       
   819 
       
   820 	b.Format(_L("MMC drive: Very long RdWr(7) (%dbytes at %d)"),(aLen-3),3);
       
   821 	test.Next(b);
       
   822 	MultipleSectorRdWrTest(3, aLen-3, aMBOnly); // Equals driver's buffer, ends on sector boundary
       
   823 	}
       
   824 
       
   825 
       
   826 /**
       
   827 @SYMTestCaseID PBASE-T_MMCDRV-0509
       
   828 @SYMTestCaseDesc Test Sector Read/Writing
       
   829 @SYMTestPriority High
       
   830 
       
   831 @SYMTestActions
       
   832 		a.) Test Writing blocks on sector boundaries
       
   833 		b.) Test Reading blocks on sector boundaries
       
   834 		c.) Test single sector Write/Read at:
       
   835 			  i.) Sector Start
       
   836 			 ii.) Mid Sector
       
   837 			iii.) Sector End
       
   838 		d.) Test Multiple Sector Write/Read:
       
   839 			  i.) Start on Sector Boundary
       
   840 			 ii.) Start/End on Sector Boundary
       
   841 			iii.) End on Sector Boundary
       
   842 		e.) Test Write/Read over sector boundary
       
   843 
       
   844 @SYMTestExpectedResults All tests must pass
       
   845 */
       
   846 LOCAL_C void TestSectorReadWrite()
       
   847 	{
       
   848 	TBuf<64> b;
       
   849 	b.Format(_L("MMC drive: Sector RdWr(%d)"), KDiskSectorSize);
       
   850 
       
   851 	test.Next(b);
       
   852 
       
   853 	TInt len;
       
   854 
       
   855 	// Fill wrBuf with a pattern of ascending numbers.
       
   856 	wrBuf.SetLength(KDiskSectorSize);
       
   857 	TUint32 *p = REINTERPRET_CAST(TUint32 *, &wrBuf[0]);
       
   858 	TInt secPos;
       
   859 	for (secPos = 0; secPos < KDiskSectorSize; secPos++)
       
   860 		{
       
   861 		wrBuf[secPos] = TUint8(secPos % 0x0100);
       
   862 		}
       
   863 
       
   864 	// Write 512 byte blocks to the card, writing the sector number to the first
       
   865 	// word in each buffer.
       
   866 
       
   867 	test.Printf(_L("Writing    "));
       
   868 	TInt64 i;
       
   869 //	for (i=0;i<DriveSize;i+=len)  // B - Sector wr/rd on sector boundary
       
   870 	for (i=0;i<(0x200<<3);i+=len)	 // B - Sector wr/rd on sector boundary
       
   871 		{
       
   872 		ProgressBar(i, TheMmcDrive.Size(), 11);
       
   873 		len = KDiskSectorSize < TheMmcDrive.Size() - i ? KDiskSectorSize : I64LOW(TheMmcDrive.Size() - i);
       
   874 		(*p) = I64LOW(i) / KDiskSectorSize;
       
   875 		wrBuf.SetLength(len);
       
   876 		TInt r = TheMmcDrive.Write(i, wrBuf);
       
   877 		if (r != KErrNone)
       
   878 			{
       
   879 			test.Printf(_L("wt:i = %d, len = %d, r  %d"), i, len, r);
       
   880 			test(EFalse);
       
   881 			}
       
   882 		}
       
   883 
       
   884 	// Read each of the 512 byte blocks back from the card.
       
   885 	test.Printf(_L("\r\nReading    "));
       
   886 //	for (i=0;i<TheMmcDrive.Size();i+=len)
       
   887 	for (i=0;i<(0x200<<3);i+=len)	 // B - Sector wr/rd on sector boundary
       
   888 		{
       
   889 		ProgressBar(i, TheMmcDrive.Size(), 11);
       
   890 		len = KDiskSectorSize < TheMmcDrive.Size() - i ? KDiskSectorSize : I64LOW(TheMmcDrive.Size() - i);
       
   891 		rdBuf.Fill(0,len);
       
   892 		TInt r = TheMmcDrive.Read(i, len, rdBuf);
       
   893 		if (r != KErrNone)
       
   894 			{
       
   895 			test.Printf(_L("rd:i = %d, len = %d, r  %d"), i, len, r);
       
   896 			test(EFalse);
       
   897 			}
       
   898 		(*p) = (I64LOW(i)/KDiskSectorSize);
       
   899 		wrBuf.SetLength(len);
       
   900 
       
   901 		if ((r = rdBuf.Compare(wrBuf)) != 0)
       
   902 			{
       
   903 			test.Printf(_L("wc:i = %d, len = %d, r  %d"), i, len, r);
       
   904 			test.Printf(_L("wc: wrBuf.Length() = %d, rdBuf.Length() = %d"), wrBuf.Length(), rdBuf.Length());
       
   905 			TInt j;
       
   906 			for (j = 0; j < wrBuf.Length() && wrBuf[j] == rdBuf[j]; j++)
       
   907 				{
       
   908 				// empty.
       
   909 				}
       
   910 			test.Printf(_L("wc: wrBuf[%d] = %d, rdBuf[%d] = %d"), j, wrBuf[j], j, rdBuf[j]);
       
   911 
       
   912 			test(EFalse);
       
   913 			}
       
   914 		}
       
   915 	test.Printf(_L("\r\n"));
       
   916 
       
   917 	b.Format(_L("MMC drive: Short RdWr(1) (%dbytes at %d)"),25,0); 
       
   918 	test.Next(b);
       
   919 	singleSectorRdWrTest(0,25); // A - Sub-sector wr/rd at sector start
       
   920 
       
   921 	b.Format(_L("MMC drive: Short RdWr(2) (%dbytes at %d)"),16,277); 
       
   922 	test.Next(b);
       
   923 	singleSectorRdWrTest(277,16); // E - Sub-sector wr/rd in mid sector
       
   924 
       
   925 	b.Format(_L("MMC drive: Short RdWr(3) (%dbytes at %d)"),100,412); 
       
   926 	test.Next(b);
       
   927 	singleSectorRdWrTest(412,100); // F - Sub-sector wr/rd at sector end
       
   928 
       
   929 	b.Format(_L("MMC drive: Long RdWr(1) (%dbytes at %d)"),KDiskSectorSize+15,0);
       
   930 	test.Next(b);
       
   931 	MultipleSectorRdWrTest(0,KDiskSectorSize+15); // C - Long wr/rd starting on sector boundary
       
   932 
       
   933 	b.Format(_L("MMC drive: Long RdWr(2) (%dbytes at %d)"),(KDiskSectorSize<<1),0);
       
   934 	test.Next(b);
       
   935 	MultipleSectorRdWrTest(0,(KDiskSectorSize<<1)); // D - Long wr/rd starting/ending on sector boundary
       
   936 
       
   937 	b.Format(_L("MMC drive: Long RdWr(3) (%dbytes at %d)"),KDiskSectorSize+3,509);
       
   938 	test.Next(b);
       
   939 	MultipleSectorRdWrTest(509,KDiskSectorSize+3); // H -  - Long wr/rd ending on sector boundary
       
   940 
       
   941 	b.Format(_L("MMC drive: Long RdWr(4) (%dbytes at %d)"),(KDiskSectorSize<<1),508);
       
   942 	test.Next(b);
       
   943 	MultipleSectorRdWrTest(508,(KDiskSectorSize<<1));
       
   944 
       
   945 	b.Format(_L("MMC drive: Sector RdWr across sector boundary(%dbytes at %d)"),KDiskSectorSize,508);
       
   946 	test.Next(b);
       
   947 	MultipleSectorRdWrTest(508,KDiskSectorSize);	// G - Sector wr/rd over sector boundary
       
   948 
       
   949 	TestLongReadWriteBoundaries(KRdWrBufLen);			// Short length - As per original test
       
   950 
       
   951 	if (ManualMode)
       
   952 		{
       
   953 		for(TInt bufLen = KRdWrBufLen; bufLen <= 256*1024; bufLen += KRdWrBufLen)
       
   954 			{
       
   955 			TestLongReadWriteBoundaries(bufLen, ETrue);				// Very long length - to test Double-Buffering
       
   956 			}
       
   957 		
       
   958 		TestLongReadWriteBoundaries(KVeryLongRdWrBufLen, ETrue);	// Very long length - to test Double-Buffering
       
   959 		}
       
   960 	}
       
   961 
       
   962 
       
   963 /**
       
   964 @SYMTestCaseID PBASE-T_MMCDRV-0168
       
   965 @SYMTestCaseDesc Test Sector Formatting
       
   966 @SYMTestPriority High
       
   967 
       
   968 @SYMTestActions
       
   969 		a.) Test Format/Read/Verify Single Sector
       
   970 		b.) Test Format/Read/Verify Multiple Sectors
       
   971 		c.) Test Format/Read/Verify Whole Media
       
   972 
       
   973 @SYMTestExpectedResults All tests must pass
       
   974 */
       
   975 LOCAL_C void TestFormat()
       
   976 	{
       
   977 	if(TheMmcDrive.TestMode() != TMMCDrive::ETestPartition)
       
   978 		{
       
   979 		test.Printf(_L("Skipping format tests - only supported on Partition Test Mode"));
       
   980 		return;
       
   981 		}
       
   982 
       
   983 	if(CardType == TKnownCardTypes::EBuffalloMiniSD_32M_ERASE ||	
       
   984 	   CardType == TKnownCardTypes::EBuffalloMiniSD_64M_ERASE ||
       
   985 	   CardType == TKnownCardTypes::EBuffalloMiniSD_128M_ERASE ||
       
   986 	   CardType == TKnownCardTypes::EBuffalloMiniSD_256M_ERASE ||
       
   987 	   CardType == TKnownCardTypes::EBuffalloMiniSD_512M_ERASE
       
   988 	   )
       
   989 	    {
       
   990 	    //These cards implement the erase command incorrectly
       
   991 	    test.Printf( _L(" -- Skipping Format Tests - Known card detected --\n") );
       
   992 	    return;
       
   993 	    }
       
   994 	
       
   995 	test.Next(_L("MMC drive: Format sectors (short)"));
       
   996 	TBuf8<KDiskSectorSize> savBuf1,savBuf2;
       
   997 	TInt fmtTestPos=(10<<KDiskSectorShift);
       
   998 	// Save sectors surrounding those which will be formatted
       
   999 	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,savBuf1)==KErrNone);
       
  1000 	test(TheMmcDrive.Read((fmtTestPos+KShortFormatInBytes),KDiskSectorSize,savBuf2)==KErrNone);
       
  1001 
       
  1002 	// Fill buffer with 0xCC 
       
  1003 	// (i.e. a value which is not going to be written by formatting the device)
       
  1004 	// & then write to area which is to be formatted
       
  1005 	wrBuf.SetLength(KShortFormatInBytes);
       
  1006 	wrBuf.Fill(0xCC);
       
  1007 	test(TheMmcDrive.Write(fmtTestPos, wrBuf)==KErrNone);
       
  1008 
       
  1009 
       
  1010 	test(TheMmcDrive.Format(fmtTestPos,KShortFormatInBytes)==KErrNone);
       
  1011 	test(TheMmcDrive.Read(fmtTestPos,KShortFormatInBytes,rdBuf)==KErrNone);
       
  1012 
       
  1013 	TUint8 defEraseVal = rdBuf[0];
       
  1014 	test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
       
  1015 	wrBuf.Fill(defEraseVal ,KShortFormatInBytes);
       
  1016 	test(rdBuf.Compare(wrBuf)==0);
       
  1017 
       
  1018 	// Check that surrounding sectors unaffected
       
  1019 	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,rdBuf)==KErrNone);
       
  1020 	test(rdBuf.Compare(savBuf1)==0);
       
  1021 	test(TheMmcDrive.Read((fmtTestPos+KShortFormatInBytes),KDiskSectorSize,rdBuf)==KErrNone);
       
  1022 	test(rdBuf.Compare(savBuf2)==0);
       
  1023 
       
  1024 	test.Next(_L("MMC drive: Format sectors (long)"));
       
  1025 	fmtTestPos+=(4<<KDiskSectorShift);
       
  1026 	// Save sectors surrounding those which will be formatted
       
  1027 	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,savBuf1)==KErrNone);
       
  1028 	test(TheMmcDrive.Read((fmtTestPos+KLongFormatInBytes),KDiskSectorSize,savBuf2)==KErrNone);
       
  1029 
       
  1030 	// Fill buffer with 0xCC 
       
  1031 	// (i.e. a value which is not going to be written by formatting the device)
       
  1032 	// & then write to area which is to be formatted
       
  1033 	wrBuf.SetLength(KLongFormatInBytes);
       
  1034 	wrBuf.Fill(0xCC);
       
  1035 	test(TheMmcDrive.Write(fmtTestPos, wrBuf)==KErrNone);
       
  1036 
       
  1037 	test(TheMmcDrive.Format(fmtTestPos,KLongFormatInBytes)==KErrNone);
       
  1038 	test(TheMmcDrive.Read(fmtTestPos,KLongFormatInBytes,rdBuf)==KErrNone);
       
  1039 
       
  1040 	defEraseVal = rdBuf[0];
       
  1041 	test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
       
  1042 	wrBuf.Fill(defEraseVal,KLongFormatInBytes);
       
  1043 	TInt cmpRes = rdBuf.Compare(wrBuf);
       
  1044 	if(cmpRes != 0)
       
  1045 		{
       
  1046 		test.Printf(_L("\n\rExpected 0x%02x\n\r"));
       
  1047 		for(TInt x=0; x<KLongFormatInBytes; x+=8)
       
  1048 			{
       
  1049 			test.Printf(_L("%08x : %02x %02x %02x %02x %02x %02x %02x %02x\n\r"), x, rdBuf[x],rdBuf[x+1],rdBuf[x+2],rdBuf[x+3],rdBuf[x+4],rdBuf[x+5],rdBuf[x+6],rdBuf[x+7]);
       
  1050 			}
       
  1051 		}
       
  1052 	test(cmpRes==0);
       
  1053 
       
  1054 	// Check that surrounding sectors unaffected
       
  1055 	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,rdBuf)==KErrNone);
       
  1056 	test(rdBuf.Compare(savBuf1)==0);
       
  1057 	test(TheMmcDrive.Read((fmtTestPos+KLongFormatInBytes),KDiskSectorSize,rdBuf)==KErrNone);
       
  1058 	test(rdBuf.Compare(savBuf2)==0);
       
  1059 
       
  1060 	if (ManualMode)
       
  1061 		{
       
  1062 		test.Next(_L("Fill the drive with garbage"));
       
  1063 		TInt64 driveSize = TheMmcDrive.Size();
       
  1064 		TInt wtLen = wrBuf.MaxLength();
       
  1065 		TInt64 i;
       
  1066 		for (i=0; i<driveSize; i+=wtLen)
       
  1067 			{
       
  1068 			ProgressBar(i,driveSize,11);
       
  1069 			wtLen = wtLen < driveSize - i ? wtLen : I64LOW(driveSize - i);
       
  1070 			wrBuf.Fill(0xCC,wtLen);
       
  1071 
       
  1072 			wrBuf.SetLength(wtLen);
       
  1073 
       
  1074 			test.Printf(_L("writing pos %08lX len %08X\n"), i, wrBuf.Length());
       
  1075 			test(TheMmcDrive.Write(i, wrBuf) == KErrNone);
       
  1076 			}
       
  1077 
       
  1078 		test.Next(_L("MMC drive: Format entire disk"));
       
  1079 		TFormatInfo fi;
       
  1080 		test.Printf(_L("Formatting "));
       
  1081 		TInt ret;
       
  1082 		TInt stage = 0;
       
  1083 		while((ret=TheMmcDrive.Format(fi))!=KErrEof)
       
  1084 			{
       
  1085 			stage++;
       
  1086 			ProgressBar((fi.i512ByteSectorsFormatted<<9),TheMmcDrive.Size(),11);
       
  1087 			test(ret==KErrNone);
       
  1088 			}
       
  1089 
       
  1090 		test.Printf(_L("\r\nReading    "));
       
  1091 		
       
  1092 		TInt len = KVeryLongSectBufSizeInBytes;
       
  1093 
       
  1094 		for (i=0; i<TheMmcDrive.Size(); i+=len)
       
  1095 			{
       
  1096 			ProgressBar(i,TheMmcDrive.Size(),11);
       
  1097 			len = len < TheMmcDrive.Size() - i ? len : I64LOW(TheMmcDrive.Size() - i);
       
  1098 			rdBuf.Fill(0x55,len);
       
  1099 			test(TheMmcDrive.Read(i,len,rdBuf) == KErrNone);
       
  1100 
       
  1101 			const TInt wholeSectors = len / KDiskSectorSize;
       
  1102 			const TInt rem = len - (wholeSectors * KDiskSectorSize);
       
  1103 
       
  1104 			TInt sec;
       
  1105 			for(sec=1;sec<wholeSectors; sec++)	// Start at Base+1 - Card may have written an MBR at sector 0
       
  1106 				{
       
  1107 				wrBuf.SetLength(KDiskSectorSize);
       
  1108 				defEraseVal = rdBuf[sec * KDiskSectorSize];
       
  1109 				test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
       
  1110 				wrBuf.Fill(defEraseVal, KDiskSectorSize);
       
  1111 				test( CompareBuffers( wrBuf, rdBuf.Mid( sec * KDiskSectorSize, KDiskSectorSize ) ) );
       
  1112 				}
       
  1113 
       
  1114 			if(rem > 0)
       
  1115 				{
       
  1116 				wrBuf.SetLength(rem);
       
  1117 				defEraseVal = rdBuf[sec * KDiskSectorSize];
       
  1118 				test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
       
  1119 				wrBuf.Fill(defEraseVal, rem);
       
  1120 				test( CompareBuffers( wrBuf, rdBuf.Mid( sec * KDiskSectorSize, rem ) ) );
       
  1121 				}
       
  1122 			}
       
  1123 		}
       
  1124 	}
       
  1125 
       
  1126 
       
  1127 class TRandGen
       
  1128 	{
       
  1129 	public:
       
  1130 		TRandGen();
       
  1131 		void Seed();
       
  1132 		void Seed( const TInt64& aSeed );
       
  1133 		TUint Next();
       
  1134 
       
  1135 	private:
       
  1136 		TInt64	iValue;
       
  1137 	};
       
  1138 
       
  1139 
       
  1140 TRandGen::TRandGen()
       
  1141 	: iValue(KDefaultRandSeed)
       
  1142 	{
       
  1143 	}
       
  1144 
       
  1145 
       
  1146 void TRandGen::Seed( const TInt64& aSeed )
       
  1147 	{
       
  1148 	iValue = aSeed;
       
  1149 	}
       
  1150 
       
  1151 void TRandGen::Seed()
       
  1152 	{
       
  1153 	iValue = KDefaultRandSeed;
       
  1154 	}
       
  1155 
       
  1156 TUint TRandGen::Next()
       
  1157 	{
       
  1158 	iValue *= 214013;
       
  1159     iValue += 2531011;
       
  1160     return static_cast<TUint>( I64LOW(iValue) );
       
  1161 	}
       
  1162 
       
  1163 
       
  1164 GLDEF_C void FillRandomBuffer( TDes8& aBuf, TRandGen& aRand )
       
  1165 	/**
       
  1166 	 * Fill buffer aBuf with data generated by aRand
       
  1167 	 */
       
  1168 	{
       
  1169 	TUint l = aBuf.MaxLength();
       
  1170 	aBuf.SetLength( l );
       
  1171 	TUint* p = (TUint*)aBuf.Ptr();
       
  1172 
       
  1173 	// Do any unaligned bytes at the start
       
  1174 	TInt preAlign = (TUint)p & 3;
       
  1175 	if( preAlign )
       
  1176 		{
       
  1177 		preAlign = 4 - preAlign;
       
  1178 		TUint8* p8 = (TUint8*)p;
       
  1179 		TUint rand = aRand.Next();
       
  1180 		while( preAlign && l )
       
  1181 			{
       
  1182 			*p8 = (TUint8)(rand & 0xFF);
       
  1183 			rand >>= 8;
       
  1184 			++p8;
       
  1185 			--preAlign;
       
  1186 			--l;
       
  1187 			}
       
  1188 		p = (TUint*)p8;
       
  1189 		}
       
  1190 
       
  1191 	for( ; l > 3; l-=4 )
       
  1192 		{
       
  1193 		*p++ = aRand.Next();
       
  1194 		}
       
  1195 	// Fill in any trailing bytes
       
  1196 	if( l > 0 )
       
  1197 		{
       
  1198 		TUint8* q = (TUint8*)p;
       
  1199 		TUint r = aRand.Next();
       
  1200 		if( l > 1 )
       
  1201 			{
       
  1202 			*((TUint16*)q) = (TUint16)(r & 0xFFFF);
       
  1203 			q += 2;
       
  1204 			l -= 2;
       
  1205 			r >>= 16;
       
  1206 			}
       
  1207 		if( l > 0 )
       
  1208 			{
       
  1209 			*q = (TUint8)(r & 0xFF);
       
  1210 			}
       
  1211 		}
       
  1212 	}
       
  1213 
       
  1214 GLDEF_C void FillRandomBuffer( HBufC8* aBuf, TRandGen& aRand )
       
  1215 	/**
       
  1216 	 * Fill buffer aBuf with data generated by aRand
       
  1217 	 * For convenience this version takes a HBufC8*
       
  1218 	 */
       
  1219 	{
       
  1220 	TPtr8 ptr = aBuf->Des();
       
  1221 	FillRandomBuffer( ptr, aRand );
       
  1222 	}
       
  1223 
       
  1224 
       
  1225 /**
       
  1226 @SYMTestCaseID PBASE-T_MMCDRV-0164
       
  1227 @SYMTestCaseDesc Test MMC Drive Capabilities
       
  1228 @SYMTestPriority High
       
  1229 
       
  1230 @SYMTestActions  
       
  1231 	a. Obtain MMC Drive Capabilities
       
  1232 	b. If the card size is greater than 2GBytes, test that the driver reports FAT32 file system supported.
       
  1233 	c. Test that the type of media is reported as EMediaHardDisk
       
  1234 	d. Test that the drive attributes report KDriveAttLocal and KDriveAttRemovable
       
  1235 	e. Test that the drive attributes do not report KDriveAttRemote
       
  1236 	f. If the drive is not write protected or a ROM card, test that the media attributes report that the drive is formattable
       
  1237 	g. If the drive is write protected or a ROM card, test that the media attributes do not report that the drive is formattable
       
  1238 	h. Test that the media attributes do not report variable sized media.
       
  1239 
       
  1240 @SYMTestExpectedResults All tests must pass
       
  1241 
       
  1242 @SYMPREQ1389 CR0795 Support for >2G SD Cards
       
  1243 */
       
  1244 TBool TestDriveInfo()
       
  1245 	{
       
  1246 	test.Next( _L("Test drive info") );
       
  1247 
       
  1248 	TEST_FOR_ERROR( TheMmcDrive.Caps( DriveCaps ) );
       
  1249 
       
  1250 	test.Printf( _L("Caps V1:\n\tiSize=0x%lx\n\tiType=%d\n\tiBattery=%d\n\tiDriveAtt=0x%x\n\tiMediaAtt=0x%x\n\tiBaseAddress=0x%x\n\tiFileSystemId=0x%x\n\tiPartitionType=0x%x\n"),
       
  1251 			DriveCaps().iSize,
       
  1252 			DriveCaps().iType,
       
  1253 			DriveCaps().iBattery,
       
  1254 			DriveCaps().iDriveAtt,
       
  1255 			DriveCaps().iMediaAtt,
       
  1256 			DriveCaps().iBaseAddress,
       
  1257 			DriveCaps().iFileSystemId,
       
  1258 			DriveCaps().iPartitionType );
       
  1259 
       
  1260 	test.Printf( _L("Caps V2:\n\tiHiddenSectors=0x%x\n\tiEraseBlockSize=0x%x\nCaps V3:\n\tiExtraInfo=%x\n\tiMaxBytesPerFormat=0x%x\n"),
       
  1261 			DriveCaps().iHiddenSectors,
       
  1262 			DriveCaps().iEraseBlockSize, 
       
  1263 			DriveCaps().iExtraInfo,
       
  1264 			DriveCaps().iMaxBytesPerFormat );
       
  1265 
       
  1266 	test.Printf( _L("Format info:\n\tiCapacity=0x%lx\n\tiSectorsPerCluster=0x%x\n\tiSectorsPerTrack=0x%x\n\tiNumberOfSides=0x%x\n\tiFatBits=%d\n"),
       
  1267 			DriveCaps().iFormatInfo.iCapacity,
       
  1268 			DriveCaps().iFormatInfo.iSectorsPerCluster,
       
  1269 			DriveCaps().iFormatInfo.iSectorsPerTrack,
       
  1270 			DriveCaps().iFormatInfo.iNumberOfSides,
       
  1271 			DriveCaps().iFormatInfo.iFATBits );
       
  1272 
       
  1273 	if(DriveCaps().iSerialNumLength > 0)
       
  1274 		{
       
  1275         test.Printf( _L("Serial Number : ") );
       
  1276         TBuf8<2*KMaxSerialNumLength> snBuf;
       
  1277         TUint i;
       
  1278 		for (i=0; i<DriveCaps().iSerialNumLength; i++)
       
  1279 			{
       
  1280             snBuf.AppendNumFixedWidth( DriveCaps().iSerialNum[i], EHex, 2 );
       
  1281 			test.Printf( _L("%02x"), DriveCaps().iSerialNum[i]);
       
  1282 			}
       
  1283 		test.Printf( _L("\n") );
       
  1284 
       
  1285 		CardType = TKnownCardTypes::EStandardCard;
       
  1286 		for(i=0; i < sizeof(KnownCardTypes) / sizeof(TKnownCardTypes); i++)
       
  1287 			{
       
  1288 			TPtrC8 serial(KnownCardTypes[i].iSerialNumber);
       
  1289 			if(snBuf.Compare(serial) == 0)
       
  1290 				{
       
  1291 				CardType = KnownCardTypes[i].iCardType;
       
  1292 				break;
       
  1293 				}
       
  1294 			}
       
  1295 		}
       
  1296 	else
       
  1297 		{
       
  1298 		test.Printf( _L("Serial Number : Not Supported") );
       
  1299 		}
       
  1300 
       
  1301 	// DriveSize - The size of the partition to which the test is connected.
       
  1302 	// MediaSize - The entire size of the media containing the partition.
       
  1303 	
       
  1304 	TInt64 mediaSize = DriveCaps().MediaSizeInBytes();
       
  1305 	TheMmcDrive.SetSize(DriveCaps().iSize, mediaSize);
       
  1306 	if(mediaSize == 0)
       
  1307 		{
       
  1308 		test.Printf(_L("Check entire media size: Not Supported\r\n"));
       
  1309 		}
       
  1310 
       
  1311 	test.Printf(_L("Entire media size: %ld\r\n"),mediaSize);
       
  1312 	test.Printf(_L("Partition size:    %ld\r\n"),DriveCaps().iSize);
       
  1313 	test.Printf(_L("Hidden sectors:    %d\r\n"),DriveCaps().iHiddenSectors);
       
  1314 	
       
  1315 	
       
  1316 	TEST_FOR_VALUE( DriveCaps().iFileSystemId, KDriveFileSysFAT );
       
  1317 	
       
  1318 	// Test that a drive >2GB is marked as requesting FAT32
       
  1319 	if( DriveCaps().iSize > KTwoGigbytes && DriveCaps().iExtraInfo)
       
  1320 		{
       
  1321 		TEST_FOR_VALUE( DriveCaps().iFormatInfo.iFATBits, TLDFormatInfo::EFB32 );
       
  1322 		}
       
  1323 
       
  1324 	TEST_FOR_VALUE( DriveCaps().iType, EMediaHardDisk );
       
  1325 	
       
  1326 	const TUint KExpectedDriveAtt = KDriveAttLocal | KDriveAttRemovable;
       
  1327 	const TUint KNotExpectedDriveAtt = KDriveAttRemote;
       
  1328 	TEST_FOR_VALUE( DriveCaps().iDriveAtt & KExpectedDriveAtt, KExpectedDriveAtt );
       
  1329 	TEST_FOR_VALUE( DriveCaps().iDriveAtt & KNotExpectedDriveAtt, 0 );
       
  1330 
       
  1331 	TUint expectedMediaAtt = KMediaAttFormattable;
       
  1332 	TUint notExpectedMediaAtt = KMediaAttVariableSize;
       
  1333 
       
  1334 	TBool isReadOnly = DriveCaps().iMediaAtt & KMediaAttWriteProtected;
       
  1335 	if(isReadOnly)
       
  1336 		{
       
  1337 		expectedMediaAtt &= ~KMediaAttFormattable;
       
  1338 
       
  1339 		test.Printf( _L("\n ---------------------------\n") );
       
  1340 		test.Printf( _L("  Media is Write Protected\n") );
       
  1341 		if((DriveCaps().iMediaAtt & KMediaAttFormattable) != KMediaAttFormattable)
       
  1342 			{
       
  1343 			test.Printf( _L("    Media is a ROM card\n") );
       
  1344 			}
       
  1345 		test.Printf( _L("  Some tests will be skipped\n") );
       
  1346 		test.Printf( _L(" ---------------------------\n") );
       
  1347 		}
       
  1348 
       
  1349 	TEST_FOR_VALUE( DriveCaps().iMediaAtt & expectedMediaAtt, expectedMediaAtt );
       
  1350 	TEST_FOR_VALUE( DriveCaps().iMediaAtt & notExpectedMediaAtt, 0 );
       
  1351 
       
  1352 	return(isReadOnly);
       
  1353 	}
       
  1354 
       
  1355 
       
  1356 /**
       
  1357 @SYMTestCaseID PBASE-T_MMCDRV-0165
       
  1358 @SYMTestCaseDesc Test MMC Card Reads
       
  1359 @SYMTestPriority High
       
  1360 
       
  1361 @SYMTestActions  
       
  1362 	a. Read 64K in one operation from the start of the media and store the contents.
       
  1363 	b. Read 512 byte blocks from the start of the media at various offsets and compare with initial read.
       
  1364 	b. Read 64K in 512 byte blocks from the start of the media and compare with the initial read.
       
  1365 	c. read 64K from the end of the drive
       
  1366 
       
  1367 @SYMTestExpectedResults All tests must pass
       
  1368 
       
  1369 @SYMPREQ1389 CR0795 Support for >2G SD Cards
       
  1370 */
       
  1371 void TestRead()
       
  1372 	{
       
  1373 	// This just tests that we can read *something* from the drive
       
  1374 	// We check elsewhere that we can read what we've written
       
  1375 	test.Next( _L("Test reading" ) );
       
  1376 
       
  1377 	HBufC8* bigBuf = HBufC8::New( 65536 );
       
  1378 	HBufC8* smallBuf = HBufC8::New( 512 );
       
  1379 
       
  1380 	test( bigBuf != NULL );
       
  1381 	test( smallBuf != NULL );
       
  1382 	TPtr8 bigPtr( bigBuf->Des() );
       
  1383 	TPtr8 smallPtr( smallBuf->Des() );
       
  1384 
       
  1385 	test.Printf( _L("Read block from start of media\n") );
       
  1386 	TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(0), 65536, bigPtr) );
       
  1387 
       
  1388 	test.Printf( _L("Read smaller blocks which should match the data in big block\n\r" ) );
       
  1389 	TInt i;
       
  1390 	for( i = 0; i <= 512; ++i )
       
  1391 		{
       
  1392 		test.Printf( _L("\toffset: %d\r"), i );
       
  1393 		TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(i), 512, smallPtr ) );
       
  1394 		test( CompareBuffers( smallBuf->Des(), bigBuf->Mid( i, 512 ) ) );
       
  1395 		}
       
  1396 
       
  1397 	for( i = 512; i <= 65536-512; i += 512 )
       
  1398 		{
       
  1399 		test.Printf( _L("\toffset: %d\r"), i );
       
  1400 		TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(i), 512, smallPtr ) );
       
  1401 		test( CompareBuffers( smallBuf->Des(), bigBuf->Mid( i, 512 ) ) );
       
  1402 		}
       
  1403 
       
  1404 	test.Printf( _L("\nTest read from end of drive\n") );
       
  1405 	
       
  1406 	if(CardType == TKnownCardTypes::EBuffalloMiniSD_512M ||	
       
  1407 	   CardType == TKnownCardTypes::EIntegralHSSD_2G)
       
  1408 		{
       
  1409 		// These cards have issues with reading at the end of the drive...
       
  1410 		test.Printf( _L(" -- Skipping Test - Known card detected --\n") );
       
  1411 		}
       
  1412 	else
       
  1413 		{
       
  1414 		TEST_FOR_ERROR( TheMmcDrive.Read( TheMmcDrive.Size() - 65536, 65536, bigPtr) );
       
  1415 		}
       
  1416 
       
  1417 	delete smallBuf;
       
  1418 	delete bigBuf;
       
  1419 	}
       
  1420 
       
  1421 
       
  1422 /**
       
  1423 @SYMTestCaseID PBASE-T_MMCDRV-0511
       
  1424 @SYMTestCaseDesc Test Moving Read/Write
       
  1425 @SYMTestPriority High
       
  1426 
       
  1427 @SYMTestActions
       
  1428 		a.) Test Read/Verify Whole Sectors
       
  1429 		b.) Test Read/Verify Sliding sector sized window
       
  1430 		c.) Test Read/Verify Sliding byte sized window
       
  1431 		d.) Test Read/Verify Increasing sized window
       
  1432 		e.) Test Write/Read/Verify Whole Sectors
       
  1433 		f.) Test Write/Read/Verify Sliding sector sized window
       
  1434 		g.) Test Write/Read/Verify Increasing sized window
       
  1435 		
       
  1436 @SYMTestExpectedResults All tests must pass
       
  1437 */
       
  1438 void DoReadWriteTest( TInt64 aPos, TInt aWindowSize, TBool aQuick )
       
  1439 	{
       
  1440 	// Do various read/write tests within a aWindowSize window starting at aPos
       
  1441 	HBufC8* wholeBuf = HBufC8::New( aWindowSize );
       
  1442 	test( wholeBuf != NULL );
       
  1443 
       
  1444 	HBufC8* readBuf = HBufC8::New( aWindowSize );
       
  1445 	test( readBuf != NULL );
       
  1446 
       
  1447 	TBuf8<512> sectorBuf;
       
  1448 	TRandGen rand;
       
  1449 	
       
  1450 	test.Printf( _L("Walking sector read\n\r") );
       
  1451 	FillRandomBuffer( wholeBuf, rand );
       
  1452 	TPtr8 wholeBufPtr( wholeBuf->Des() );
       
  1453 	TEST_FOR_ERROR( TheMmcDrive.Write( aPos, *wholeBuf ) );
       
  1454 	
       
  1455 	// Read each sector back and check that it's correct
       
  1456 	TInt64 pos( aPos );
       
  1457 	TInt i;
       
  1458 	for( i = 0; i < aWindowSize - 512; i += 512 )
       
  1459 		{
       
  1460 		pos = aPos + i;
       
  1461 		test.Printf(_L("\tRead @0x%lx\r"), pos);
       
  1462 		TEST_FOR_ERROR( TheMmcDrive.Read( pos, 512, sectorBuf ) );
       
  1463 		test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 512 ) ) );
       
  1464 		}
       
  1465 
       
  1466 	test.Printf( _L("\nSliding sector read\n\r") );
       
  1467 	// Slide a sector-sized window over the data
       
  1468 	TInt maxl = Min( aWindowSize - 512, 512 * 3 );
       
  1469 	for( i = 0; i < maxl; i++ )
       
  1470 		{
       
  1471 		pos = aPos + i;
       
  1472 		test.Printf(_L("\tRead @0x%lx\r"), pos);
       
  1473 		TEST_FOR_ERROR( TheMmcDrive.Read( pos, 512, sectorBuf ) );
       
  1474 		test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 512 ) ) );
       
  1475 		}
       
  1476 	
       
  1477 	if( !aQuick )
       
  1478 		{
       
  1479 		test.Printf( _L("\nSliding byte read\n\r") );
       
  1480 		// Slide a byte-sized window over the data
       
  1481 		for( i = 0; i < maxl; i++ )
       
  1482 			{
       
  1483 			pos = aPos + i;
       
  1484 			test.Printf(_L("\tRead @0x%lx\r"), pos);
       
  1485 			TEST_FOR_ERROR( TheMmcDrive.Read( pos, 1, sectorBuf ) );
       
  1486 			test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 1 ) ) );
       
  1487 			}
       
  1488 
       
  1489 		test.Printf( _L("\nGrowing read\n\r") );
       
  1490 		// Read from an increasing-sized window
       
  1491 		for( i = 1; i < 512; i++ )
       
  1492 			{
       
  1493 			test.Printf(_L("\tRead length: %d\r"), i);
       
  1494 			TEST_FOR_ERROR( TheMmcDrive.Read( aPos, i, sectorBuf ) );
       
  1495 			test( CompareBuffers( sectorBuf, wholeBuf->Left( i ) ) );
       
  1496 			}
       
  1497 
       
  1498 		test.Printf( _L("\nDownward-expanding read\n\r") );
       
  1499 		// Read from a window that grows downward from the end of the test region
       
  1500 		for( i = 1; i <= 512; i++ )
       
  1501 			{
       
  1502 			pos = aPos + aWindowSize - i;
       
  1503 			test.Printf(_L("\t[pos:len] %lx:%d\r"), pos, i);
       
  1504 			TEST_FOR_ERROR( TheMmcDrive.Read( pos, i, sectorBuf ) );
       
  1505 			test( CompareBuffers( sectorBuf, wholeBuf->Mid( aWindowSize - i, i ) ) );
       
  1506 			}
       
  1507 		}
       
  1508 
       
  1509 	test.Printf( _L("\nWalking sector write\n\r") );
       
  1510 	// Overwrite each sector and check the whole region is correct
       
  1511 	for( i = 0; i < aWindowSize - 512; i += 512 )
       
  1512 		{
       
  1513 		FillRandomBuffer( sectorBuf, rand );
       
  1514 		pos = aPos + i;
       
  1515 		test.Printf(_L("\tWrite @0x%lx\r"), pos);
       
  1516 		TEST_FOR_ERROR( TheMmcDrive.Write( pos, sectorBuf ) );
       
  1517 		wholeBufPtr.MidTPtr( i, 512 ) = sectorBuf;	// update our match data
       
  1518 		
       
  1519 		TPtr8 ptr( readBuf->Des() );
       
  1520 		TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) );
       
  1521 		test( CompareBuffers( *readBuf, *wholeBuf ) );
       
  1522 		}
       
  1523 
       
  1524 	if( !aQuick )
       
  1525 		{
       
  1526 		test.Printf( _L("\nSliding sector overwrite\n\r") );
       
  1527 		// Overwrite a sector-sized region that slides across the test region
       
  1528 		for( i = 0; i < maxl; i += 1 )
       
  1529 			{
       
  1530 			FillRandomBuffer( sectorBuf, rand );
       
  1531 			pos = aPos + i;
       
  1532 			test.Printf(_L("\tWrite @0x%lx\r"), pos);
       
  1533 			TEST_FOR_ERROR( TheMmcDrive.Write( pos, sectorBuf ) );
       
  1534 			wholeBufPtr.MidTPtr( i, 512 ) = sectorBuf;	// update our match data
       
  1535 			
       
  1536 			TPtr8 ptr( readBuf->Des() );
       
  1537 			TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) );
       
  1538 			test( CompareBuffers( *readBuf, *wholeBuf ) );
       
  1539 			}
       
  1540 
       
  1541 		test.Printf( _L("\nGrowing sector overwrite\n\r") );
       
  1542 		// Overwrite an expanding region starting at aPos
       
  1543 		for( i = 1; i < 512; i += 1 )
       
  1544 			{
       
  1545 			FillRandomBuffer( sectorBuf, rand );
       
  1546 			test.Printf(_L("\tWrite length: %d\r"), i);
       
  1547 			sectorBuf.SetLength( i );
       
  1548 			TEST_FOR_ERROR( TheMmcDrive.Write( aPos, sectorBuf ) );
       
  1549 			wholeBufPtr.LeftTPtr( i ) = sectorBuf;	// update our match data
       
  1550 			
       
  1551 			TPtr8 ptr( readBuf->Des() );
       
  1552 			TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) );
       
  1553 			test( CompareBuffers( *readBuf, *wholeBuf ) );
       
  1554 			}
       
  1555 		}
       
  1556 
       
  1557 	test.Printf( _L("\nTest zero-length read\n") );
       
  1558 	FillRandomBuffer( sectorBuf, rand );
       
  1559 	TEST_FOR_ERROR( TheMmcDrive.Read( aPos, 0, sectorBuf ) );
       
  1560 	TEST_FOR_VALUE( sectorBuf.Length(), 0 );
       
  1561 
       
  1562 	delete wholeBuf;
       
  1563 	delete readBuf;
       
  1564 	}
       
  1565 
       
  1566 
       
  1567 // This tests for a bug observed in certain ESanDiskMmcMobile_1GB cards which never exit the busy state
       
  1568 // when writing a buffer which is one sector bigger than the PSL buffer size (resulting in a single write
       
  1569 // request split into 2 fragments, the last of which is one sector only). The "fix" for this is to make the 
       
  1570 // PSL reject CMD23 (SET_BLOCK_COUNT) for these particular cards, forcing the PIL to issue a CMD12 (STOP_TRANSMISSION)
       
  1571 void TestFragmentedWrite(TInt aLength)
       
  1572 	{
       
  1573 	test.Next( _L("Test a large write just bigger than PSL buffer size") );
       
  1574 
       
  1575 	HBufC8* bigBuf = HBufC8::New( aLength);
       
  1576 	test( bigBuf != NULL );
       
  1577 	TPtr8 bigPtr( bigBuf->Des() );
       
  1578 
       
  1579 	TInt64 startPos = 0;
       
  1580 
       
  1581 	// for a dual-slot enabled H4, buffer size is 132K - (512 * 2) = 131K
       
  1582 
       
  1583 	
       
  1584 	test.Printf( _L("Initializing buffer contents...\n"));
       
  1585 	bigPtr.SetLength(aLength);
       
  1586 	TInt n;
       
  1587 	for (n=0; n<aLength; n++)
       
  1588 		{
       
  1589 		bigPtr[n] = (TUint8) n;
       
  1590 		}
       
  1591 
       
  1592 	bigPtr.SetLength(aLength);
       
  1593 	test.Printf( _L("Write %d sectors\n"), bigPtr.Length() / 512);
       
  1594 	TEST_FOR_ERROR( TheMmcDrive.Write( startPos, bigPtr) );
       
  1595 
       
  1596 
       
  1597 	bigPtr.SetLength(aLength);
       
  1598 	bigPtr.FillZ();
       
  1599 
       
  1600 	test.Printf( _L("Read %d sectors\n"), bigPtr.Length() / 512);
       
  1601 	TEST_FOR_ERROR( TheMmcDrive.Read( startPos, bigPtr.Length(), bigPtr) );
       
  1602 
       
  1603 	test.Printf( _L("Read #1 len %d \n"), bigPtr.Length());
       
  1604 
       
  1605 	for (n=0; n< 0 + aLength; n++)
       
  1606 		{
       
  1607 		if (bigPtr[n] != (TUint8) n)
       
  1608 			{
       
  1609 			test.Printf(_L("mismatch at %lx [0x%02x] != [0x%02x]"), n, bigPtr[n], (TUint8) n);
       
  1610 			test(0);
       
  1611 			}
       
  1612 		}
       
  1613 
       
  1614 	delete bigBuf;
       
  1615 	}
       
  1616 
       
  1617 void TestWrite()
       
  1618 	{
       
  1619 	// for a dual-slot enabled H4, buffer size is 132K - (512 * 2) = 131K
       
  1620 	TestFragmentedWrite(131*1024 + 512);
       
  1621 	// for a single-slot enabled H4, buffer size is 132K - (512 * 1) = 131K + 512
       
  1622 	TestFragmentedWrite(131*1024 + 1024);
       
  1623 
       
  1624 
       
  1625 	test.Next( _L("Test writing to drive") );
       
  1626 	DoReadWriteTest( 0, 65536, EFalse );
       
  1627 	}
       
  1628 
       
  1629 
       
  1630 /**
       
  1631 @SYMTestCaseID PBASE-T_MMCDRV-0166
       
  1632 @SYMTestCaseDesc Test MMC Card accesses at the end of the media
       
  1633 @SYMTestPriority High
       
  1634 
       
  1635 @SYMTestActions  
       
  1636 	a. If the card is not read-only, perform read/write tests at the last 64K of the media.
       
  1637 	b. Test that all accesses beyond the end of the media produce an error.
       
  1638 
       
  1639 @SYMTestExpectedResults All tests must pass
       
  1640 
       
  1641 @SYMPREQ1389 CR0795 Support for >2G SD Cards
       
  1642 */
       
  1643 void TestCapacity()
       
  1644 	{
       
  1645 	if(!IsReadOnly)
       
  1646 		{
       
  1647 		test.Next( _L("Test access at end of media") );
       
  1648 		DoReadWriteTest( TheMmcDrive.Size() - 65536, 65536, ETrue );
       
  1649 		}
       
  1650 
       
  1651 	test.Printf( _L("Test accesses past end of media produce an error\n") );
       
  1652 
       
  1653 	TBuf8<1024> buf;
       
  1654 	
       
  1655 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 1, buf ) );
       
  1656 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 2, buf ) );
       
  1657 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 512, buf ) );
       
  1658 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() + 1, 512, buf ) );
       
  1659 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() + 512, 512, buf ) );
       
  1660 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 1, 2, buf ) );
       
  1661 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 511, 512, buf ) );
       
  1662 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 512, 513, buf ) );
       
  1663 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 65536, 65537, buf ) );
       
  1664 	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 512, 1024, buf ) );
       
  1665 	}
       
  1666 
       
  1667 
       
  1668 void WriteAcrossBoundaries(TInt64 aBoundary)
       
  1669 	{
       
  1670 	test.Printf( _L("Test for aliasing around boundary\n") );
       
  1671 	TBuf8<512> bufLo;
       
  1672 	TBuf8<512> bufHi;
       
  1673 	TBuf8<8192> bufRead;
       
  1674 	
       
  1675 	bufLo.Fill( 0xE4, 512 );
       
  1676 	bufHi.Fill( 0x19, 512 );
       
  1677 
       
  1678 	TEST_FOR_ERROR( TheMmcDrive.Write( 0, bufLo ) );
       
  1679 	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) );
       
  1680 	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
       
  1681 	test( bufRead == bufLo );
       
  1682 	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) );
       
  1683 	test( bufRead == bufHi );
       
  1684 
       
  1685 	bufHi.Fill( 0xBB, 1 );
       
  1686 	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) );
       
  1687 	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
       
  1688 	test( bufRead == bufLo );
       
  1689 
       
  1690 	bufHi.Fill( 0xCC, 1 );
       
  1691 	TEST_FOR_ERROR( TheMmcDrive.Write( (aBoundary+1), bufHi ) );
       
  1692 	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
       
  1693 	test( bufRead == bufLo );
       
  1694 
       
  1695 	test.Printf( _L("Test write which ends at boundary\n") );
       
  1696 	bufHi.Fill( 0x33, 512 );
       
  1697 	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) );
       
  1698 	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) );
       
  1699 	test( bufRead == bufHi );
       
  1700 
       
  1701 	bufHi.Fill( 0x44, 512 );
       
  1702 	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512, bufHi ) );
       
  1703 	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary - 512, 512, bufRead ) );
       
  1704 	test( bufRead == bufHi );
       
  1705 
       
  1706 	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
       
  1707 	test( bufRead == bufLo );
       
  1708 
       
  1709 	bufHi.Fill( 0x33, 512 );
       
  1710 	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) );
       
  1711 	test( bufRead == bufHi );
       
  1712 
       
  1713 	test.Printf( _L("Test read-modify-write across boundary\n") );
       
  1714 	TBuf8<512> rmw;
       
  1715 	TBuf8<8192> data;
       
  1716 	rmw.Fill( 0x66, 512 );
       
  1717 	data.Fill( 0x11, 8192 );
       
  1718 	
       
  1719 	for( TInt i = 1; i < 511; ++i )
       
  1720 		{
       
  1721 		ProgressBar(i, 511, 11);
       
  1722 	
       
  1723 		// Create initial data block
       
  1724 		TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512, data ) );
       
  1725 
       
  1726 		// Read-modify-write some data
       
  1727 		TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512 + i, rmw ) );
       
  1728 
       
  1729 		// Modify buffer to what we expect
       
  1730 		data.MidTPtr( i, 512 ) = rmw;
       
  1731 
       
  1732 		// Read it back and check it matches
       
  1733 		TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary - 512, 8192, bufRead ) );
       
  1734 		test( CompareBuffers( bufRead, data ) );
       
  1735 		}
       
  1736 	test.Printf(_L("\n"));
       
  1737 	}
       
  1738 
       
  1739 
       
  1740 /**
       
  1741 @SYMTestCaseID PBASE-T_MMCDRV-0167
       
  1742 @SYMTestCaseDesc Test that the boundary >2GB doesn't produce aliases or errors
       
  1743 @SYMTestPriority High
       
  1744 
       
  1745 @SYMTestActions  
       
  1746 	a. Test that writing at the 2G boundary does not produce aliases.
       
  1747 	b. Test writes that end at the 2G boundary.
       
  1748 	c. Test read/modify/write across the 2G boundary.
       
  1749 
       
  1750 @SYMTestExpectedResults All tests must pass
       
  1751 
       
  1752 @SYMPREQ1389 CR0795 Support for >2G SD Cards
       
  1753 */
       
  1754 void TestBoundaries()
       
  1755 	{
       
  1756 
       
  1757 	if( TheMmcDrive.Size() < 0x80008000 )
       
  1758 		{
       
  1759 		test.Printf( _L("Drive not large enough for 2GB boundary test... skipped\n") );
       
  1760 		return;
       
  1761 		}
       
  1762 		
       
  1763 	// Test that the boundary 2GB doesn't produce aliases or errors
       
  1764 	// >2Gb cards change addressing scheme from byte to block base
       
  1765 	test.Next( _L("Test 2GB boundary") );	
       
  1766 	WriteAcrossBoundaries(0x80000000);
       
  1767 	
       
  1768 // N.B. Commented Out for now due to compiler warnings	
       
  1769 //	if( TheMmcDrive.Size() < 0x100008000ll )
       
  1770 //			{
       
  1771 //			test.Printf( _L("Drive not large enough for 4GB boundary test... skipped\n") );
       
  1772 //			return;
       
  1773 //			}
       
  1774 //	// Test that the boundary 4GB doesn't produce aliases or errors
       
  1775 //	// >4GB cards change addressing scheme from 32bit to 64bit addresses
       
  1776 //	test.Next( _L("Test 4GB boundary") );	
       
  1777 //	WriteAcrossBoundaries(0x100000000ll); 
       
  1778 	}
       
  1779 
       
  1780 
       
  1781 /**
       
  1782 @SYMTestCaseID PBASE-T_MMCDRV-0512
       
  1783 @SYMTestCaseDesc Test Media Change/Capabilities Reporting
       
  1784 @SYMTestPriority High
       
  1785 
       
  1786 @SYMTestActions
       
  1787 	    a.) Test Media Change flag after Media Change
       
  1788 		b.) Test Capabilities reporting for Out Of Memory Conditions
       
  1789         c.) Test Media Change flag after Machine power-off
       
  1790 		d.) Test Capabilities reporting after Machine power-off
       
  1791 		e.) Test Multiple Media Change flags after Media Change
       
  1792 
       
  1793 @SYMTestExpectedResults All tests must pass	
       
  1794 */
       
  1795 void TestMediaChange()
       
  1796 	{
       
  1797 	test.Next(_L("MMC drive: Media change"));
       
  1798 #if defined (__WINS__)
       
  1799 	test.Printf( _L("<<<Hit F5 - then any other key>>>\r\n"));
       
  1800 #else
       
  1801 	test.Printf( _L("<<<Generate Media change - then hit a key>>>\r\n"));
       
  1802 #endif
       
  1803 	test.Getch();
       
  1804 	User::After(300000);	// Allow 0.3s after power down for controller to detect door closed.
       
  1805 	test(ChangeFlag!=EFalse);
       
  1806 
       
  1807 	test.Next(_L("MMC drive: Caps following media change"));
       
  1808 	
       
  1809 	TLocalDriveCapsV4 info;
       
  1810 	TPckg<TLocalDriveCapsV4> infoPckg(info);
       
  1811 	
       
  1812 	test(TheMmcDrive.Caps(infoPckg)==KErrNone);
       
  1813 	test(info.iType==EMediaHardDisk);
       
  1814 
       
  1815 	test.Next(_L("MMC drive: Caps while OOM"));
       
  1816 	TInt err;
       
  1817 	test.Printf(_L("Mount returns:"));
       
  1818 	for (TInt j=1;j<16;j++)
       
  1819 		{
       
  1820 		__KHEAP_SETFAIL(RHeap::EDeterministic,j);
       
  1821 		err=TheMmcDrive.Caps(infoPckg);
       
  1822 		test.Printf(_L("(%d)"),err);
       
  1823 		__KHEAP_RESET;
       
  1824 		}
       
  1825 	test.Printf(_L("\r\n"));
       
  1826 
       
  1827 	test.Next(_L("MMC drive: Machine power-off."));
       
  1828 	ChangeFlag=EFalse;
       
  1829 	RTimer timer;
       
  1830 	TRequestStatus trs;
       
  1831 	test(timer.CreateLocal()==KErrNone);
       
  1832 	TTime tim;
       
  1833 	tim.HomeTime();
       
  1834 	tim+=TTimeIntervalSeconds(8);
       
  1835 	timer.At(trs,tim);
       
  1836 	UserHal::SwitchOff();
       
  1837 	User::WaitForRequest(trs);
       
  1838 	test(trs.Int()==KErrNone);
       
  1839 	test(ChangeFlag==EFalse);		// ie machine power off hasn't updated it
       
  1840 
       
  1841 	test.Next(_L("MMC drive: Caps following power off"));
       
  1842 	TInt r=TheMmcDrive.Caps(infoPckg);
       
  1843 	test(r==KErrNone);
       
  1844 	test(info.iType==EMediaHardDisk);
       
  1845 
       
  1846 	test.Next(_L("Starting 2nd thread"));
       
  1847 	SecThreadChangeFlag=EFalse;
       
  1848 	RThread thread;
       
  1849 	TRequestStatus stat;
       
  1850 	test(thread.Create(_L("Thread"),dontDisconnectThread,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone);
       
  1851 	thread.Logon(stat);
       
  1852 	thread.Resume();
       
  1853 	User::WaitForRequest(stat);
       
  1854 	test(stat==KErrNone);
       
  1855 	thread.Close();
       
  1856 
       
  1857 	test.Next(_L("MMC drive: 2nd media change"));
       
  1858 //	UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change	
       
  1859 	test(ChangeFlag!=EFalse);
       
  1860 	test(SecThreadChangeFlag==EFalse); // Closed 2nd thread so shouldn't have been updated
       
  1861 	}
       
  1862 	
       
  1863 
       
  1864 //// End of Test 
       
  1865 void Format()
       
  1866 //
       
  1867 // Format current drive
       
  1868 //
       
  1869 	{
       
  1870 	RFs TheFs;
       
  1871 	test(TheFs.Connect() == KErrNone);
       
  1872 	
       
  1873 	test.Next(_L("Format"));
       
  1874 	TBuf<4> driveBuf=_L("?:\\");
       
  1875 	driveBuf[0]=(TText)(RFsDNum+'A');
       
  1876 	
       
  1877 	RFormat format;
       
  1878 	TInt count;
       
  1879 	TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count);
       
  1880 	test(r==KErrNone);
       
  1881 	while(count)
       
  1882 		{
       
  1883 		TInt r=format.Next(count);
       
  1884 		test(r==KErrNone);
       
  1885 		}
       
  1886 	format.Close();
       
  1887 	}
       
  1888 
       
  1889 void AllocateBuffers()
       
  1890 	{
       
  1891 	test.Next(_L("Allocate Buffers"));
       
  1892 
       
  1893 	//HBufC8* wrBufH = NULL;
       
  1894 	//HBufC8* rdBufH = NULL;
       
  1895 
       
  1896 	wrBufH = HBufC8::New(KVeryLongRdWrBufLen);
       
  1897 	test(wrBufH != NULL);
       
  1898 
       
  1899 	rdBufH = HBufC8::New(KVeryLongRdWrBufLen);
       
  1900 	if(rdBufH == NULL) delete wrBufH;
       
  1901 	test(rdBufH != NULL);
       
  1902 
       
  1903 	wrBuf.Set(wrBufH->Des());
       
  1904 	rdBuf.Set(rdBufH->Des());
       
  1905 	}
       
  1906 	
       
  1907 void AllocateSharedBuffers(TBool Fragmented, TBool Caching)
       
  1908 	{
       
  1909 	// Setup SharedMemory Buffers
       
  1910 	test.Next(_L("Allocate Shared Memory\n"));
       
  1911 	
       
  1912 	RLoader l;
       
  1913 	test(l.Connect()==KErrNone);
       
  1914 	test(l.CancelLazyDllUnload()==KErrNone);
       
  1915 	l.Close();
       
  1916 
       
  1917 	test.Printf(_L("Initialise\n"));
       
  1918 	TInt r = UserHal::PageSizeInBytes(PageSize);
       
  1919 	test(r==KErrNone);
       
  1920 
       
  1921 	test.Printf(_L("Loading test driver\n"));
       
  1922 	r = User::LoadLogicalDevice(KSharedChunkLddName);
       
  1923 	test(r==KErrNone || r==KErrAlreadyExists);
       
  1924 
       
  1925 	test.Printf(_L("Opening channel\n"));
       
  1926 	r = Ldd.Open();
       
  1927 	test(r==KErrNone);
       
  1928 
       
  1929 	test.Printf(_L("Create chunk\n"));
       
  1930 	
       
  1931 	TUint aCreateFlags = EMultiple|EOwnsMemory;
       
  1932 	
       
  1933 	if (Caching)
       
  1934 		{
       
  1935 		test.Printf(_L("Chunk Type:Caching\n"));
       
  1936 		aCreateFlags |= ECached;
       
  1937 		}
       
  1938 	else
       
  1939 		test.Printf(_L("Chunk Type:Fully Blocking\n"));
       
  1940 	
       
  1941     TCommitType aCommitType = EContiguous;
       
  1942       
       
  1943     TUint TotalChunkSize = ChunkSize;  // rounded to nearest Page Size
       
  1944     
       
  1945 	TUint ChunkAttribs = TotalChunkSize|aCreateFlags;	
       
  1946 	r = Ldd.CreateChunk(ChunkAttribs);
       
  1947 	test(r==KErrNone);
       
  1948 
       
  1949 	if(Fragmented)
       
  1950 		{
       
  1951 		test.Printf(_L("Commit Fragmented Memory\n"));
       
  1952 			
       
  1953 		// Allocate Pages in reverse order to maximise memory fragmentation
       
  1954 		TUint i = ChunkSize;
       
  1955 		do
       
  1956 			{
       
  1957 			i-=PageSize;
       
  1958 			test.Printf(_L("Commit %d\n"), i);
       
  1959 			r = Ldd.CommitMemory(aCommitType|i,PageSize);
       
  1960 			test(r==KErrNone);
       
  1961 			}while (i>0);
       
  1962 		}
       
  1963 	else
       
  1964 		{
       
  1965 		test.Printf(_L("Commit Contigouos Memory\n"));
       
  1966 		r = Ldd.CommitMemory(aCommitType,TotalChunkSize);
       
  1967 		test(r==KErrNone);
       
  1968 		}
       
  1969 
       
  1970 	test.Printf(_L("Open user handle\n"));
       
  1971 	r = Ldd.GetChunkHandle(TheChunk);
       
  1972 	test(r==KErrNone);
       
  1973 	
       
  1974 	}
       
  1975 
       
  1976 
       
  1977 void DeAllocateBuffers()
       
  1978 	{
       
  1979 	delete rdBufH;
       
  1980 	delete wrBufH;
       
  1981 	}
       
  1982 
       
  1983 void DeAllocareSharedMemory()
       
  1984 	{
       
  1985 // destory chunk
       
  1986 	test.Printf(_L("Shared Memory\n"));
       
  1987 	test.Printf(_L("Close user chunk handle\n"));
       
  1988 	TheChunk.Close();
       
  1989 
       
  1990 	test.Printf(_L("Close kernel chunk handle\n"));
       
  1991 	TInt r = Ldd.CloseChunk();  // 1==DObject::EObjectDeleted
       
  1992 	test(r==1);
       
  1993 
       
  1994 	test.Printf(_L("Check chunk is destroyed\n"));
       
  1995 	r = Ldd.IsDestroyed();
       
  1996 	test(r==1);
       
  1997         
       
  1998 	test.Printf(_L("Close test driver\n"));
       
  1999 	Ldd.Close();
       
  2000 	}
       
  2001 
       
  2002 
       
  2003 TBool SetupDrivesForPlatform(TInt& aDrive, TInt &aRFsDriveNum)
       
  2004 /**
       
  2005  * Finds a MMC/SD suitable drive for testing
       
  2006  *
       
  2007  * @param aDrive  The number of the local drive to test
       
  2008  * @return TBool ETrue if a suitable drive is found, EFalse otherwise.
       
  2009  */
       
  2010 	{
       
  2011 	
       
  2012 	TDriveInfoV1Buf diBuf;
       
  2013 	UserHal::DriveInfo(diBuf);
       
  2014 	TDriveInfoV1 &di=diBuf();
       
  2015 
       
  2016 	test.Printf(_L(" iRegisteredDriveBitmask 0x%08X"), di.iRegisteredDriveBitmask);
       
  2017 
       
  2018 	aDrive  = -1;
       
  2019 	
       
  2020 	TLocalDriveCapsV5Buf capsBuf;
       
  2021 	TBusLocalDrive TBLD;
       
  2022 	TLocalDriveCapsV5& caps = capsBuf();
       
  2023 	TPtrC8 localSerialNum;
       
  2024 	TInt registeredDriveNum = 0;
       
  2025 	for(aDrive=0; aDrive < KMaxLocalDrives; aDrive++)
       
  2026 		{
       
  2027 		TInt driveNumberMask = 1 << aDrive;
       
  2028 		if ((di.iRegisteredDriveBitmask & driveNumberMask) == 0)
       
  2029 			continue;
       
  2030 
       
  2031 		test.Printf(_L(" Drive %d -  %S\r\n"), aDrive, &di.iDriveName[registeredDriveNum]);
       
  2032 
       
  2033 		// check that the card is readable (so we can ignore for empty card slots)
       
  2034 		if ((di.iDriveName[registeredDriveNum].MatchF(_L("MultiMediaCard0")) == KErrNone) ||
       
  2035 		    (di.iDriveName[registeredDriveNum].MatchF(_L("SDIOCard0")) == KErrNone))
       
  2036 			{
       
  2037 			
       
  2038 			TBool TBLDChangedFlag;
       
  2039 			TInt r = TBLD.Connect(aDrive, TBLDChangedFlag);
       
  2040 //test.Printf(_L(" Connect returned %d\n"), r);
       
  2041 			if (r == KErrNone)
       
  2042 				{
       
  2043 				r = TBLD.Caps(capsBuf);
       
  2044 				localSerialNum.Set(caps.iSerialNum, caps.iSerialNumLength);
       
  2045 				const TInt KSectSize = 512;
       
  2046 				TBuf8<KSectSize> sect;
       
  2047 				r = TBLD.Read(0, KSectSize, sect);
       
  2048 //test.Printf(_L(" Read returned %d\n"), r);
       
  2049 				
       
  2050 				TBLD.Disconnect();
       
  2051 				if (r == KErrNone)
       
  2052 					break;
       
  2053 				}
       
  2054 			}
       
  2055 		registeredDriveNum++;
       
  2056 		}
       
  2057 
       
  2058 	if(aDrive == KMaxLocalDrives)
       
  2059 		{
       
  2060 		test.Printf(_L(" MMC Drive Not Found\r\n"));
       
  2061 		return EFalse;
       
  2062 		}
       
  2063 
       
  2064 	// Work out the file server drive number (which isn't necessarily the same 
       
  2065 	// as the TBusLocalDrive drive number)
       
  2066 	RFs theFs;
       
  2067 	test(theFs.Connect() == KErrNone);
       
  2068 
       
  2069 	TInt i;
       
  2070 	for (i = EDriveA; i < EDriveZ; i++)
       
  2071 		{
       
  2072 		TMediaSerialNumber serialNum;
       
  2073 	    TInt r = theFs.GetMediaSerialNumber(serialNum, i);
       
  2074 		TInt len = serialNum.Length();
       
  2075 		TInt n;
       
  2076 		for (n=0; n<len; n+=16)
       
  2077 		{
       
  2078 		TBuf16<16*3 +1> buf;
       
  2079 			for (TInt m=n; m<n+16; m++)
       
  2080 				{
       
  2081 				TBuf16<3> hexBuf;
       
  2082 				hexBuf.Format(_L("%02X "),serialNum[m]);
       
  2083 				buf.Append(hexBuf);
       
  2084 				}
       
  2085 		buf.Append(_L("\n"));
       
  2086 		test.Printf(buf);
       
  2087 		}
       
  2088 		if (serialNum.Compare(localSerialNum) == 0)
       
  2089 			{
       
  2090 			TVolumeInfo vi;
       
  2091 	        r = theFs.Volume(vi, i);
       
  2092 			TBool sizeMatch = (vi.iSize < caps.iSize);
       
  2093 			if (sizeMatch)
       
  2094 				{
       
  2095 				aRFsDriveNum = i;
       
  2096 				break;
       
  2097 				}
       
  2098 			}
       
  2099 		
       
  2100 		}
       
  2101 	if (i == EDriveZ)
       
  2102 		{
       
  2103 		test.Printf(_L(" RFs MMC Drive Not Found\r\n"));
       
  2104 		return EFalse;
       
  2105 		}
       
  2106 
       
  2107 	theFs.Close();
       
  2108 
       
  2109 	return ETrue;
       
  2110 	}
       
  2111 
       
  2112 
       
  2113 LOCAL_D TBool ParseCommandLineArgs()
       
  2114 	{
       
  2115 	
       
  2116 	TBuf<0x100> cmd;
       
  2117 	User::CommandLine(cmd);
       
  2118 	TLex lex(cmd);
       
  2119 
       
  2120     for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken()))
       
  2121 		{
       
  2122 		if (token.CompareF(_L("-m"))== 0)
       
  2123 			{
       
  2124 			ManualMode = ETrue;
       
  2125 			continue;
       
  2126 			}
       
  2127 		}
       
  2128 	
       
  2129 	if (ManualMode)
       
  2130 		{
       
  2131 		// Get the list of drives
       
  2132 		TDriveInfoV1Buf diBuf;
       
  2133 		UserHal::DriveInfo(diBuf);
       
  2134 		TDriveInfoV1 &di=diBuf();
       
  2135 		TInt driveCount = di.iTotalSupportedDrives;
       
  2136 		
       
  2137 		//Print the list of usable drives
       
  2138 		test.Printf(_L("\nDRIVES USED AT PRESENT :\r\n"));
       
  2139 
       
  2140 		for (TInt i=0; i < driveCount; i++)
       
  2141 			{
       
  2142 			TBool flag=EFalse;
       
  2143 			RLocalDrive d;
       
  2144 			TInt r=d.Connect(i,flag);
       
  2145 			//Not all the drives are used at present
       
  2146 			if (r == KErrNotSupported)
       
  2147 				continue;
       
  2148 
       
  2149 			test.Printf(_L("%d : DRIVE NAME  :%- 16S\r\n"), i, &di.iDriveName[i]);
       
  2150 			}	
       
  2151 		
       
  2152 		test.Printf(_L("\r\nWarning - all data on removable drive will be lost.\r\n"));
       
  2153 		test.Printf(_L("<<<Hit mmc drive number to continue>>>\r\n"));
       
  2154 
       
  2155 		TChar driveToTest;
       
  2156 		driveToTest=(TUint)test.Getch();
       
  2157 		DriveNumber=((TUint)driveToTest) - '0';
       
  2158 		test(DriveNumber >= 1 && DriveNumber < di.iTotalSupportedDrives);
       
  2159 		
       
  2160 		return ETrue;
       
  2161 		}
       
  2162 	else
       
  2163 		{
       
  2164 		//Auto Mode
       
  2165 		//Lets find an MMC Drive to Test with....		
       
  2166 		return SetupDrivesForPlatform(DriveNumber, RFsDNum);
       
  2167 		}
       
  2168 	}
       
  2169 
       
  2170 
       
  2171 GLDEF_C TInt E32Main()
       
  2172 	{
       
  2173 	test.Title();
       
  2174 	test.Start(_L("Test the MultiMediaCard (MMC) media driver"));
       
  2175 
       
  2176 	if (!ParseCommandLineArgs())
       
  2177 		{
       
  2178 		test.Printf(_L("MMC Drive Not Found - Skipping test\r\n"));
       
  2179 		test.End();
       
  2180 		return(0);
       
  2181 		}
       
  2182 	
       
  2183 	AllocateBuffers();
       
  2184 
       
  2185 	test.Printf(_L("Connect to local drive (%d)\n"),DriveNumber);
       
  2186 
       
  2187 	ChangeFlag=EFalse;
       
  2188 	test(TheMmcDrive.Connect(DriveNumber,ChangeFlag)==KErrNone);
       
  2189 
       
  2190 	TTime startTime;
       
  2191 	startTime.HomeTime();
       
  2192 	
       
  2193 	IsReadOnly = TestDriveInfo();
       
  2194 
       
  2195 	// The following line causes t_mmcdrv to jump to the tests that check if the
       
  2196 	// mmc driver will carry on reading when the door is opened, but abort with
       
  2197 	// KErrGeneral when it is not.	Enabling the goto here is useful because it
       
  2198 	// allows the tester to skip the long read and write tests, which can take several
       
  2199 	// minutes on a 16Mb card, and longer if tracing is enabled.  It also stops the test
       
  2200 	// from returning when !mediaChangeSupported and not getting to the door opening tests.
       
  2201 
       
  2202 #if TEST_DOOR_CLOSE
       
  2203 	goto doorTest;
       
  2204 #endif
       
  2205 	
       
  2206 	for(TInt pass = 0; pass < TMMCDrive::EMaxTestModes; pass++) 
       
  2207 		{
       
  2208 		TInt r = KErrNone;
       
  2209 		switch (pass)
       
  2210 			{			
       
  2211 			case 0 : r = TheMmcDrive.SetTestMode(TMMCDrive::ETestPartition); break;
       
  2212 			case 1 : 
       
  2213 				// don't trash partition table in automated mode because...
       
  2214 				// cards in test rigs have often got deliberately small partition sizes to testing (!)
       
  2215 				if (!ManualMode)
       
  2216 					continue;
       
  2217 				r = TheMmcDrive.SetTestMode(TMMCDrive::ETestWholeMedia); 
       
  2218 				break; 
       
  2219 			case 2 : {
       
  2220 						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemory);
       
  2221 						AllocateSharedBuffers(EFalse,EFalse);
       
  2222 						break;
       
  2223 					 }
       
  2224 			case 3 : {
       
  2225 						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryCache); 
       
  2226 						AllocateSharedBuffers(EFalse, ETrue);
       
  2227 						break;
       
  2228 					 }
       
  2229 			case 4 : {
       
  2230 						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryFrag);
       
  2231 						AllocateSharedBuffers(ETrue, EFalse);
       
  2232 						break;
       
  2233 			         }
       
  2234 			default: {
       
  2235 						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryFragCache);
       
  2236 						AllocateSharedBuffers(ETrue, ETrue);
       
  2237 						break;
       
  2238 			         }
       
  2239 			}
       
  2240 
       
  2241 
       
  2242 		if(r == KErrNone)
       
  2243 			{
       
  2244 			TestRead();
       
  2245 			TestCapacity();
       
  2246  
       
  2247 			if(IsReadOnly == EFalse)
       
  2248 				{
       
  2249 				TestMultipleBlockReads();
       
  2250 				TestSectorReadWrite();
       
  2251 				TestWrite();
       
  2252 				TestBoundaries();
       
  2253 				TestFormat();
       
  2254 				}
       
  2255 			}
       
  2256 		
       
  2257 		if (pass > 1)
       
  2258 			{
       
  2259 			// Shared memory Test Mode in use
       
  2260 			DeAllocareSharedMemory();
       
  2261 			}
       
  2262 		}
       
  2263 
       
  2264 	if (mediaChangeSupported)
       
  2265 		{
       
  2266 		// Remainder of tests involve media change
       
  2267 		TestMediaChange();
       
  2268 		
       
  2269 		#if TEST_DOOR_CLOSE
       
  2270 doorTest:
       
  2271 		#endif
       
  2272 		test.Next(_L("Launching 1.0Mb Read to interrupt with media change.\n"));
       
  2273 		TestHugeReadWrite(ETrue, 512 * 1024);
       
  2274 
       
  2275 		test.Next(_L("Launching 1.0Mb Write to interrupt with media change.\n"));
       
  2276 		TestHugeReadWrite(EFalse, 512 * 1024);
       
  2277 		}
       
  2278 		
       
  2279 	TTime endTime;
       
  2280 	endTime.HomeTime();
       
  2281 	TTimeIntervalMicroSeconds elapsed=endTime.MicroSecondsFrom(startTime);
       
  2282 	test.Printf(_L("\n\r   (Elapsed time: %dmS)\r\n"),(elapsed.Int64()/1000));
       
  2283 	
       
  2284 	test.Printf(_L("Disconnect from local drive (%d)"),DriveNumber);
       
  2285 	TheMmcDrive.Disconnect();
       
  2286 
       
  2287 	DeAllocateBuffers();
       
  2288 
       
  2289 	// Format card with a File System i.e. FAT
       
  2290 	// Such that it is re-usable by next test
       
  2291 	Format();
       
  2292 	
       
  2293 	test.End();
       
  2294 
       
  2295 	return(0);
       
  2296 	}
       
  2297