os/kernelhwsrv/kerneltest/e32test/pccd/t_mmcdrv.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/pccd/t_mmcdrv.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2297 @@
     1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32test\pccd\t_mmcdrv.cpp
    1.18 +// Test the MultiMediaCard (MMC) media driver
    1.19 +// Spare Test case Numbers 0513-0519
    1.20 +// 
    1.21 +//
    1.22 +
    1.23 +#include "../mmu/d_sharedchunk.h"
    1.24 +#include <e32test.h>
    1.25 +#include <e32svr.h>
    1.26 +#include <e32hal.h>
    1.27 +#include <e32uid.h>
    1.28 +#include <f32fsys.h>
    1.29 +#include <e32def.h>
    1.30 +#include <e32def_private.h>
    1.31 +
    1.32 +const TInt KDiskSectorSize=512;
    1.33 +const TInt KDiskSectorShift=9;
    1.34 +const TUint KDiskSectorMask=0xFFFFFE00;
    1.35 +const TInt KSectBufSizeInSectors=8;
    1.36 +const TInt KSectBufSizeInBytes=(KSectBufSizeInSectors<<KDiskSectorShift);
    1.37 +const TInt KRdWrBufLen=(KSectBufSizeInBytes+KDiskSectorSize); // 4.5K - exceeds driver local buffer size
    1.38 +
    1.39 +const TInt KShortFormatInSectors=1;
    1.40 +const TInt KShortFormatInBytes=(KShortFormatInSectors<<KDiskSectorShift);
    1.41 +const TInt KLongFormatInSectors=KSectBufSizeInSectors+1;	// 4.5K - exceeds driver local buffer size
    1.42 +const TInt KLongFormatInBytes=(KLongFormatInSectors<<KDiskSectorShift);
    1.43 +
    1.44 +const TInt KVeryLongSectBufSizeInSectors=4096;												// ..2M
    1.45 +const TInt KVeryLongSectBufSizeInBytes=(KVeryLongSectBufSizeInSectors<<KDiskSectorShift);	//
    1.46 +const TInt KVeryLongRdWrBufLen=(KVeryLongSectBufSizeInBytes+KDiskSectorSize);				// 2M + 0.5K
    1.47 +
    1.48 +const TInt KHeapSize=0x4000;
    1.49 +
    1.50 +const TInt64 KDefaultRandSeed = MAKE_TINT64(0x501a501a, 0x501a501a);
    1.51 +
    1.52 +#define TEST_DOOR_CLOSE 	0					// see comment in E32Main()
    1.53 +
    1.54 +
    1.55 +class TMMCDrive : public TBusLocalDrive
    1.56 +	{
    1.57 +public:
    1.58 +	enum TTestMode
    1.59 +		{
    1.60 +		ETestPartition,
    1.61 +		ETestWholeMedia,
    1.62 +		ETestSharedMemory,
    1.63 +		ETestSharedMemoryCache,
    1.64 +		ETestSharedMemoryFrag,
    1.65 +		ETestSharedMemoryFragCache,
    1.66 +		EMaxTestModes
    1.67 +		};
    1.68 +public:
    1.69 +	TMMCDrive();
    1.70 +	
    1.71 +	TInt Read(TInt64 aPos, TInt aLength, TDes8& aTrg);
    1.72 +	TInt Write(TInt64 aPos, const TDesC8& aSrc);
    1.73 +
    1.74 +	TInt SetTestMode(TTestMode aTestMode);
    1.75 +	TTestMode TestMode();
    1.76 +
    1.77 +	void SetSize(TInt64 aDriveSize, TInt64 aMediaSize);
    1.78 +	TInt64 Size();
    1.79 +private:
    1.80 +	TTestMode iTestMode;
    1.81 +
    1.82 +	TInt64 iDriveSize;
    1.83 +	TInt64 iMediaSize;
    1.84 +	};
    1.85 +
    1.86 +// Serial numbers for 'special case' test cards (ie - those with known problems)
    1.87 +class TKnownCardTypes
    1.88 +	{
    1.89 +public:
    1.90 +	enum TCardType
    1.91 +		{
    1.92 +		EStandardCard = 0,
    1.93 +		EBuffalloMiniSD_32M_ERASE,
    1.94 +		EBuffalloMiniSD_64M_ERASE,
    1.95 +		EBuffalloMiniSD_128M_ERASE,
    1.96 +		EBuffalloMiniSD_256M_ERASE,
    1.97 +		EBuffalloMiniSD_512M_ERASE,
    1.98 +		EBuffalloMiniSD_512M,
    1.99 +		EIntegralHSSD_2G,
   1.100 +		ESanDiskMmcMobile_1GB
   1.101 +		};
   1.102 +
   1.103 +	TKnownCardTypes(TCardType aCardType, const TText8* aSerialNumber) 
   1.104 +		: iCardType(aCardType), iSerialNumber(aSerialNumber) {};
   1.105 +
   1.106 +	TCardType iCardType;
   1.107 +	const TText8* iSerialNumber;
   1.108 +	};
   1.109 +
   1.110 +LOCAL_D TKnownCardTypes KnownCardTypes[] = 	
   1.111 +	{
   1.112 +	//** The Following Buffalo Cards all have a known Mis-Implementation
   1.113 +	// When requesting Erase the area to be erase is specified in terms of a start (CMD32) and stop (CMD33) blocks
   1.114 +	// Specification states that CMD33 refers to the end block in terms of the first byte of that block
   1.115 +	// the Buffallo implementation requires that the last byte of the block is specified.
   1.116 +	
   1.117 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_32M_ERASE,  _S8("936300c70e150d003630333046445004")),
   1.118 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_64M_ERASE,  _S8("d96600456d120a003732343046445004")),
   1.119 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_128M_ERASE, _S8("f964000d13150c003630333046445004")),
   1.120 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_256M_ERASE, _S8("4d66004c68120a003732343046445004")),
   1.121 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M_ERASE, _S8("db6500824e0010013236333243454228")),
   1.122 +	
   1.123 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_32M_ERASE,  _S8("df6400e60d150d003630333046445004")),
   1.124 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_64M_ERASE,  _S8("296600386d120a003732343046445004")),
   1.125 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_128M_ERASE, _S8("b16400f512150c003630333046445004")),
   1.126 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_256M_ERASE, _S8("435600cc390000000000004453474b13")),
   1.127 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M_ERASE, _S8("ed6300de700000000000004453474b13")),
   1.128 +	//***********************************************************************************************//
   1.129 +	
   1.130 +	TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M, _S8("0d56004e2d0000000000004453474b13")),
   1.131 +	TKnownCardTypes(TKnownCardTypes::EIntegralHSSD_2G,     _S8("37570058073099114732304453000027")),
   1.132 +	TKnownCardTypes(TKnownCardTypes::ESanDiskMmcMobile_1GB,_S8("956a1c00001810303030303030000015"))
   1.133 +	};
   1.134 +
   1.135 +
   1.136 +LOCAL_D RTest test(_L("T_MMCDRV"));
   1.137 +LOCAL_D RTest nTest(_L("This thread doesn't disconnect"));
   1.138 +LOCAL_D TBool ChangeFlag;
   1.139 +LOCAL_D TBool SecThreadChangeFlag;
   1.140 +
   1.141 +
   1.142 +LOCAL_D TPtr8 wrBuf(NULL, KVeryLongRdWrBufLen);
   1.143 +LOCAL_D TPtr8 rdBuf(NULL, KVeryLongRdWrBufLen);
   1.144 +LOCAL_D HBufC8* wrBufH = NULL;
   1.145 +LOCAL_D HBufC8* rdBufH = NULL;
   1.146 +
   1.147 +LOCAL_D TInt DriveNumber = -1; // Local Drive number
   1.148 +LOCAL_D TInt RFsDNum = -1;	// File Server Drive number
   1.149 +LOCAL_D TMMCDrive TheMmcDrive;
   1.150 +LOCAL_D TLocalDriveCapsV5Buf DriveCaps;
   1.151 +LOCAL_D TKnownCardTypes::TCardType CardType;
   1.152 +LOCAL_D TBool IsReadOnly;
   1.153 +
   1.154 +LOCAL_D RSharedChunkLdd Ldd;
   1.155 +LOCAL_D RChunk TheChunk;
   1.156 +LOCAL_D TInt PageSize;
   1.157 +const TUint ChunkSize    = 0x201000;	//2MB+4096bytes > than largest transfer
   1.158 +
   1.159 +const TInt	 KSingSectorNo=1;
   1.160 +const TInt64 KTwoGigbytes = 0x80000000;
   1.161 +
   1.162 +TBool mediaChangeSupported=EFalse; // ???
   1.163 +TBool ManualMode=EFalse;
   1.164 +
   1.165 +// Wrappers for the test asserts
   1.166 +GLREF_C void TestIfError( TInt aValue, TInt aLine, const TText* aFile );
   1.167 +GLREF_C void TestIfErrorMsg( TInt aValue, TInt aLine, const TText* aFile, const TDesC& aMessageOnError );
   1.168 +GLREF_C void TestEqual( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile );
   1.169 +GLREF_C void TestEqualMsg( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile, const TDesC& aMessageOnError );
   1.170 +GLREF_C void TestEitherEqual( TInt aValue, TInt aExpected1, TInt aExpected2, TInt aLine, const TText* aFile );
   1.171 +GLREF_C void TestRange( TInt aValue, TInt aMin, TInt Max, TInt aLine, const TText* aFile );
   1.172 +
   1.173 +#define TEST_FOR_ERROR2( r, l, f )	TestIfError( r, l, _S(f) )
   1.174 +#define TEST_FOR_ERROR_ERRMSG2( r, l, f, m )	TestIfErrorMsg( r, l, _S(f), m )
   1.175 +#define TEST_FOR_VALUE2( r, e, l, f )	TestEqual( r, e, l, _S(f) )
   1.176 +#define TEST_FOR_VALUE_ERRMSG2( r, e, l, f, m )	TestEqualMsg( r, e, l, _S(f), m )
   1.177 +#define TEST_FOR_EITHER_VALUE2( r, e1, e2, l, f )	TestEitherEqual( r, e1, e2, l, _S(f) )
   1.178 +#define TEST_FOR_RANGE2( r, min, max, l, f )	TestRange( r, min, max, l, _S(f) )
   1.179 +
   1.180 +#define TEST_FOR_ERROR( r )	TEST_FOR_ERROR2( r, __LINE__, __FILE__ )
   1.181 +#define TEST_FOR_ERROR_ERRMSG( r, m )	TEST_FOR_ERRORMSG2( r, __LINE__, __FILE__, m )
   1.182 +#define TEST_FOR_VALUE( r, expected )	TEST_FOR_VALUE2( r, expected, __LINE__, __FILE__ )
   1.183 +#define TEST_FOR_VALUE_ERRMSG( r, expected, m )	TEST_FOR_VALUE_ERRMSG2( r, expected, __LINE__, __FILE__, m )
   1.184 +#define TEST_FOR_EITHER_VALUE( r, expected1, expected2 )	TEST_FOR_EITHER_VALUE2( r, expected1, expected2, __LINE__, __FILE__ )
   1.185 +#define TEST_FOR_RANGE( r, min, max )	TEST_FOR_RANGE2( r, min, max, __LINE__, __FILE__ )
   1.186 +
   1.187 +GLDEF_C void TestIfError( TInt aValue, TInt aLine, const TText* aFile )
   1.188 +	{
   1.189 +	if( aValue < 0 )
   1.190 +		{
   1.191 +		_LIT( KErrorTestFailMsg, "ERROR %d\n\r" );
   1.192 +		test.Printf( KErrorTestFailMsg, aValue );
   1.193 +		test.operator()( EFalse, aLine, (const TText*)(aFile) );
   1.194 +		}
   1.195 +	}
   1.196 +
   1.197 +GLDEF_C void TestIfErrorMsg( TInt aValue, TInt aLine, const TText* aFile, const TDesC& aMessageOnError )
   1.198 +	{
   1.199 +	if( aValue < 0 )
   1.200 +		{
   1.201 +		_LIT( KErrorTestFailMsg, "ERROR %d %S\n\r" );
   1.202 +		test.Printf( KErrorTestFailMsg, aValue, &aMessageOnError );
   1.203 +		test.operator()( EFalse, aLine, (const TText*)(aFile) );
   1.204 +		}
   1.205 +	}
   1.206 +
   1.207 +
   1.208 +GLDEF_C void TestEqual( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile )
   1.209 +	{
   1.210 +	if( aExpected != aValue )
   1.211 +		{
   1.212 +		_LIT( KEqualTestFailMsg, "ERROR %d expected %d\n\r" );
   1.213 +		test.Printf( KEqualTestFailMsg, aValue, aExpected );
   1.214 +		test.operator()( EFalse, aLine, (const TText*)(aFile) );
   1.215 +		}
   1.216 +	}
   1.217 +
   1.218 +GLDEF_C void TestEqualMsg( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile, const TDesC& aMessageOnError )
   1.219 +	{
   1.220 +	if( aExpected != aValue )
   1.221 +		{
   1.222 +		_LIT( KEqualTestFailMsg, "ERROR %d expected %d %S\n\r" );
   1.223 +		test.Printf( KEqualTestFailMsg, aValue, aExpected, &aMessageOnError );
   1.224 +		test.operator()( EFalse, aLine, (const TText*)(aFile) );
   1.225 +		}
   1.226 +	}
   1.227 +
   1.228 +GLDEF_C void TestEitherEqual( TInt aValue, TInt aExpected1, TInt aExpected2, TInt aLine, const TText* aFile )
   1.229 +	{
   1.230 +	if( (aExpected1 != aValue) && (aExpected2 != aValue) )
   1.231 +		{
   1.232 +		_LIT( KEqualTestFailMsg, "ERROR %d expected %d or %d\n\r" );
   1.233 +		test.Printf( KEqualTestFailMsg, aValue, aExpected1, aExpected2 );
   1.234 +		test.operator()( EFalse, aLine, (const TText*)(aFile) );
   1.235 +		}
   1.236 +	}
   1.237 +
   1.238 +GLDEF_C void TestRange( TInt aValue, TInt aMin, TInt aMax, TInt aLine, const TText* aFile )
   1.239 +	{
   1.240 +	if( (aValue < aMin) || (aValue > aMax) )
   1.241 +		{
   1.242 +		_LIT( KRangeTestFailMsg, "ERROR 0x%x expected 0x%x..0x%x\n\r" );
   1.243 +		test.Printf( KRangeTestFailMsg, aValue, aMin, aMax );
   1.244 +		test.operator()( EFalse, aLine, (const TText*)(aFile) );
   1.245 +		}
   1.246 +	}
   1.247 +
   1.248 +////
   1.249 +
   1.250 +TMMCDrive::TMMCDrive()
   1.251 +  : iTestMode(ETestPartition),
   1.252 +    iDriveSize(0),
   1.253 +    iMediaSize(0)
   1.254 +	{
   1.255 +	}
   1.256 +
   1.257 +TInt TMMCDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg)
   1.258 +	{
   1.259 +	if(iTestMode == ETestWholeMedia)
   1.260 +		{
   1.261 +		return TBusLocalDrive::Read(aPos, aLength, &aTrg, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
   1.262 +		}
   1.263 +	else if(iTestMode != ETestPartition && aLength <= (TInt)ChunkSize)
   1.264 +		{
   1.265 +		TPtr8 wholeBufPtr(TheChunk.Base(),aLength);
   1.266 +	
   1.267 +		TInt r = TBusLocalDrive::Read(aPos, aLength, wholeBufPtr);
   1.268 +	
   1.269 +		aTrg.Copy(wholeBufPtr);
   1.270 +		return r;
   1.271 +		}
   1.272 +	
   1.273 +	return TBusLocalDrive::Read(aPos, aLength, aTrg);
   1.274 +	}
   1.275 +
   1.276 +TInt TMMCDrive::Write(TInt64 aPos,const TDesC8& aSrc)
   1.277 +	{
   1.278 +	if(iTestMode == ETestWholeMedia)
   1.279 +		{
   1.280 +		return TBusLocalDrive::Write(aPos, aSrc.Length(), &aSrc, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
   1.281 +		}
   1.282 +	else if(iTestMode != ETestPartition && aSrc.Length() <= (TInt)ChunkSize)
   1.283 +		{		
   1.284 +		TPtr8 wholeBufPtr(TheChunk.Base(),aSrc.Length());
   1.285 +		wholeBufPtr.Copy(aSrc);
   1.286 +	
   1.287 +		TInt r = TBusLocalDrive::Write(aPos, wholeBufPtr);
   1.288 +		
   1.289 +		return r;
   1.290 +		}
   1.291 +		
   1.292 +	return TBusLocalDrive::Write(aPos, aSrc);
   1.293 +	}
   1.294 +
   1.295 +TInt TMMCDrive::SetTestMode(TTestMode aTestMode)
   1.296 +	{
   1.297 +	switch (aTestMode) 
   1.298 +		{
   1.299 +		case ETestWholeMedia   : 		test.Printf(_L("\nTesting Whole Media\n")); break;
   1.300 +		case ETestPartition    : 		test.Printf(_L("\nTesting Partition\n")); break;
   1.301 +		case ETestSharedMemory : 		test.Printf(_L("\nTesting Shared Memory\n")); break;
   1.302 +		case ETestSharedMemoryCache : 	test.Printf(_L("\nTesting Shared Memory (Caching)\n")); break;
   1.303 +		case ETestSharedMemoryFrag : 	test.Printf(_L("\nTesting Shared Memory (Fragmented)\n")); break;
   1.304 +		default :           			test.Printf(_L("\nTesting Shared Memory (Fragmented/Caching)\n")); break;
   1.305 +		}
   1.306 +
   1.307 +	if(aTestMode == ETestWholeMedia && iMediaSize == 0)
   1.308 +		{
   1.309 +		test.Printf(_L("...not supported"));
   1.310 +		return KErrNotSupported;
   1.311 +		}
   1.312 +
   1.313 +	iTestMode = aTestMode;
   1.314 +	return KErrNone;
   1.315 +	}
   1.316 +
   1.317 +TMMCDrive::TTestMode TMMCDrive::TestMode()
   1.318 +	{
   1.319 +	return iTestMode;
   1.320 +	}
   1.321 +
   1.322 +void TMMCDrive::SetSize(TInt64 aDriveSize, TInt64 aMediaSize)
   1.323 +	{
   1.324 +	iDriveSize = aDriveSize;
   1.325 +	iMediaSize = aMediaSize;
   1.326 +	}
   1.327 +
   1.328 +TInt64 TMMCDrive::Size()
   1.329 +	{
   1.330 +	switch (iTestMode)
   1.331 +		{
   1.332 +		case ETestWholeMedia : return iMediaSize;
   1.333 +		default 			 : return iDriveSize;
   1.334 +		}
   1.335 +	}
   1.336 +
   1.337 +//////
   1.338 +
   1.339 +GLDEF_C void DumpBuffer( const TDesC8& aBuffer )
   1.340 +	/**
   1.341 +	 * Dump the content of aBuffer in hex
   1.342 +	 */
   1.343 +	{
   1.344 +	static const TText hextab[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
   1.345 +										'A', 'B', 'C', 'D', 'E', 'F' };
   1.346 +	const TInt KBytesPerLine = 32;
   1.347 +	const TInt KCharsPerLine = KBytesPerLine * 2;
   1.348 +
   1.349 +	TInt remaining = aBuffer.Length();
   1.350 +	TUint8* pSrc = const_cast<TUint8*>(aBuffer.Ptr());
   1.351 +
   1.352 +	TBuf<KCharsPerLine> line;
   1.353 +	line.SetLength( KCharsPerLine );	// don't need to print trailing space
   1.354 +	TInt bytesPerLine = KBytesPerLine;
   1.355 +	TInt lineOffs = 0;
   1.356 +	while( remaining )
   1.357 +		{
   1.358 +		if( remaining < KBytesPerLine )
   1.359 +			{
   1.360 +			bytesPerLine = remaining;
   1.361 +			line.SetLength( (bytesPerLine*2) );
   1.362 +			}
   1.363 +		TUint16* pDest = const_cast<TUint16*>(line.Ptr());
   1.364 +		remaining -= bytesPerLine;
   1.365 +		for( TInt i = bytesPerLine; i > 0; --i )
   1.366 +			{
   1.367 +			TUint8 c = *pSrc++;
   1.368 +			*pDest++ = hextab[c >> 4];
   1.369 +			*pDest++ = hextab[c & 0xF];
   1.370 +			}
   1.371 +		_LIT( KFmt, "%06x: %S\n\r" );
   1.372 +		test.Printf( KFmt, lineOffs, &line );
   1.373 +		lineOffs += bytesPerLine;
   1.374 +		}
   1.375 +	}
   1.376 +
   1.377 +
   1.378 +GLDEF_C TBool CompareBuffers( const TDesC8& aBuf1, const TDesC8& aBuf2 )
   1.379 +	{
   1.380 +	TInt count = 32;
   1.381 +	if (aBuf1.Length() < count) 
   1.382 +		count = aBuf1.Length();
   1.383 +
   1.384 +	
   1.385 +	for (TInt i = 0; i < (aBuf1.Length()-count); i+= count)
   1.386 +		{
   1.387 +		if( aBuf1.Mid(i,count).Compare(aBuf2.Mid(i,count)) != 0)
   1.388 +			{
   1.389 +			// now need to find where mismatch ends
   1.390 +			TInt j =i;
   1.391 +			for (; j <= (aBuf1.Length()-count); j+= count)
   1.392 +				{
   1.393 +				if( aBuf1.Mid(j,count).Compare(aBuf2.Mid(j,count)) == 0) break;
   1.394 +				}
   1.395 +			test.Printf(_L("buf1 len: %d, buf2 len: %d\n"),aBuf1.Length(),aBuf2.Length());
   1.396 +			test.Printf( _L("Buffer mismatch @%d to %d (%d Bytes)\n\r"),i,j, (j-i) );
   1.397 +			test.Printf( _L("buffer 1 ------------------\n\r") );
   1.398 +			DumpBuffer( aBuf1.Mid(i,(j-i)) );
   1.399 +			test.Printf( _L("buffer 2 ------------------\n\r") );
   1.400 +			DumpBuffer( aBuf2.Mid(i,(j-i)) );
   1.401 +			test.Printf(_L("buf1 len: %d, buf2 len: %d\n"),aBuf1.Length(),aBuf2.Length());
   1.402 +			test.Printf( _L("Buffer mismatch @%d to %d (%d Bytes)\n\r"),i,j, (j-i) );
   1.403 +			return EFalse;
   1.404 +			}
   1.405 +		}
   1.406 +	return ETrue;
   1.407 +	}
   1.408 +
   1.409 +
   1.410 +void singleSectorRdWrTest(TInt aSectorOffset,TInt aLen)
   1.411 +//
   1.412 +// Perform a write / read test on a single sector (KSingSectorNo). Verify that the
   1.413 +// write / read back is successful and that the rest of the sector is unchanged.
   1.414 +//
   1.415 +	{
   1.416 +
   1.417 +	TBuf8<KDiskSectorSize> saveBuf;
   1.418 +	test.Start(_L("Single sector write/read test"));
   1.419 +	test(aSectorOffset+aLen<=KDiskSectorSize);
   1.420 +
   1.421 +	// Now save state of sector before we write to it
   1.422 +	TInt secStart=(KSingSectorNo<<KDiskSectorShift);
   1.423 +	test(TheMmcDrive.Read(secStart,KDiskSectorSize,saveBuf)==KErrNone);
   1.424 +
   1.425 +	// Write zero's to another sector altogether (to ensure drivers 
   1.426 +	// local buffer hasn't already got test pattern we expect).
   1.427 +	wrBuf.Fill(0,KDiskSectorSize);
   1.428 +	test(TheMmcDrive.Write((KSingSectorNo+4)<<KDiskSectorShift,wrBuf)==KErrNone);
   1.429 +
   1.430 +	// Write / read back sector in question
   1.431 +	wrBuf.SetLength(aLen);
   1.432 +	for (TInt i=0;i<aLen;i++)
   1.433 +		wrBuf[i]=(TUint8)(0xFF-i);
   1.434 +	test(TheMmcDrive.Write((secStart+aSectorOffset),wrBuf)==KErrNone);
   1.435 +	rdBuf.Fill(0,aLen);
   1.436 +	test(TheMmcDrive.Read((secStart+aSectorOffset),aLen,rdBuf)==KErrNone);
   1.437 +	test(CompareBuffers(rdBuf, wrBuf));
   1.438 +	//test(rdBuf.Compare(wrBuf)==0);
   1.439 +
   1.440 +	// Now check the rest of the sector is unchanged
   1.441 +	rdBuf.Fill(0,KDiskSectorSize);
   1.442 +	test(TheMmcDrive.Read(secStart,KDiskSectorSize,rdBuf)==KErrNone);
   1.443 +	saveBuf.Replace(aSectorOffset,aLen,wrBuf);
   1.444 +	test(CompareBuffers(rdBuf, saveBuf));
   1.445 +	test.End();
   1.446 +	}
   1.447 +
   1.448 +const TInt KMultSectorNo=2; 
   1.449 +
   1.450 +void MultipleSectorRdWrTestMB(TInt aFirstSectorOffset, TInt aLen, TBool aWrMB, TBool aRdMB)
   1.451 +//
   1.452 +// Perform a write / read test over multiple sectors (starting within sector KMultSectorNo).
   1.453 +// Verify that the write / read back is successful and that the remainder of the first and
   1.454 +// last sectors are not affected.
   1.455 +//
   1.456 +	{
   1.457 +
   1.458 +	TBuf8<KDiskSectorSize> saveBuf1;
   1.459 +	TBuf8<KDiskSectorSize> saveBuf2;
   1.460 +
   1.461 +	test.Printf(_L("   MBW[%d] : MBR[%d]\n\r"), aWrMB, aRdMB);
   1.462 +	
   1.463 +	test(aFirstSectorOffset<KDiskSectorSize&&aLen<=KVeryLongRdWrBufLen);
   1.464 +
   1.465 +	// If not starting on sector boundary then save 1st sector to check rest of 1st sector is unchanged
   1.466 +	TInt startSecPos=(KMultSectorNo<<KDiskSectorShift);
   1.467 +	if (aFirstSectorOffset!=0)
   1.468 +		test(TheMmcDrive.Read(startSecPos,KDiskSectorSize,saveBuf1)==KErrNone);
   1.469 +
   1.470 +	// If not ending on sector boundary then save last sector to check rest of last sector is unchanged
   1.471 +	TInt endOffset=(aFirstSectorOffset+aLen)&(~KDiskSectorMask);
   1.472 +	TInt endSecPos=((startSecPos+aFirstSectorOffset+aLen)&KDiskSectorMask);
   1.473 +	if (endOffset)
   1.474 +		{
   1.475 +		test(TheMmcDrive.Read(endSecPos,KDiskSectorSize,saveBuf2)==KErrNone);
   1.476 +		}
   1.477 +
   1.478 +	// Write zero's to another sector altogether (to ensure drivers 
   1.479 +	// local buffer hasn't already got test pattern we expect).
   1.480 +	wrBuf.Fill(0,KSectBufSizeInBytes);
   1.481 +	test(TheMmcDrive.Write((endSecPos+(2*KDiskSectorSize)),wrBuf)==KErrNone);
   1.482 +	
   1.483 +	TInt i;
   1.484 +
   1.485 +	wrBuf.SetLength(aLen);
   1.486 +	for (i=0;i<aLen;i++)
   1.487 +		{
   1.488 +		wrBuf[i]=(TUint8)(0xFF-i);
   1.489 +		}
   1.490 +
   1.491 +	if(aWrMB)
   1.492 +		{
   1.493 +		test(TheMmcDrive.Write((startSecPos+aFirstSectorOffset),wrBuf)==KErrNone);
   1.494 +		}
   1.495 +	else
   1.496 +		{
   1.497 +		for (i=0;i<aLen;i+=512)
   1.498 +			{
   1.499 +			TInt thisLen = (aLen-i) < 512 ? (aLen-i) : 512;
   1.500 +			TPtrC8 sectorWr(wrBuf.Mid(i, thisLen).Ptr(), thisLen);
   1.501 +			test(TheMmcDrive.Write((startSecPos+aFirstSectorOffset+i), sectorWr)==KErrNone);
   1.502 +			}
   1.503 +		}
   1.504 +
   1.505 +	rdBuf.Fill(0,aLen);
   1.506 +	rdBuf.SetLength(aLen);
   1.507 +
   1.508 +	if(aRdMB)
   1.509 +		{
   1.510 +		test(TheMmcDrive.Read((startSecPos+aFirstSectorOffset),aLen,rdBuf) == KErrNone);
   1.511 +		}
   1.512 +	else
   1.513 +		{
   1.514 +		for (i=0;i<aLen;i+=512)
   1.515 +			{
   1.516 +			TInt thisLen = (aLen-i) < 512 ? (aLen-i) : 512;
   1.517 +			TPtr8 sectorRd(((TUint8*)(rdBuf.Ptr()))+i, thisLen, thisLen);
   1.518 +			test(TheMmcDrive.Read((startSecPos+aFirstSectorOffset+i), thisLen, sectorRd) == KErrNone);
   1.519 +			}
   1.520 +		}
   1.521 +
   1.522 +	test(CompareBuffers(rdBuf, wrBuf));
   1.523 +
   1.524 +	// Check rest of first sector involved is unchanged (if offset specified)
   1.525 +	if (aFirstSectorOffset!=0)
   1.526 +		{
   1.527 +		rdBuf.Fill(0,KDiskSectorSize);
   1.528 +		test(TheMmcDrive.Read(startSecPos,KDiskSectorSize,rdBuf)==KErrNone);
   1.529 +		wrBuf.SetLength(KDiskSectorSize-aFirstSectorOffset);
   1.530 +		saveBuf1.Replace(aFirstSectorOffset,(KDiskSectorSize-aFirstSectorOffset),wrBuf);
   1.531 +		test(rdBuf.Compare(saveBuf1)==0);
   1.532 +		}
   1.533 +
   1.534 +	// Check rest of last sector involved is unchanged (if not ending on sector boundary)
   1.535 +	if (endOffset)
   1.536 +		{
   1.537 +		rdBuf.Fill(0,KDiskSectorSize);
   1.538 +		test(TheMmcDrive.Read(endSecPos,KDiskSectorSize,rdBuf)==KErrNone);
   1.539 +		wrBuf.SetLength(aLen);
   1.540 +		wrBuf.Delete(0,aLen-endOffset);
   1.541 +		saveBuf2.Replace(0,endOffset,wrBuf);
   1.542 +		test(CompareBuffers(rdBuf, saveBuf2));
   1.543 +		}
   1.544 +	}
   1.545 +
   1.546 +void MultipleSectorRdWrTest(TInt aFirstSectorOffset,TInt aLen, TBool aMBOnly = EFalse)
   1.547 +//
   1.548 +// Perform a write / read test over multiple sectors (starting within sector KMultSectorNo).
   1.549 +// Verify that the write / read back is successful and that the remainder of the first and
   1.550 +// last sectors are not affected.
   1.551 +//
   1.552 +	{
   1.553 +	test.Start(_L("Multiple sector write/read test"));
   1.554 +
   1.555 +	if(!aMBOnly)
   1.556 +		{
   1.557 +		MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, EFalse, EFalse);
   1.558 +		MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, EFalse, ETrue);
   1.559 +		MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, ETrue,  EFalse);
   1.560 +		}
   1.561 +
   1.562 +	MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, ETrue,  ETrue);
   1.563 +
   1.564 +	test.End();
   1.565 +	}
   1.566 +
   1.567 +LOCAL_C TInt dontDisconnectThread(TAny*)
   1.568 +	{
   1.569 +
   1.570 +	TBusLocalDrive anotherMmcDrive;
   1.571 +	nTest.Title();
   1.572 +
   1.573 +	nTest.Start(_L("Connect to internal drive"));
   1.574 +	anotherMmcDrive.Connect(DriveNumber,SecThreadChangeFlag);
   1.575 +
   1.576 +	nTest.Next(_L("Capabilities"));
   1.577 +	TLocalDriveCapsV2 info;
   1.578 +	TPckg<TLocalDriveCapsV2> infoPckg(info);
   1.579 +	nTest(anotherMmcDrive.Caps(infoPckg)==KErrNone);
   1.580 +	nTest(info.iType==EMediaHardDisk);
   1.581 +
   1.582 +	nTest.End();
   1.583 +	return(KErrNone);
   1.584 +	}
   1.585 +
   1.586 +LOCAL_C void ProgressBar(TInt64 aPos,TInt64 anEndPos,TInt anXPos)
   1.587 +//
   1.588 +// Display progress of local drive operation on screen (1-16 dots)
   1.589 +//
   1.590 +	{
   1.591 +	static TInt64 prev;
   1.592 +	TInt64 curr;
   1.593 +	if ((curr=(aPos-1)/(anEndPos>>4))>prev)
   1.594 +		{ // Update progress bar
   1.595 +		test.Console()->SetPos(anXPos);
   1.596 +		for (TInt64 i=curr;i>=0;i--)
   1.597 +			test.Printf(_L("."));
   1.598 +		}
   1.599 +	prev=curr;
   1.600 +	}
   1.601 +
   1.602 +
   1.603 +/**
   1.604 +@SYMTestCaseID PBASE-T_MMCDRV-0510
   1.605 +@SYMTestCaseDesc Test Write/Read during media Change
   1.606 +@SYMTestPriority High
   1.607 +
   1.608 +@SYMTestActions
   1.609 +		a.) Test Read during a Media Change
   1.610 +		b.) Test Write during a Media Change
   1.611 +
   1.612 +@SYMTestExpectedResults All tests must pass
   1.613 +*/
   1.614 +LOCAL_C void TestHugeReadWrite(TBool aIsRead, TInt aLen)
   1.615 +//
   1.616 +// Writes aLen bytes to the MMC drive.  Gives user enough time to flip the media
   1.617 +// change switch.  Request should abort with KErrNotReady on write command, but nothing
   1.618 +// on read command.
   1.619 +// Each read or write is started from sector KMultSectNo (2).
   1.620 +// The media change operation only works when the switch is moved from the closed position
   1.621 +// to the open position.
   1.622 +// 
   1.623 +	{
   1.624 +	test.Start(_L("TestHugeReadWrite: media change during I/O test."));
   1.625 +	test.Printf(_L("aIsRead = %x, aLen = %x.\n"), aIsRead, aLen);
   1.626 +
   1.627 +	HBufC8 *buf = HBufC8::New(aLen);
   1.628 +	test(buf != NULL);
   1.629 +
   1.630 +	TInt startSectPos = KMultSectorNo << KDiskSectorShift;
   1.631 +	if (aIsRead)
   1.632 +		{
   1.633 +		test.Printf(_L("Launching %08x byte read at %08x.\n"), aLen, startSectPos);
   1.634 +		test.Printf(_L("Move media change from closed to open position before finished.\n"));
   1.635 +		TPtr8 ptr(buf->Des());
   1.636 +		TInt r = TheMmcDrive.Read(startSectPos, aLen, ptr);
   1.637 +		test.Printf(_L("r = %d.\n"), r);
   1.638 +		test(r == KErrNone);
   1.639 +		}
   1.640 +	else
   1.641 +		{
   1.642 +		buf->Des().Fill(0xff, aLen);
   1.643 +		test.Printf(_L("Launching %08x byte write at %08x.\n"), aLen, startSectPos);
   1.644 +		test.Printf(_L("Move media change from closed to open position before finished.\n"));
   1.645 +		TInt r = TheMmcDrive.Write(startSectPos, *buf);
   1.646 +		test.Printf(_L("r = %d.\n"), r);
   1.647 +		test(r == KErrNotReady);
   1.648 +		}
   1.649 +	
   1.650 +	test.Printf(_L("Pausing for 5 seconds to move media change switch back to closed.\n"));
   1.651 +	User::After(5 * 1000 * 1000);
   1.652 +	delete buf;
   1.653 +	test.End();
   1.654 +	}
   1.655 +
   1.656 +
   1.657 +LOCAL_C void FillBufferWithPattern(TDes8 &aBuf)
   1.658 +//
   1.659 +// Fills aBuf with cycling hex digits up to aBuf.Length().
   1.660 +//
   1.661 +	{
   1.662 +	TInt len = aBuf.Length() & ~3;
   1.663 +	for (TInt i = 0; i < len; i+=4)
   1.664 +		{
   1.665 +		*((TUint32*) &aBuf[i]) = i;
   1.666 +		}
   1.667 +	}
   1.668 +
   1.669 +
   1.670 +LOCAL_C void WriteAndReadBack(TInt64 aStartPos, const TDesC8 &aWrBuf)
   1.671 +//
   1.672 +// This function tests the multiple block reads when aWrBuf is sufficiently large.
   1.673 +//
   1.674 +	{
   1.675 +	test.Start(_L("WriteAndReadBack"));
   1.676 +
   1.677 +	TInt r;										// general error values
   1.678 +
   1.679 +	// Allocate a same size buffer to read back into and compare with.
   1.680 +	HBufC8 *rdBuf = aWrBuf.Alloc();
   1.681 +	test(rdBuf != NULL);
   1.682 +	TPtr8 rdPtr(rdBuf->Des());
   1.683 +	
   1.684 +	test.Next(_L("wrb: writing"));
   1.685 +	r = TheMmcDrive.Write(aStartPos, aWrBuf);
   1.686 +	test.Printf(_L("\nwrb:r=%d"), r);
   1.687 +	test(r == KErrNone);
   1.688 +
   1.689 +	test.Printf(_L("\n"));
   1.690 +	test.Next(_L("wrb: reading"));
   1.691 +	r = TheMmcDrive.Read(aStartPos, rdPtr.Length(), rdPtr);
   1.692 +	test.Printf(_L("rb:r=%d"), r);
   1.693 +	test(r == KErrNone);
   1.694 +
   1.695 +	// Compare the pattern that has just been read back with the original.
   1.696 +	test.Printf(_L("\n"));
   1.697 +	test.Next(_L("wrb: comparing"));
   1.698 +	test.Printf(
   1.699 +		_L("rdPtr.Length() = %04x, aWrBuf.Length() = %04x"),
   1.700 +		rdPtr.Length(), aWrBuf.Length());
   1.701 +	test(rdPtr == aWrBuf);
   1.702 +
   1.703 +#if 0											// extra debug when buffers not compare.
   1.704 +	for (TInt j = 0; j < rdPtr.Length(); j++)
   1.705 +		{
   1.706 +		test.Printf(_L("%d: w%02x r%02x"), j, aWrBuf[j], rdBuf[j]);
   1.707 +
   1.708 +		if (rdPtr[j] != aWrBuf[j])
   1.709 +			{
   1.710 +			test.Printf(_L("buffer mismatch at %04x: %02x v %02x"), j, rdPtr[j], aWrBuf[j]);
   1.711 +			test(EFalse);
   1.712 +			}
   1.713 +		}
   1.714 +#endif
   1.715 +
   1.716 +	test.Printf(_L("\n"));
   1.717 +	delete rdBuf;
   1.718 +	test.End();
   1.719 +	}
   1.720 +
   1.721 +/**
   1.722 +@SYMTestCaseID PBASE-T_MMCDRV-0169
   1.723 +@SYMTestCaseDesc Test Multiple Block Reads
   1.724 +@SYMTestPriority High
   1.725 +
   1.726 +@SYMTestActions
   1.727 +		a.) Test Multiple Block Reads at the internal buffer size
   1.728 +		b.) Test Multiple Block Reads greater than the internal buffer size
   1.729 +
   1.730 +@SYMTestExpectedResults All tests must pass
   1.731 +
   1.732 +@TODO: increase Buffer size to match current reference platform (128KB)
   1.733 +*/
   1.734 +LOCAL_C void TestMultipleBlockReads()
   1.735 +	{
   1.736 +	// Test multiple block reads.
   1.737 +	static TBuf8<256 * 1024> rw_wrBuf;
   1.738 +
   1.739 +	rw_wrBuf.SetLength(rw_wrBuf.MaxLength());
   1.740 +	FillBufferWithPattern(rw_wrBuf);
   1.741 +
   1.742 +	test.Next(_L("Testing multiple block reads at internal buffer size"));
   1.743 +	rw_wrBuf.SetLength(8 * KDiskSectorSize);
   1.744 +	WriteAndReadBack(KMultSectorNo << KDiskSectorShift, rw_wrBuf);
   1.745 +
   1.746 +	test.Next(_L("Testing multiple block reads at gt internal buffer size"));
   1.747 +	rw_wrBuf.SetLength(10 * KDiskSectorSize);
   1.748 +	WriteAndReadBack(KMultSectorNo << KDiskSectorShift, rw_wrBuf);
   1.749 +
   1.750 +	test.Next(_L("Testing unaligned large block read "));
   1.751 +	rw_wrBuf.SetLength(rw_wrBuf.MaxLength());
   1.752 +	WriteAndReadBack((KMultSectorNo << KDiskSectorShift) + 128, rw_wrBuf);
   1.753 +	}
   1.754 +
   1.755 +
   1.756 +/**
   1.757 +@SYMTestCaseID PBASE-T_MMCDRV-0558
   1.758 +@SYMTestCaseDesc Test Long Read/Write Boundaries
   1.759 +@SYMTestPriority High
   1.760 +
   1.761 +@SYMTestActions  
   1.762 +	
   1.763 +  Perform and Write/Read/Verify for the given length (L) of data across the following boundaries.
   1.764 +  Depending on the length provided, this will also perform a partial write/read at the end sector.
   1.765 +
   1.766 +									 -------------------
   1.767 +									| Start	|	End		|
   1.768 +									|-------------------|
   1.769 +									| 0		|	L		|
   1.770 +									| 507	|	L-507	|
   1.771 +									| 10	|	L		|
   1.772 +									| 0		|	L-3		|
   1.773 +									| 27	|	L-512	|
   1.774 +									| 0		|	L-509	|
   1.775 +									| 3		|	L-3		|
   1.776 +									 -------------------
   1.777 +
   1.778 +  For each combination, the write/read/verify operations are performed in the following sequence:
   1.779 +
   1.780 +	a: Write and Read in single 512-byte blocks.
   1.781 +	b: Write in a single operation (multiple blocks), Read in 512-Byte blocks.
   1.782 +	c: Write in 512-Byte blocks, Read in a single operation (multiple-blocks).
   1.783 +	d: Write and Read in a single operation (multiple-blocks).
   1.784 +
   1.785 +  In the cases where a partial read/write operation occurs (ie - the start and/or end position don't lie within
   1.786 +  a sector boundary), the original contents of the start and/or end sectors are read and stored at the start of
   1.787 +  the test, and compared with the contents of the sectors at the end of the test to ensure that unwritten data within
   1.788 +  the sectors remain unaffected.
   1.789 +  
   1.790 +@SYMTestExpectedResults All tests must pass
   1.791 +
   1.792 +@SYMPREQ1389 REQ6951 Double Buffering and SD Switch
   1.793 +*/
   1.794 +	
   1.795 +LOCAL_C void TestLongReadWriteBoundaries(TUint aLen, TBool aMBOnly = EFalse)
   1.796 +	{
   1.797 +	TBuf<64> b;
   1.798 +
   1.799 +	b.Format(_L("MMC drive: Very long RdWr(1) (%dbytes at %d)"),aLen,0);
   1.800 +	test.Next(b);
   1.801 +	MultipleSectorRdWrTest(0, aLen, aMBOnly); // Exceeds driver's buffer, starts/ends on sector boundary
   1.802 +
   1.803 +	b.Format(_L("MMC drive: Very long RdWr(2) (%dbytes at %d)"),(aLen-KDiskSectorSize+5),507);
   1.804 +	test.Next(b);
   1.805 +	MultipleSectorRdWrTest(507, (aLen-KDiskSectorSize+5), aMBOnly); // Exceeds driver's buffer, ends on sector boundary
   1.806 +
   1.807 +	b.Format(_L("MMC drive: Very long RdWr(3) (%dbytes at %d)"),aLen,10);
   1.808 +	test.Next(b);
   1.809 +	MultipleSectorRdWrTest(10, aLen, aMBOnly); // Exceeds driver's buffer, starts/ends off sector boundary
   1.810 +
   1.811 +	b.Format(_L("MMC drive: Very long RdWr(4) (%dbytes at %d)"),(aLen-3),0);
   1.812 +	test.Next(b);
   1.813 +	MultipleSectorRdWrTest(0, aLen-3, aMBOnly); // Exceeds driver's buffer, starts on sector boundary
   1.814 +
   1.815 +	b.Format(_L("MMC drive: Very long RdWr(5) (%dbytes at %d)"),(aLen-KDiskSectorSize),27);
   1.816 +	test.Next(b);
   1.817 +	MultipleSectorRdWrTest(27, (aLen-KDiskSectorSize), aMBOnly); // Exceeds driver's buffer (due to start offset), starts/ends off sector boundary
   1.818 +
   1.819 +	b.Format(_L("MMC drive: Very long RdWr(6) (%dbytes at %d)"),(aLen-KDiskSectorSize-3),0);
   1.820 +	test.Next(b);
   1.821 +	MultipleSectorRdWrTest(0, aLen-KDiskSectorSize-3, aMBOnly); // Equals driver's buffer, starts on sector boundary
   1.822 +
   1.823 +	b.Format(_L("MMC drive: Very long RdWr(7) (%dbytes at %d)"),(aLen-3),3);
   1.824 +	test.Next(b);
   1.825 +	MultipleSectorRdWrTest(3, aLen-3, aMBOnly); // Equals driver's buffer, ends on sector boundary
   1.826 +	}
   1.827 +
   1.828 +
   1.829 +/**
   1.830 +@SYMTestCaseID PBASE-T_MMCDRV-0509
   1.831 +@SYMTestCaseDesc Test Sector Read/Writing
   1.832 +@SYMTestPriority High
   1.833 +
   1.834 +@SYMTestActions
   1.835 +		a.) Test Writing blocks on sector boundaries
   1.836 +		b.) Test Reading blocks on sector boundaries
   1.837 +		c.) Test single sector Write/Read at:
   1.838 +			  i.) Sector Start
   1.839 +			 ii.) Mid Sector
   1.840 +			iii.) Sector End
   1.841 +		d.) Test Multiple Sector Write/Read:
   1.842 +			  i.) Start on Sector Boundary
   1.843 +			 ii.) Start/End on Sector Boundary
   1.844 +			iii.) End on Sector Boundary
   1.845 +		e.) Test Write/Read over sector boundary
   1.846 +
   1.847 +@SYMTestExpectedResults All tests must pass
   1.848 +*/
   1.849 +LOCAL_C void TestSectorReadWrite()
   1.850 +	{
   1.851 +	TBuf<64> b;
   1.852 +	b.Format(_L("MMC drive: Sector RdWr(%d)"), KDiskSectorSize);
   1.853 +
   1.854 +	test.Next(b);
   1.855 +
   1.856 +	TInt len;
   1.857 +
   1.858 +	// Fill wrBuf with a pattern of ascending numbers.
   1.859 +	wrBuf.SetLength(KDiskSectorSize);
   1.860 +	TUint32 *p = REINTERPRET_CAST(TUint32 *, &wrBuf[0]);
   1.861 +	TInt secPos;
   1.862 +	for (secPos = 0; secPos < KDiskSectorSize; secPos++)
   1.863 +		{
   1.864 +		wrBuf[secPos] = TUint8(secPos % 0x0100);
   1.865 +		}
   1.866 +
   1.867 +	// Write 512 byte blocks to the card, writing the sector number to the first
   1.868 +	// word in each buffer.
   1.869 +
   1.870 +	test.Printf(_L("Writing    "));
   1.871 +	TInt64 i;
   1.872 +//	for (i=0;i<DriveSize;i+=len)  // B - Sector wr/rd on sector boundary
   1.873 +	for (i=0;i<(0x200<<3);i+=len)	 // B - Sector wr/rd on sector boundary
   1.874 +		{
   1.875 +		ProgressBar(i, TheMmcDrive.Size(), 11);
   1.876 +		len = KDiskSectorSize < TheMmcDrive.Size() - i ? KDiskSectorSize : I64LOW(TheMmcDrive.Size() - i);
   1.877 +		(*p) = I64LOW(i) / KDiskSectorSize;
   1.878 +		wrBuf.SetLength(len);
   1.879 +		TInt r = TheMmcDrive.Write(i, wrBuf);
   1.880 +		if (r != KErrNone)
   1.881 +			{
   1.882 +			test.Printf(_L("wt:i = %d, len = %d, r  %d"), i, len, r);
   1.883 +			test(EFalse);
   1.884 +			}
   1.885 +		}
   1.886 +
   1.887 +	// Read each of the 512 byte blocks back from the card.
   1.888 +	test.Printf(_L("\r\nReading    "));
   1.889 +//	for (i=0;i<TheMmcDrive.Size();i+=len)
   1.890 +	for (i=0;i<(0x200<<3);i+=len)	 // B - Sector wr/rd on sector boundary
   1.891 +		{
   1.892 +		ProgressBar(i, TheMmcDrive.Size(), 11);
   1.893 +		len = KDiskSectorSize < TheMmcDrive.Size() - i ? KDiskSectorSize : I64LOW(TheMmcDrive.Size() - i);
   1.894 +		rdBuf.Fill(0,len);
   1.895 +		TInt r = TheMmcDrive.Read(i, len, rdBuf);
   1.896 +		if (r != KErrNone)
   1.897 +			{
   1.898 +			test.Printf(_L("rd:i = %d, len = %d, r  %d"), i, len, r);
   1.899 +			test(EFalse);
   1.900 +			}
   1.901 +		(*p) = (I64LOW(i)/KDiskSectorSize);
   1.902 +		wrBuf.SetLength(len);
   1.903 +
   1.904 +		if ((r = rdBuf.Compare(wrBuf)) != 0)
   1.905 +			{
   1.906 +			test.Printf(_L("wc:i = %d, len = %d, r  %d"), i, len, r);
   1.907 +			test.Printf(_L("wc: wrBuf.Length() = %d, rdBuf.Length() = %d"), wrBuf.Length(), rdBuf.Length());
   1.908 +			TInt j;
   1.909 +			for (j = 0; j < wrBuf.Length() && wrBuf[j] == rdBuf[j]; j++)
   1.910 +				{
   1.911 +				// empty.
   1.912 +				}
   1.913 +			test.Printf(_L("wc: wrBuf[%d] = %d, rdBuf[%d] = %d"), j, wrBuf[j], j, rdBuf[j]);
   1.914 +
   1.915 +			test(EFalse);
   1.916 +			}
   1.917 +		}
   1.918 +	test.Printf(_L("\r\n"));
   1.919 +
   1.920 +	b.Format(_L("MMC drive: Short RdWr(1) (%dbytes at %d)"),25,0); 
   1.921 +	test.Next(b);
   1.922 +	singleSectorRdWrTest(0,25); // A - Sub-sector wr/rd at sector start
   1.923 +
   1.924 +	b.Format(_L("MMC drive: Short RdWr(2) (%dbytes at %d)"),16,277); 
   1.925 +	test.Next(b);
   1.926 +	singleSectorRdWrTest(277,16); // E - Sub-sector wr/rd in mid sector
   1.927 +
   1.928 +	b.Format(_L("MMC drive: Short RdWr(3) (%dbytes at %d)"),100,412); 
   1.929 +	test.Next(b);
   1.930 +	singleSectorRdWrTest(412,100); // F - Sub-sector wr/rd at sector end
   1.931 +
   1.932 +	b.Format(_L("MMC drive: Long RdWr(1) (%dbytes at %d)"),KDiskSectorSize+15,0);
   1.933 +	test.Next(b);
   1.934 +	MultipleSectorRdWrTest(0,KDiskSectorSize+15); // C - Long wr/rd starting on sector boundary
   1.935 +
   1.936 +	b.Format(_L("MMC drive: Long RdWr(2) (%dbytes at %d)"),(KDiskSectorSize<<1),0);
   1.937 +	test.Next(b);
   1.938 +	MultipleSectorRdWrTest(0,(KDiskSectorSize<<1)); // D - Long wr/rd starting/ending on sector boundary
   1.939 +
   1.940 +	b.Format(_L("MMC drive: Long RdWr(3) (%dbytes at %d)"),KDiskSectorSize+3,509);
   1.941 +	test.Next(b);
   1.942 +	MultipleSectorRdWrTest(509,KDiskSectorSize+3); // H -  - Long wr/rd ending on sector boundary
   1.943 +
   1.944 +	b.Format(_L("MMC drive: Long RdWr(4) (%dbytes at %d)"),(KDiskSectorSize<<1),508);
   1.945 +	test.Next(b);
   1.946 +	MultipleSectorRdWrTest(508,(KDiskSectorSize<<1));
   1.947 +
   1.948 +	b.Format(_L("MMC drive: Sector RdWr across sector boundary(%dbytes at %d)"),KDiskSectorSize,508);
   1.949 +	test.Next(b);
   1.950 +	MultipleSectorRdWrTest(508,KDiskSectorSize);	// G - Sector wr/rd over sector boundary
   1.951 +
   1.952 +	TestLongReadWriteBoundaries(KRdWrBufLen);			// Short length - As per original test
   1.953 +
   1.954 +	if (ManualMode)
   1.955 +		{
   1.956 +		for(TInt bufLen = KRdWrBufLen; bufLen <= 256*1024; bufLen += KRdWrBufLen)
   1.957 +			{
   1.958 +			TestLongReadWriteBoundaries(bufLen, ETrue);				// Very long length - to test Double-Buffering
   1.959 +			}
   1.960 +		
   1.961 +		TestLongReadWriteBoundaries(KVeryLongRdWrBufLen, ETrue);	// Very long length - to test Double-Buffering
   1.962 +		}
   1.963 +	}
   1.964 +
   1.965 +
   1.966 +/**
   1.967 +@SYMTestCaseID PBASE-T_MMCDRV-0168
   1.968 +@SYMTestCaseDesc Test Sector Formatting
   1.969 +@SYMTestPriority High
   1.970 +
   1.971 +@SYMTestActions
   1.972 +		a.) Test Format/Read/Verify Single Sector
   1.973 +		b.) Test Format/Read/Verify Multiple Sectors
   1.974 +		c.) Test Format/Read/Verify Whole Media
   1.975 +
   1.976 +@SYMTestExpectedResults All tests must pass
   1.977 +*/
   1.978 +LOCAL_C void TestFormat()
   1.979 +	{
   1.980 +	if(TheMmcDrive.TestMode() != TMMCDrive::ETestPartition)
   1.981 +		{
   1.982 +		test.Printf(_L("Skipping format tests - only supported on Partition Test Mode"));
   1.983 +		return;
   1.984 +		}
   1.985 +
   1.986 +	if(CardType == TKnownCardTypes::EBuffalloMiniSD_32M_ERASE ||	
   1.987 +	   CardType == TKnownCardTypes::EBuffalloMiniSD_64M_ERASE ||
   1.988 +	   CardType == TKnownCardTypes::EBuffalloMiniSD_128M_ERASE ||
   1.989 +	   CardType == TKnownCardTypes::EBuffalloMiniSD_256M_ERASE ||
   1.990 +	   CardType == TKnownCardTypes::EBuffalloMiniSD_512M_ERASE
   1.991 +	   )
   1.992 +	    {
   1.993 +	    //These cards implement the erase command incorrectly
   1.994 +	    test.Printf( _L(" -- Skipping Format Tests - Known card detected --\n") );
   1.995 +	    return;
   1.996 +	    }
   1.997 +	
   1.998 +	test.Next(_L("MMC drive: Format sectors (short)"));
   1.999 +	TBuf8<KDiskSectorSize> savBuf1,savBuf2;
  1.1000 +	TInt fmtTestPos=(10<<KDiskSectorShift);
  1.1001 +	// Save sectors surrounding those which will be formatted
  1.1002 +	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,savBuf1)==KErrNone);
  1.1003 +	test(TheMmcDrive.Read((fmtTestPos+KShortFormatInBytes),KDiskSectorSize,savBuf2)==KErrNone);
  1.1004 +
  1.1005 +	// Fill buffer with 0xCC 
  1.1006 +	// (i.e. a value which is not going to be written by formatting the device)
  1.1007 +	// & then write to area which is to be formatted
  1.1008 +	wrBuf.SetLength(KShortFormatInBytes);
  1.1009 +	wrBuf.Fill(0xCC);
  1.1010 +	test(TheMmcDrive.Write(fmtTestPos, wrBuf)==KErrNone);
  1.1011 +
  1.1012 +
  1.1013 +	test(TheMmcDrive.Format(fmtTestPos,KShortFormatInBytes)==KErrNone);
  1.1014 +	test(TheMmcDrive.Read(fmtTestPos,KShortFormatInBytes,rdBuf)==KErrNone);
  1.1015 +
  1.1016 +	TUint8 defEraseVal = rdBuf[0];
  1.1017 +	test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
  1.1018 +	wrBuf.Fill(defEraseVal ,KShortFormatInBytes);
  1.1019 +	test(rdBuf.Compare(wrBuf)==0);
  1.1020 +
  1.1021 +	// Check that surrounding sectors unaffected
  1.1022 +	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,rdBuf)==KErrNone);
  1.1023 +	test(rdBuf.Compare(savBuf1)==0);
  1.1024 +	test(TheMmcDrive.Read((fmtTestPos+KShortFormatInBytes),KDiskSectorSize,rdBuf)==KErrNone);
  1.1025 +	test(rdBuf.Compare(savBuf2)==0);
  1.1026 +
  1.1027 +	test.Next(_L("MMC drive: Format sectors (long)"));
  1.1028 +	fmtTestPos+=(4<<KDiskSectorShift);
  1.1029 +	// Save sectors surrounding those which will be formatted
  1.1030 +	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,savBuf1)==KErrNone);
  1.1031 +	test(TheMmcDrive.Read((fmtTestPos+KLongFormatInBytes),KDiskSectorSize,savBuf2)==KErrNone);
  1.1032 +
  1.1033 +	// Fill buffer with 0xCC 
  1.1034 +	// (i.e. a value which is not going to be written by formatting the device)
  1.1035 +	// & then write to area which is to be formatted
  1.1036 +	wrBuf.SetLength(KLongFormatInBytes);
  1.1037 +	wrBuf.Fill(0xCC);
  1.1038 +	test(TheMmcDrive.Write(fmtTestPos, wrBuf)==KErrNone);
  1.1039 +
  1.1040 +	test(TheMmcDrive.Format(fmtTestPos,KLongFormatInBytes)==KErrNone);
  1.1041 +	test(TheMmcDrive.Read(fmtTestPos,KLongFormatInBytes,rdBuf)==KErrNone);
  1.1042 +
  1.1043 +	defEraseVal = rdBuf[0];
  1.1044 +	test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
  1.1045 +	wrBuf.Fill(defEraseVal,KLongFormatInBytes);
  1.1046 +	TInt cmpRes = rdBuf.Compare(wrBuf);
  1.1047 +	if(cmpRes != 0)
  1.1048 +		{
  1.1049 +		test.Printf(_L("\n\rExpected 0x%02x\n\r"));
  1.1050 +		for(TInt x=0; x<KLongFormatInBytes; x+=8)
  1.1051 +			{
  1.1052 +			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]);
  1.1053 +			}
  1.1054 +		}
  1.1055 +	test(cmpRes==0);
  1.1056 +
  1.1057 +	// Check that surrounding sectors unaffected
  1.1058 +	test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,rdBuf)==KErrNone);
  1.1059 +	test(rdBuf.Compare(savBuf1)==0);
  1.1060 +	test(TheMmcDrive.Read((fmtTestPos+KLongFormatInBytes),KDiskSectorSize,rdBuf)==KErrNone);
  1.1061 +	test(rdBuf.Compare(savBuf2)==0);
  1.1062 +
  1.1063 +	if (ManualMode)
  1.1064 +		{
  1.1065 +		test.Next(_L("Fill the drive with garbage"));
  1.1066 +		TInt64 driveSize = TheMmcDrive.Size();
  1.1067 +		TInt wtLen = wrBuf.MaxLength();
  1.1068 +		TInt64 i;
  1.1069 +		for (i=0; i<driveSize; i+=wtLen)
  1.1070 +			{
  1.1071 +			ProgressBar(i,driveSize,11);
  1.1072 +			wtLen = wtLen < driveSize - i ? wtLen : I64LOW(driveSize - i);
  1.1073 +			wrBuf.Fill(0xCC,wtLen);
  1.1074 +
  1.1075 +			wrBuf.SetLength(wtLen);
  1.1076 +
  1.1077 +			test.Printf(_L("writing pos %08lX len %08X\n"), i, wrBuf.Length());
  1.1078 +			test(TheMmcDrive.Write(i, wrBuf) == KErrNone);
  1.1079 +			}
  1.1080 +
  1.1081 +		test.Next(_L("MMC drive: Format entire disk"));
  1.1082 +		TFormatInfo fi;
  1.1083 +		test.Printf(_L("Formatting "));
  1.1084 +		TInt ret;
  1.1085 +		TInt stage = 0;
  1.1086 +		while((ret=TheMmcDrive.Format(fi))!=KErrEof)
  1.1087 +			{
  1.1088 +			stage++;
  1.1089 +			ProgressBar((fi.i512ByteSectorsFormatted<<9),TheMmcDrive.Size(),11);
  1.1090 +			test(ret==KErrNone);
  1.1091 +			}
  1.1092 +
  1.1093 +		test.Printf(_L("\r\nReading    "));
  1.1094 +		
  1.1095 +		TInt len = KVeryLongSectBufSizeInBytes;
  1.1096 +
  1.1097 +		for (i=0; i<TheMmcDrive.Size(); i+=len)
  1.1098 +			{
  1.1099 +			ProgressBar(i,TheMmcDrive.Size(),11);
  1.1100 +			len = len < TheMmcDrive.Size() - i ? len : I64LOW(TheMmcDrive.Size() - i);
  1.1101 +			rdBuf.Fill(0x55,len);
  1.1102 +			test(TheMmcDrive.Read(i,len,rdBuf) == KErrNone);
  1.1103 +
  1.1104 +			const TInt wholeSectors = len / KDiskSectorSize;
  1.1105 +			const TInt rem = len - (wholeSectors * KDiskSectorSize);
  1.1106 +
  1.1107 +			TInt sec;
  1.1108 +			for(sec=1;sec<wholeSectors; sec++)	// Start at Base+1 - Card may have written an MBR at sector 0
  1.1109 +				{
  1.1110 +				wrBuf.SetLength(KDiskSectorSize);
  1.1111 +				defEraseVal = rdBuf[sec * KDiskSectorSize];
  1.1112 +				test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
  1.1113 +				wrBuf.Fill(defEraseVal, KDiskSectorSize);
  1.1114 +				test( CompareBuffers( wrBuf, rdBuf.Mid( sec * KDiskSectorSize, KDiskSectorSize ) ) );
  1.1115 +				}
  1.1116 +
  1.1117 +			if(rem > 0)
  1.1118 +				{
  1.1119 +				wrBuf.SetLength(rem);
  1.1120 +				defEraseVal = rdBuf[sec * KDiskSectorSize];
  1.1121 +				test(defEraseVal == 0x00 || defEraseVal == 0xFF);	// The card should erase with 0x00 or 0xFF
  1.1122 +				wrBuf.Fill(defEraseVal, rem);
  1.1123 +				test( CompareBuffers( wrBuf, rdBuf.Mid( sec * KDiskSectorSize, rem ) ) );
  1.1124 +				}
  1.1125 +			}
  1.1126 +		}
  1.1127 +	}
  1.1128 +
  1.1129 +
  1.1130 +class TRandGen
  1.1131 +	{
  1.1132 +	public:
  1.1133 +		TRandGen();
  1.1134 +		void Seed();
  1.1135 +		void Seed( const TInt64& aSeed );
  1.1136 +		TUint Next();
  1.1137 +
  1.1138 +	private:
  1.1139 +		TInt64	iValue;
  1.1140 +	};
  1.1141 +
  1.1142 +
  1.1143 +TRandGen::TRandGen()
  1.1144 +	: iValue(KDefaultRandSeed)
  1.1145 +	{
  1.1146 +	}
  1.1147 +
  1.1148 +
  1.1149 +void TRandGen::Seed( const TInt64& aSeed )
  1.1150 +	{
  1.1151 +	iValue = aSeed;
  1.1152 +	}
  1.1153 +
  1.1154 +void TRandGen::Seed()
  1.1155 +	{
  1.1156 +	iValue = KDefaultRandSeed;
  1.1157 +	}
  1.1158 +
  1.1159 +TUint TRandGen::Next()
  1.1160 +	{
  1.1161 +	iValue *= 214013;
  1.1162 +    iValue += 2531011;
  1.1163 +    return static_cast<TUint>( I64LOW(iValue) );
  1.1164 +	}
  1.1165 +
  1.1166 +
  1.1167 +GLDEF_C void FillRandomBuffer( TDes8& aBuf, TRandGen& aRand )
  1.1168 +	/**
  1.1169 +	 * Fill buffer aBuf with data generated by aRand
  1.1170 +	 */
  1.1171 +	{
  1.1172 +	TUint l = aBuf.MaxLength();
  1.1173 +	aBuf.SetLength( l );
  1.1174 +	TUint* p = (TUint*)aBuf.Ptr();
  1.1175 +
  1.1176 +	// Do any unaligned bytes at the start
  1.1177 +	TInt preAlign = (TUint)p & 3;
  1.1178 +	if( preAlign )
  1.1179 +		{
  1.1180 +		preAlign = 4 - preAlign;
  1.1181 +		TUint8* p8 = (TUint8*)p;
  1.1182 +		TUint rand = aRand.Next();
  1.1183 +		while( preAlign && l )
  1.1184 +			{
  1.1185 +			*p8 = (TUint8)(rand & 0xFF);
  1.1186 +			rand >>= 8;
  1.1187 +			++p8;
  1.1188 +			--preAlign;
  1.1189 +			--l;
  1.1190 +			}
  1.1191 +		p = (TUint*)p8;
  1.1192 +		}
  1.1193 +
  1.1194 +	for( ; l > 3; l-=4 )
  1.1195 +		{
  1.1196 +		*p++ = aRand.Next();
  1.1197 +		}
  1.1198 +	// Fill in any trailing bytes
  1.1199 +	if( l > 0 )
  1.1200 +		{
  1.1201 +		TUint8* q = (TUint8*)p;
  1.1202 +		TUint r = aRand.Next();
  1.1203 +		if( l > 1 )
  1.1204 +			{
  1.1205 +			*((TUint16*)q) = (TUint16)(r & 0xFFFF);
  1.1206 +			q += 2;
  1.1207 +			l -= 2;
  1.1208 +			r >>= 16;
  1.1209 +			}
  1.1210 +		if( l > 0 )
  1.1211 +			{
  1.1212 +			*q = (TUint8)(r & 0xFF);
  1.1213 +			}
  1.1214 +		}
  1.1215 +	}
  1.1216 +
  1.1217 +GLDEF_C void FillRandomBuffer( HBufC8* aBuf, TRandGen& aRand )
  1.1218 +	/**
  1.1219 +	 * Fill buffer aBuf with data generated by aRand
  1.1220 +	 * For convenience this version takes a HBufC8*
  1.1221 +	 */
  1.1222 +	{
  1.1223 +	TPtr8 ptr = aBuf->Des();
  1.1224 +	FillRandomBuffer( ptr, aRand );
  1.1225 +	}
  1.1226 +
  1.1227 +
  1.1228 +/**
  1.1229 +@SYMTestCaseID PBASE-T_MMCDRV-0164
  1.1230 +@SYMTestCaseDesc Test MMC Drive Capabilities
  1.1231 +@SYMTestPriority High
  1.1232 +
  1.1233 +@SYMTestActions  
  1.1234 +	a. Obtain MMC Drive Capabilities
  1.1235 +	b. If the card size is greater than 2GBytes, test that the driver reports FAT32 file system supported.
  1.1236 +	c. Test that the type of media is reported as EMediaHardDisk
  1.1237 +	d. Test that the drive attributes report KDriveAttLocal and KDriveAttRemovable
  1.1238 +	e. Test that the drive attributes do not report KDriveAttRemote
  1.1239 +	f. If the drive is not write protected or a ROM card, test that the media attributes report that the drive is formattable
  1.1240 +	g. If the drive is write protected or a ROM card, test that the media attributes do not report that the drive is formattable
  1.1241 +	h. Test that the media attributes do not report variable sized media.
  1.1242 +
  1.1243 +@SYMTestExpectedResults All tests must pass
  1.1244 +
  1.1245 +@SYMPREQ1389 CR0795 Support for >2G SD Cards
  1.1246 +*/
  1.1247 +TBool TestDriveInfo()
  1.1248 +	{
  1.1249 +	test.Next( _L("Test drive info") );
  1.1250 +
  1.1251 +	TEST_FOR_ERROR( TheMmcDrive.Caps( DriveCaps ) );
  1.1252 +
  1.1253 +	test.Printf( _L("Caps V1:\n\tiSize=0x%lx\n\tiType=%d\n\tiConnectionBusType=%d\n\tiDriveAtt=0x%x\n\tiMediaAtt=0x%x\n\tiBaseAddress=0x%x\n\tiFileSystemId=0x%x\n\tiPartitionType=0x%x\n"),
  1.1254 +			DriveCaps().iSize,
  1.1255 +			DriveCaps().iType,
  1.1256 +			DriveCaps().iConnectionBusType,
  1.1257 +			DriveCaps().iDriveAtt,
  1.1258 +			DriveCaps().iMediaAtt,
  1.1259 +			DriveCaps().iBaseAddress,
  1.1260 +			DriveCaps().iFileSystemId,
  1.1261 +			DriveCaps().iPartitionType );
  1.1262 +
  1.1263 +	test.Printf( _L("Caps V2:\n\tiHiddenSectors=0x%x\n\tiEraseBlockSize=0x%x\nCaps V3:\n\tiExtraInfo=%x\n\tiMaxBytesPerFormat=0x%x\n"),
  1.1264 +			DriveCaps().iHiddenSectors,
  1.1265 +			DriveCaps().iEraseBlockSize, 
  1.1266 +			DriveCaps().iExtraInfo,
  1.1267 +			DriveCaps().iMaxBytesPerFormat );
  1.1268 +
  1.1269 +	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"),
  1.1270 +			DriveCaps().iFormatInfo.iCapacity,
  1.1271 +			DriveCaps().iFormatInfo.iSectorsPerCluster,
  1.1272 +			DriveCaps().iFormatInfo.iSectorsPerTrack,
  1.1273 +			DriveCaps().iFormatInfo.iNumberOfSides,
  1.1274 +			DriveCaps().iFormatInfo.iFATBits );
  1.1275 +
  1.1276 +	if(DriveCaps().iSerialNumLength > 0)
  1.1277 +		{
  1.1278 +        test.Printf( _L("Serial Number : ") );
  1.1279 +        TBuf8<2*KMaxSerialNumLength> snBuf;
  1.1280 +        TUint i;
  1.1281 +		for (i=0; i<DriveCaps().iSerialNumLength; i++)
  1.1282 +			{
  1.1283 +            snBuf.AppendNumFixedWidth( DriveCaps().iSerialNum[i], EHex, 2 );
  1.1284 +			test.Printf( _L("%02x"), DriveCaps().iSerialNum[i]);
  1.1285 +			}
  1.1286 +		test.Printf( _L("\n") );
  1.1287 +
  1.1288 +		CardType = TKnownCardTypes::EStandardCard;
  1.1289 +		for(i=0; i < sizeof(KnownCardTypes) / sizeof(TKnownCardTypes); i++)
  1.1290 +			{
  1.1291 +			TPtrC8 serial(KnownCardTypes[i].iSerialNumber);
  1.1292 +			if(snBuf.Compare(serial) == 0)
  1.1293 +				{
  1.1294 +				CardType = KnownCardTypes[i].iCardType;
  1.1295 +				break;
  1.1296 +				}
  1.1297 +			}
  1.1298 +		}
  1.1299 +	else
  1.1300 +		{
  1.1301 +		test.Printf( _L("Serial Number : Not Supported") );
  1.1302 +		}
  1.1303 +
  1.1304 +	// DriveSize - The size of the partition to which the test is connected.
  1.1305 +	// MediaSize - The entire size of the media containing the partition.
  1.1306 +	
  1.1307 +	TInt64 mediaSize = DriveCaps().MediaSizeInBytes();
  1.1308 +	TheMmcDrive.SetSize(DriveCaps().iSize, mediaSize);
  1.1309 +	if(mediaSize == 0)
  1.1310 +		{
  1.1311 +		test.Printf(_L("Check entire media size: Not Supported\r\n"));
  1.1312 +		}
  1.1313 +
  1.1314 +	test.Printf(_L("Entire media size: %ld\r\n"),mediaSize);
  1.1315 +	test.Printf(_L("Partition size:    %ld\r\n"),DriveCaps().iSize);
  1.1316 +	test.Printf(_L("Hidden sectors:    %d\r\n"),DriveCaps().iHiddenSectors);
  1.1317 +	
  1.1318 +	
  1.1319 +	TEST_FOR_VALUE( DriveCaps().iFileSystemId, KDriveFileSysFAT );
  1.1320 +	
  1.1321 +	// Test that a drive >2GB is marked as requesting FAT32
  1.1322 +	if( DriveCaps().iSize > KTwoGigbytes && DriveCaps().iExtraInfo)
  1.1323 +		{
  1.1324 +		TEST_FOR_VALUE( DriveCaps().iFormatInfo.iFATBits, TLDFormatInfo::EFB32 );
  1.1325 +		}
  1.1326 +
  1.1327 +	TEST_FOR_VALUE( DriveCaps().iType, EMediaHardDisk );
  1.1328 +	
  1.1329 +	const TUint KExpectedDriveAtt = KDriveAttLocal | KDriveAttRemovable;
  1.1330 +	const TUint KNotExpectedDriveAtt = KDriveAttRemote;
  1.1331 +	TEST_FOR_VALUE( DriveCaps().iDriveAtt & KExpectedDriveAtt, KExpectedDriveAtt );
  1.1332 +	TEST_FOR_VALUE( DriveCaps().iDriveAtt & KNotExpectedDriveAtt, 0 );
  1.1333 +
  1.1334 +	TUint expectedMediaAtt = KMediaAttFormattable;
  1.1335 +	TUint notExpectedMediaAtt = KMediaAttVariableSize;
  1.1336 +
  1.1337 +	TBool isReadOnly = DriveCaps().iMediaAtt & KMediaAttWriteProtected;
  1.1338 +	if(isReadOnly)
  1.1339 +		{
  1.1340 +		expectedMediaAtt &= ~KMediaAttFormattable;
  1.1341 +
  1.1342 +		test.Printf( _L("\n ---------------------------\n") );
  1.1343 +		test.Printf( _L("  Media is Write Protected\n") );
  1.1344 +		if((DriveCaps().iMediaAtt & KMediaAttFormattable) != KMediaAttFormattable)
  1.1345 +			{
  1.1346 +			test.Printf( _L("    Media is a ROM card\n") );
  1.1347 +			}
  1.1348 +		test.Printf( _L("  Some tests will be skipped\n") );
  1.1349 +		test.Printf( _L(" ---------------------------\n") );
  1.1350 +		}
  1.1351 +
  1.1352 +	TEST_FOR_VALUE( DriveCaps().iMediaAtt & expectedMediaAtt, expectedMediaAtt );
  1.1353 +	TEST_FOR_VALUE( DriveCaps().iMediaAtt & notExpectedMediaAtt, 0 );
  1.1354 +
  1.1355 +	return(isReadOnly);
  1.1356 +	}
  1.1357 +
  1.1358 +
  1.1359 +/**
  1.1360 +@SYMTestCaseID PBASE-T_MMCDRV-0165
  1.1361 +@SYMTestCaseDesc Test MMC Card Reads
  1.1362 +@SYMTestPriority High
  1.1363 +
  1.1364 +@SYMTestActions  
  1.1365 +	a. Read 64K in one operation from the start of the media and store the contents.
  1.1366 +	b. Read 512 byte blocks from the start of the media at various offsets and compare with initial read.
  1.1367 +	b. Read 64K in 512 byte blocks from the start of the media and compare with the initial read.
  1.1368 +	c. read 64K from the end of the drive
  1.1369 +
  1.1370 +@SYMTestExpectedResults All tests must pass
  1.1371 +
  1.1372 +@SYMPREQ1389 CR0795 Support for >2G SD Cards
  1.1373 +*/
  1.1374 +void TestRead()
  1.1375 +	{
  1.1376 +	// This just tests that we can read *something* from the drive
  1.1377 +	// We check elsewhere that we can read what we've written
  1.1378 +	test.Next( _L("Test reading" ) );
  1.1379 +
  1.1380 +	HBufC8* bigBuf = HBufC8::New( 65536 );
  1.1381 +	HBufC8* smallBuf = HBufC8::New( 512 );
  1.1382 +
  1.1383 +	test( bigBuf != NULL );
  1.1384 +	test( smallBuf != NULL );
  1.1385 +	TPtr8 bigPtr( bigBuf->Des() );
  1.1386 +	TPtr8 smallPtr( smallBuf->Des() );
  1.1387 +
  1.1388 +	test.Printf( _L("Read block from start of media\n") );
  1.1389 +	TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(0), 65536, bigPtr) );
  1.1390 +
  1.1391 +	test.Printf( _L("Read smaller blocks which should match the data in big block\n\r" ) );
  1.1392 +	TInt i;
  1.1393 +	for( i = 0; i <= 512; ++i )
  1.1394 +		{
  1.1395 +		test.Printf( _L("\toffset: %d\r"), i );
  1.1396 +		TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(i), 512, smallPtr ) );
  1.1397 +		test( CompareBuffers( smallBuf->Des(), bigBuf->Mid( i, 512 ) ) );
  1.1398 +		}
  1.1399 +
  1.1400 +	for( i = 512; i <= 65536-512; i += 512 )
  1.1401 +		{
  1.1402 +		test.Printf( _L("\toffset: %d\r"), i );
  1.1403 +		TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(i), 512, smallPtr ) );
  1.1404 +		test( CompareBuffers( smallBuf->Des(), bigBuf->Mid( i, 512 ) ) );
  1.1405 +		}
  1.1406 +
  1.1407 +	test.Printf( _L("\nTest read from end of drive\n") );
  1.1408 +	
  1.1409 +	if(CardType == TKnownCardTypes::EBuffalloMiniSD_512M ||	
  1.1410 +	   CardType == TKnownCardTypes::EIntegralHSSD_2G)
  1.1411 +		{
  1.1412 +		// These cards have issues with reading at the end of the drive...
  1.1413 +		test.Printf( _L(" -- Skipping Test - Known card detected --\n") );
  1.1414 +		}
  1.1415 +	else
  1.1416 +		{
  1.1417 +		TEST_FOR_ERROR( TheMmcDrive.Read( TheMmcDrive.Size() - 65536, 65536, bigPtr) );
  1.1418 +		}
  1.1419 +
  1.1420 +	delete smallBuf;
  1.1421 +	delete bigBuf;
  1.1422 +	}
  1.1423 +
  1.1424 +
  1.1425 +/**
  1.1426 +@SYMTestCaseID PBASE-T_MMCDRV-0511
  1.1427 +@SYMTestCaseDesc Test Moving Read/Write
  1.1428 +@SYMTestPriority High
  1.1429 +
  1.1430 +@SYMTestActions
  1.1431 +		a.) Test Read/Verify Whole Sectors
  1.1432 +		b.) Test Read/Verify Sliding sector sized window
  1.1433 +		c.) Test Read/Verify Sliding byte sized window
  1.1434 +		d.) Test Read/Verify Increasing sized window
  1.1435 +		e.) Test Write/Read/Verify Whole Sectors
  1.1436 +		f.) Test Write/Read/Verify Sliding sector sized window
  1.1437 +		g.) Test Write/Read/Verify Increasing sized window
  1.1438 +		
  1.1439 +@SYMTestExpectedResults All tests must pass
  1.1440 +*/
  1.1441 +void DoReadWriteTest( TInt64 aPos, TInt aWindowSize, TBool aQuick )
  1.1442 +	{
  1.1443 +	// Do various read/write tests within a aWindowSize window starting at aPos
  1.1444 +	HBufC8* wholeBuf = HBufC8::New( aWindowSize );
  1.1445 +	test( wholeBuf != NULL );
  1.1446 +
  1.1447 +	HBufC8* readBuf = HBufC8::New( aWindowSize );
  1.1448 +	test( readBuf != NULL );
  1.1449 +
  1.1450 +	TBuf8<512> sectorBuf;
  1.1451 +	TRandGen rand;
  1.1452 +	
  1.1453 +	test.Printf( _L("Walking sector read\n\r") );
  1.1454 +	FillRandomBuffer( wholeBuf, rand );
  1.1455 +	TPtr8 wholeBufPtr( wholeBuf->Des() );
  1.1456 +	TEST_FOR_ERROR( TheMmcDrive.Write( aPos, *wholeBuf ) );
  1.1457 +	
  1.1458 +	// Read each sector back and check that it's correct
  1.1459 +	TInt64 pos( aPos );
  1.1460 +	TInt i;
  1.1461 +	for( i = 0; i < aWindowSize - 512; i += 512 )
  1.1462 +		{
  1.1463 +		pos = aPos + i;
  1.1464 +		test.Printf(_L("\tRead @0x%lx\r"), pos);
  1.1465 +		TEST_FOR_ERROR( TheMmcDrive.Read( pos, 512, sectorBuf ) );
  1.1466 +		test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 512 ) ) );
  1.1467 +		}
  1.1468 +
  1.1469 +	test.Printf( _L("\nSliding sector read\n\r") );
  1.1470 +	// Slide a sector-sized window over the data
  1.1471 +	TInt maxl = Min( aWindowSize - 512, 512 * 3 );
  1.1472 +	for( i = 0; i < maxl; i++ )
  1.1473 +		{
  1.1474 +		pos = aPos + i;
  1.1475 +		test.Printf(_L("\tRead @0x%lx\r"), pos);
  1.1476 +		TEST_FOR_ERROR( TheMmcDrive.Read( pos, 512, sectorBuf ) );
  1.1477 +		test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 512 ) ) );
  1.1478 +		}
  1.1479 +	
  1.1480 +	if( !aQuick )
  1.1481 +		{
  1.1482 +		test.Printf( _L("\nSliding byte read\n\r") );
  1.1483 +		// Slide a byte-sized window over the data
  1.1484 +		for( i = 0; i < maxl; i++ )
  1.1485 +			{
  1.1486 +			pos = aPos + i;
  1.1487 +			test.Printf(_L("\tRead @0x%lx\r"), pos);
  1.1488 +			TEST_FOR_ERROR( TheMmcDrive.Read( pos, 1, sectorBuf ) );
  1.1489 +			test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 1 ) ) );
  1.1490 +			}
  1.1491 +
  1.1492 +		test.Printf( _L("\nGrowing read\n\r") );
  1.1493 +		// Read from an increasing-sized window
  1.1494 +		for( i = 1; i < 512; i++ )
  1.1495 +			{
  1.1496 +			test.Printf(_L("\tRead length: %d\r"), i);
  1.1497 +			TEST_FOR_ERROR( TheMmcDrive.Read( aPos, i, sectorBuf ) );
  1.1498 +			test( CompareBuffers( sectorBuf, wholeBuf->Left( i ) ) );
  1.1499 +			}
  1.1500 +
  1.1501 +		test.Printf( _L("\nDownward-expanding read\n\r") );
  1.1502 +		// Read from a window that grows downward from the end of the test region
  1.1503 +		for( i = 1; i <= 512; i++ )
  1.1504 +			{
  1.1505 +			pos = aPos + aWindowSize - i;
  1.1506 +			test.Printf(_L("\t[pos:len] %lx:%d\r"), pos, i);
  1.1507 +			TEST_FOR_ERROR( TheMmcDrive.Read( pos, i, sectorBuf ) );
  1.1508 +			test( CompareBuffers( sectorBuf, wholeBuf->Mid( aWindowSize - i, i ) ) );
  1.1509 +			}
  1.1510 +		}
  1.1511 +
  1.1512 +	test.Printf( _L("\nWalking sector write\n\r") );
  1.1513 +	// Overwrite each sector and check the whole region is correct
  1.1514 +	for( i = 0; i < aWindowSize - 512; i += 512 )
  1.1515 +		{
  1.1516 +		FillRandomBuffer( sectorBuf, rand );
  1.1517 +		pos = aPos + i;
  1.1518 +		test.Printf(_L("\tWrite @0x%lx\r"), pos);
  1.1519 +		TEST_FOR_ERROR( TheMmcDrive.Write( pos, sectorBuf ) );
  1.1520 +		wholeBufPtr.MidTPtr( i, 512 ) = sectorBuf;	// update our match data
  1.1521 +		
  1.1522 +		TPtr8 ptr( readBuf->Des() );
  1.1523 +		TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) );
  1.1524 +		test( CompareBuffers( *readBuf, *wholeBuf ) );
  1.1525 +		}
  1.1526 +
  1.1527 +	if( !aQuick )
  1.1528 +		{
  1.1529 +		test.Printf( _L("\nSliding sector overwrite\n\r") );
  1.1530 +		// Overwrite a sector-sized region that slides across the test region
  1.1531 +		for( i = 0; i < maxl; i += 1 )
  1.1532 +			{
  1.1533 +			FillRandomBuffer( sectorBuf, rand );
  1.1534 +			pos = aPos + i;
  1.1535 +			test.Printf(_L("\tWrite @0x%lx\r"), pos);
  1.1536 +			TEST_FOR_ERROR( TheMmcDrive.Write( pos, sectorBuf ) );
  1.1537 +			wholeBufPtr.MidTPtr( i, 512 ) = sectorBuf;	// update our match data
  1.1538 +			
  1.1539 +			TPtr8 ptr( readBuf->Des() );
  1.1540 +			TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) );
  1.1541 +			test( CompareBuffers( *readBuf, *wholeBuf ) );
  1.1542 +			}
  1.1543 +
  1.1544 +		test.Printf( _L("\nGrowing sector overwrite\n\r") );
  1.1545 +		// Overwrite an expanding region starting at aPos
  1.1546 +		for( i = 1; i < 512; i += 1 )
  1.1547 +			{
  1.1548 +			FillRandomBuffer( sectorBuf, rand );
  1.1549 +			test.Printf(_L("\tWrite length: %d\r"), i);
  1.1550 +			sectorBuf.SetLength( i );
  1.1551 +			TEST_FOR_ERROR( TheMmcDrive.Write( aPos, sectorBuf ) );
  1.1552 +			wholeBufPtr.LeftTPtr( i ) = sectorBuf;	// update our match data
  1.1553 +			
  1.1554 +			TPtr8 ptr( readBuf->Des() );
  1.1555 +			TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) );
  1.1556 +			test( CompareBuffers( *readBuf, *wholeBuf ) );
  1.1557 +			}
  1.1558 +		}
  1.1559 +
  1.1560 +	test.Printf( _L("\nTest zero-length read\n") );
  1.1561 +	FillRandomBuffer( sectorBuf, rand );
  1.1562 +	TEST_FOR_ERROR( TheMmcDrive.Read( aPos, 0, sectorBuf ) );
  1.1563 +	TEST_FOR_VALUE( sectorBuf.Length(), 0 );
  1.1564 +
  1.1565 +	delete wholeBuf;
  1.1566 +	delete readBuf;
  1.1567 +	}
  1.1568 +
  1.1569 +
  1.1570 +// This tests for a bug observed in certain ESanDiskMmcMobile_1GB cards which never exit the busy state
  1.1571 +// when writing a buffer which is one sector bigger than the PSL buffer size (resulting in a single write
  1.1572 +// request split into 2 fragments, the last of which is one sector only). The "fix" for this is to make the 
  1.1573 +// PSL reject CMD23 (SET_BLOCK_COUNT) for these particular cards, forcing the PIL to issue a CMD12 (STOP_TRANSMISSION)
  1.1574 +void TestFragmentedWrite(TInt aLength)
  1.1575 +	{
  1.1576 +	test.Next( _L("Test a large write just bigger than PSL buffer size") );
  1.1577 +
  1.1578 +	HBufC8* bigBuf = HBufC8::New( aLength);
  1.1579 +	test( bigBuf != NULL );
  1.1580 +	TPtr8 bigPtr( bigBuf->Des() );
  1.1581 +
  1.1582 +	TInt64 startPos = 0;
  1.1583 +
  1.1584 +	// for a dual-slot enabled H4, buffer size is 132K - (512 * 2) = 131K
  1.1585 +
  1.1586 +	
  1.1587 +	test.Printf( _L("Initializing buffer contents...\n"));
  1.1588 +	bigPtr.SetLength(aLength);
  1.1589 +	TInt n;
  1.1590 +	for (n=0; n<aLength; n++)
  1.1591 +		{
  1.1592 +		bigPtr[n] = (TUint8) n;
  1.1593 +		}
  1.1594 +
  1.1595 +	bigPtr.SetLength(aLength);
  1.1596 +	test.Printf( _L("Write %d sectors\n"), bigPtr.Length() / 512);
  1.1597 +	TEST_FOR_ERROR( TheMmcDrive.Write( startPos, bigPtr) );
  1.1598 +
  1.1599 +
  1.1600 +	bigPtr.SetLength(aLength);
  1.1601 +	bigPtr.FillZ();
  1.1602 +
  1.1603 +	test.Printf( _L("Read %d sectors\n"), bigPtr.Length() / 512);
  1.1604 +	TEST_FOR_ERROR( TheMmcDrive.Read( startPos, bigPtr.Length(), bigPtr) );
  1.1605 +
  1.1606 +	test.Printf( _L("Read #1 len %d \n"), bigPtr.Length());
  1.1607 +
  1.1608 +	for (n=0; n< 0 + aLength; n++)
  1.1609 +		{
  1.1610 +		if (bigPtr[n] != (TUint8) n)
  1.1611 +			{
  1.1612 +			test.Printf(_L("mismatch at %lx [0x%02x] != [0x%02x]"), n, bigPtr[n], (TUint8) n);
  1.1613 +			test(0);
  1.1614 +			}
  1.1615 +		}
  1.1616 +
  1.1617 +	delete bigBuf;
  1.1618 +	}
  1.1619 +
  1.1620 +void TestWrite()
  1.1621 +	{
  1.1622 +	// for a dual-slot enabled H4, buffer size is 132K - (512 * 2) = 131K
  1.1623 +	TestFragmentedWrite(131*1024 + 512);
  1.1624 +	// for a single-slot enabled H4, buffer size is 132K - (512 * 1) = 131K + 512
  1.1625 +	TestFragmentedWrite(131*1024 + 1024);
  1.1626 +
  1.1627 +
  1.1628 +	test.Next( _L("Test writing to drive") );
  1.1629 +	DoReadWriteTest( 0, 65536, EFalse );
  1.1630 +	}
  1.1631 +
  1.1632 +
  1.1633 +/**
  1.1634 +@SYMTestCaseID PBASE-T_MMCDRV-0166
  1.1635 +@SYMTestCaseDesc Test MMC Card accesses at the end of the media
  1.1636 +@SYMTestPriority High
  1.1637 +
  1.1638 +@SYMTestActions  
  1.1639 +	a. If the card is not read-only, perform read/write tests at the last 64K of the media.
  1.1640 +	b. Test that all accesses beyond the end of the media produce an error.
  1.1641 +
  1.1642 +@SYMTestExpectedResults All tests must pass
  1.1643 +
  1.1644 +@SYMPREQ1389 CR0795 Support for >2G SD Cards
  1.1645 +*/
  1.1646 +void TestCapacity()
  1.1647 +	{
  1.1648 +	if(!IsReadOnly)
  1.1649 +		{
  1.1650 +		test.Next( _L("Test access at end of media") );
  1.1651 +		DoReadWriteTest( TheMmcDrive.Size() - 65536, 65536, ETrue );
  1.1652 +		}
  1.1653 +
  1.1654 +	test.Printf( _L("Test accesses past end of media produce an error\n") );
  1.1655 +
  1.1656 +	TBuf8<1024> buf;
  1.1657 +	
  1.1658 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 1, buf ) );
  1.1659 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 2, buf ) );
  1.1660 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 512, buf ) );
  1.1661 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() + 1, 512, buf ) );
  1.1662 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() + 512, 512, buf ) );
  1.1663 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 1, 2, buf ) );
  1.1664 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 511, 512, buf ) );
  1.1665 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 512, 513, buf ) );
  1.1666 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 65536, 65537, buf ) );
  1.1667 +	test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 512, 1024, buf ) );
  1.1668 +	}
  1.1669 +
  1.1670 +
  1.1671 +void WriteAcrossBoundaries(TInt64 aBoundary)
  1.1672 +	{
  1.1673 +	test.Printf( _L("Test for aliasing around boundary\n") );
  1.1674 +	TBuf8<512> bufLo;
  1.1675 +	TBuf8<512> bufHi;
  1.1676 +	TBuf8<8192> bufRead;
  1.1677 +	
  1.1678 +	bufLo.Fill( 0xE4, 512 );
  1.1679 +	bufHi.Fill( 0x19, 512 );
  1.1680 +
  1.1681 +	TEST_FOR_ERROR( TheMmcDrive.Write( 0, bufLo ) );
  1.1682 +	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) );
  1.1683 +	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
  1.1684 +	test( bufRead == bufLo );
  1.1685 +	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) );
  1.1686 +	test( bufRead == bufHi );
  1.1687 +
  1.1688 +	bufHi.Fill( 0xBB, 1 );
  1.1689 +	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) );
  1.1690 +	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
  1.1691 +	test( bufRead == bufLo );
  1.1692 +
  1.1693 +	bufHi.Fill( 0xCC, 1 );
  1.1694 +	TEST_FOR_ERROR( TheMmcDrive.Write( (aBoundary+1), bufHi ) );
  1.1695 +	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
  1.1696 +	test( bufRead == bufLo );
  1.1697 +
  1.1698 +	test.Printf( _L("Test write which ends at boundary\n") );
  1.1699 +	bufHi.Fill( 0x33, 512 );
  1.1700 +	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) );
  1.1701 +	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) );
  1.1702 +	test( bufRead == bufHi );
  1.1703 +
  1.1704 +	bufHi.Fill( 0x44, 512 );
  1.1705 +	TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512, bufHi ) );
  1.1706 +	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary - 512, 512, bufRead ) );
  1.1707 +	test( bufRead == bufHi );
  1.1708 +
  1.1709 +	TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) );
  1.1710 +	test( bufRead == bufLo );
  1.1711 +
  1.1712 +	bufHi.Fill( 0x33, 512 );
  1.1713 +	TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) );
  1.1714 +	test( bufRead == bufHi );
  1.1715 +
  1.1716 +	test.Printf( _L("Test read-modify-write across boundary\n") );
  1.1717 +	TBuf8<512> rmw;
  1.1718 +	TBuf8<8192> data;
  1.1719 +	rmw.Fill( 0x66, 512 );
  1.1720 +	data.Fill( 0x11, 8192 );
  1.1721 +	
  1.1722 +	for( TInt i = 1; i < 511; ++i )
  1.1723 +		{
  1.1724 +		ProgressBar(i, 511, 11);
  1.1725 +	
  1.1726 +		// Create initial data block
  1.1727 +		TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512, data ) );
  1.1728 +
  1.1729 +		// Read-modify-write some data
  1.1730 +		TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512 + i, rmw ) );
  1.1731 +
  1.1732 +		// Modify buffer to what we expect
  1.1733 +		data.MidTPtr( i, 512 ) = rmw;
  1.1734 +
  1.1735 +		// Read it back and check it matches
  1.1736 +		TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary - 512, 8192, bufRead ) );
  1.1737 +		test( CompareBuffers( bufRead, data ) );
  1.1738 +		}
  1.1739 +	test.Printf(_L("\n"));
  1.1740 +	}
  1.1741 +
  1.1742 +
  1.1743 +/**
  1.1744 +@SYMTestCaseID PBASE-T_MMCDRV-0167
  1.1745 +@SYMTestCaseDesc Test that the boundary >2GB doesn't produce aliases or errors
  1.1746 +@SYMTestPriority High
  1.1747 +
  1.1748 +@SYMTestActions  
  1.1749 +	a. Test that writing at the 2G boundary does not produce aliases.
  1.1750 +	b. Test writes that end at the 2G boundary.
  1.1751 +	c. Test read/modify/write across the 2G boundary.
  1.1752 +
  1.1753 +@SYMTestExpectedResults All tests must pass
  1.1754 +
  1.1755 +@SYMPREQ1389 CR0795 Support for >2G SD Cards
  1.1756 +*/
  1.1757 +void TestBoundaries()
  1.1758 +	{
  1.1759 +
  1.1760 +	if( TheMmcDrive.Size() < 0x80008000 )
  1.1761 +		{
  1.1762 +		test.Printf( _L("Drive not large enough for 2GB boundary test... skipped\n") );
  1.1763 +		return;
  1.1764 +		}
  1.1765 +		
  1.1766 +	// Test that the boundary 2GB doesn't produce aliases or errors
  1.1767 +	// >2Gb cards change addressing scheme from byte to block base
  1.1768 +	test.Next( _L("Test 2GB boundary") );	
  1.1769 +	WriteAcrossBoundaries(0x80000000);
  1.1770 +	
  1.1771 +// N.B. Commented Out for now due to compiler warnings	
  1.1772 +//	if( TheMmcDrive.Size() < 0x100008000ll )
  1.1773 +//			{
  1.1774 +//			test.Printf( _L("Drive not large enough for 4GB boundary test... skipped\n") );
  1.1775 +//			return;
  1.1776 +//			}
  1.1777 +//	// Test that the boundary 4GB doesn't produce aliases or errors
  1.1778 +//	// >4GB cards change addressing scheme from 32bit to 64bit addresses
  1.1779 +//	test.Next( _L("Test 4GB boundary") );	
  1.1780 +//	WriteAcrossBoundaries(0x100000000ll); 
  1.1781 +	}
  1.1782 +
  1.1783 +
  1.1784 +/**
  1.1785 +@SYMTestCaseID PBASE-T_MMCDRV-0512
  1.1786 +@SYMTestCaseDesc Test Media Change/Capabilities Reporting
  1.1787 +@SYMTestPriority High
  1.1788 +
  1.1789 +@SYMTestActions
  1.1790 +	    a.) Test Media Change flag after Media Change
  1.1791 +		b.) Test Capabilities reporting for Out Of Memory Conditions
  1.1792 +        c.) Test Media Change flag after Machine power-off
  1.1793 +		d.) Test Capabilities reporting after Machine power-off
  1.1794 +		e.) Test Multiple Media Change flags after Media Change
  1.1795 +
  1.1796 +@SYMTestExpectedResults All tests must pass	
  1.1797 +*/
  1.1798 +void TestMediaChange()
  1.1799 +	{
  1.1800 +	test.Next(_L("MMC drive: Media change"));
  1.1801 +#if defined (__WINS__)
  1.1802 +	test.Printf( _L("<<<Hit F5 - then any other key>>>\r\n"));
  1.1803 +#else
  1.1804 +	test.Printf( _L("<<<Generate Media change - then hit a key>>>\r\n"));
  1.1805 +#endif
  1.1806 +	test.Getch();
  1.1807 +	User::After(300000);	// Allow 0.3s after power down for controller to detect door closed.
  1.1808 +	test(ChangeFlag!=EFalse);
  1.1809 +
  1.1810 +	test.Next(_L("MMC drive: Caps following media change"));
  1.1811 +	
  1.1812 +	TLocalDriveCapsV4 info;
  1.1813 +	TPckg<TLocalDriveCapsV4> infoPckg(info);
  1.1814 +	
  1.1815 +	test(TheMmcDrive.Caps(infoPckg)==KErrNone);
  1.1816 +	test(info.iType==EMediaHardDisk);
  1.1817 +
  1.1818 +	test.Next(_L("MMC drive: Caps while OOM"));
  1.1819 +	TInt err;
  1.1820 +	test.Printf(_L("Mount returns:"));
  1.1821 +	for (TInt j=1;j<16;j++)
  1.1822 +		{
  1.1823 +		__KHEAP_SETFAIL(RHeap::EDeterministic,j);
  1.1824 +		err=TheMmcDrive.Caps(infoPckg);
  1.1825 +		test.Printf(_L("(%d)"),err);
  1.1826 +		__KHEAP_RESET;
  1.1827 +		}
  1.1828 +	test.Printf(_L("\r\n"));
  1.1829 +
  1.1830 +	test.Next(_L("MMC drive: Machine power-off."));
  1.1831 +	ChangeFlag=EFalse;
  1.1832 +	RTimer timer;
  1.1833 +	TRequestStatus trs;
  1.1834 +	test(timer.CreateLocal()==KErrNone);
  1.1835 +	TTime tim;
  1.1836 +	tim.HomeTime();
  1.1837 +	tim+=TTimeIntervalSeconds(8);
  1.1838 +	timer.At(trs,tim);
  1.1839 +	UserHal::SwitchOff();
  1.1840 +	User::WaitForRequest(trs);
  1.1841 +	test(trs.Int()==KErrNone);
  1.1842 +	test(ChangeFlag==EFalse);		// ie machine power off hasn't updated it
  1.1843 +
  1.1844 +	test.Next(_L("MMC drive: Caps following power off"));
  1.1845 +	TInt r=TheMmcDrive.Caps(infoPckg);
  1.1846 +	test(r==KErrNone);
  1.1847 +	test(info.iType==EMediaHardDisk);
  1.1848 +
  1.1849 +	test.Next(_L("Starting 2nd thread"));
  1.1850 +	SecThreadChangeFlag=EFalse;
  1.1851 +	RThread thread;
  1.1852 +	TRequestStatus stat;
  1.1853 +	test(thread.Create(_L("Thread"),dontDisconnectThread,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone);
  1.1854 +	thread.Logon(stat);
  1.1855 +	thread.Resume();
  1.1856 +	User::WaitForRequest(stat);
  1.1857 +	test(stat==KErrNone);
  1.1858 +	thread.Close();
  1.1859 +
  1.1860 +	test.Next(_L("MMC drive: 2nd media change"));
  1.1861 +//	UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change	
  1.1862 +	test(ChangeFlag!=EFalse);
  1.1863 +	test(SecThreadChangeFlag==EFalse); // Closed 2nd thread so shouldn't have been updated
  1.1864 +	}
  1.1865 +	
  1.1866 +
  1.1867 +//// End of Test 
  1.1868 +void Format()
  1.1869 +//
  1.1870 +// Format current drive
  1.1871 +//
  1.1872 +	{
  1.1873 +	RFs TheFs;
  1.1874 +	test(TheFs.Connect() == KErrNone);
  1.1875 +	
  1.1876 +	test.Next(_L("Format"));
  1.1877 +	TBuf<4> driveBuf=_L("?:\\");
  1.1878 +	driveBuf[0]=(TText)(RFsDNum+'A');
  1.1879 +	
  1.1880 +	RFormat format;
  1.1881 +	TInt count;
  1.1882 +	TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count);
  1.1883 +	test(r==KErrNone);
  1.1884 +	while(count)
  1.1885 +		{
  1.1886 +		TInt r=format.Next(count);
  1.1887 +		test(r==KErrNone);
  1.1888 +		}
  1.1889 +	format.Close();
  1.1890 +	}
  1.1891 +
  1.1892 +void AllocateBuffers()
  1.1893 +	{
  1.1894 +	test.Next(_L("Allocate Buffers"));
  1.1895 +
  1.1896 +	//HBufC8* wrBufH = NULL;
  1.1897 +	//HBufC8* rdBufH = NULL;
  1.1898 +
  1.1899 +	wrBufH = HBufC8::New(KVeryLongRdWrBufLen);
  1.1900 +	test(wrBufH != NULL);
  1.1901 +
  1.1902 +	rdBufH = HBufC8::New(KVeryLongRdWrBufLen);
  1.1903 +	if(rdBufH == NULL) delete wrBufH;
  1.1904 +	test(rdBufH != NULL);
  1.1905 +
  1.1906 +	wrBuf.Set(wrBufH->Des());
  1.1907 +	rdBuf.Set(rdBufH->Des());
  1.1908 +	}
  1.1909 +	
  1.1910 +void AllocateSharedBuffers(TBool Fragmented, TBool Caching)
  1.1911 +	{
  1.1912 +	// Setup SharedMemory Buffers
  1.1913 +	test.Next(_L("Allocate Shared Memory\n"));
  1.1914 +	
  1.1915 +	RLoader l;
  1.1916 +	test(l.Connect()==KErrNone);
  1.1917 +	test(l.CancelLazyDllUnload()==KErrNone);
  1.1918 +	l.Close();
  1.1919 +
  1.1920 +	test.Printf(_L("Initialise\n"));
  1.1921 +	TInt r = UserHal::PageSizeInBytes(PageSize);
  1.1922 +	test(r==KErrNone);
  1.1923 +
  1.1924 +	test.Printf(_L("Loading test driver\n"));
  1.1925 +	r = User::LoadLogicalDevice(KSharedChunkLddName);
  1.1926 +	test(r==KErrNone || r==KErrAlreadyExists);
  1.1927 +
  1.1928 +	test.Printf(_L("Opening channel\n"));
  1.1929 +	r = Ldd.Open();
  1.1930 +	test(r==KErrNone);
  1.1931 +
  1.1932 +	test.Printf(_L("Create chunk\n"));
  1.1933 +	
  1.1934 +	TUint aCreateFlags = EMultiple|EOwnsMemory;
  1.1935 +	
  1.1936 +	if (Caching)
  1.1937 +		{
  1.1938 +		test.Printf(_L("Chunk Type:Caching\n"));
  1.1939 +		aCreateFlags |= ECached;
  1.1940 +		}
  1.1941 +	else
  1.1942 +		test.Printf(_L("Chunk Type:Fully Blocking\n"));
  1.1943 +	
  1.1944 +    TCommitType aCommitType = EContiguous;
  1.1945 +      
  1.1946 +    TUint TotalChunkSize = ChunkSize;  // rounded to nearest Page Size
  1.1947 +    
  1.1948 +	TUint ChunkAttribs = TotalChunkSize|aCreateFlags;	
  1.1949 +	r = Ldd.CreateChunk(ChunkAttribs);
  1.1950 +	test(r==KErrNone);
  1.1951 +
  1.1952 +	if(Fragmented)
  1.1953 +		{
  1.1954 +		test.Printf(_L("Commit Fragmented Memory\n"));
  1.1955 +			
  1.1956 +		// Allocate Pages in reverse order to maximise memory fragmentation
  1.1957 +		TUint i = ChunkSize;
  1.1958 +		do
  1.1959 +			{
  1.1960 +			i-=PageSize;
  1.1961 +			test.Printf(_L("Commit %d\n"), i);
  1.1962 +			r = Ldd.CommitMemory(aCommitType|i,PageSize);
  1.1963 +			test(r==KErrNone);
  1.1964 +			}while (i>0);
  1.1965 +		}
  1.1966 +	else
  1.1967 +		{
  1.1968 +		test.Printf(_L("Commit Contigouos Memory\n"));
  1.1969 +		r = Ldd.CommitMemory(aCommitType,TotalChunkSize);
  1.1970 +		test(r==KErrNone);
  1.1971 +		}
  1.1972 +
  1.1973 +	test.Printf(_L("Open user handle\n"));
  1.1974 +	r = Ldd.GetChunkHandle(TheChunk);
  1.1975 +	test(r==KErrNone);
  1.1976 +	
  1.1977 +	}
  1.1978 +
  1.1979 +
  1.1980 +void DeAllocateBuffers()
  1.1981 +	{
  1.1982 +	delete rdBufH;
  1.1983 +	delete wrBufH;
  1.1984 +	}
  1.1985 +
  1.1986 +void DeAllocareSharedMemory()
  1.1987 +	{
  1.1988 +// destory chunk
  1.1989 +	test.Printf(_L("Shared Memory\n"));
  1.1990 +	test.Printf(_L("Close user chunk handle\n"));
  1.1991 +	TheChunk.Close();
  1.1992 +
  1.1993 +	test.Printf(_L("Close kernel chunk handle\n"));
  1.1994 +	TInt r = Ldd.CloseChunk();  // 1==DObject::EObjectDeleted
  1.1995 +	test(r==1);
  1.1996 +
  1.1997 +	test.Printf(_L("Check chunk is destroyed\n"));
  1.1998 +	r = Ldd.IsDestroyed();
  1.1999 +	test(r==1);
  1.2000 +        
  1.2001 +	test.Printf(_L("Close test driver\n"));
  1.2002 +	Ldd.Close();
  1.2003 +	}
  1.2004 +
  1.2005 +
  1.2006 +TBool SetupDrivesForPlatform(TInt& aDrive, TInt &aRFsDriveNum)
  1.2007 +/**
  1.2008 + * Finds a MMC/SD suitable drive for testing
  1.2009 + *
  1.2010 + * @param aDrive  The number of the local drive to test
  1.2011 + * @return TBool ETrue if a suitable drive is found, EFalse otherwise.
  1.2012 + */
  1.2013 +	{
  1.2014 +	
  1.2015 +	TDriveInfoV1Buf diBuf;
  1.2016 +	UserHal::DriveInfo(diBuf);
  1.2017 +	TDriveInfoV1 &di=diBuf();
  1.2018 +
  1.2019 +	test.Printf(_L(" iRegisteredDriveBitmask 0x%08X"), di.iRegisteredDriveBitmask);
  1.2020 +
  1.2021 +	aDrive  = -1;
  1.2022 +	
  1.2023 +	TLocalDriveCapsV5Buf capsBuf;
  1.2024 +	TBusLocalDrive TBLD;
  1.2025 +	TLocalDriveCapsV5& caps = capsBuf();
  1.2026 +	TPtrC8 localSerialNum;
  1.2027 +	TInt registeredDriveNum = 0;
  1.2028 +	for(aDrive=0; aDrive < KMaxLocalDrives; aDrive++)
  1.2029 +		{
  1.2030 +		TInt driveNumberMask = 1 << aDrive;
  1.2031 +		if ((di.iRegisteredDriveBitmask & driveNumberMask) == 0)
  1.2032 +			continue;
  1.2033 +
  1.2034 +		test.Printf(_L(" Drive %d -  %S\r\n"), aDrive, &di.iDriveName[registeredDriveNum]);
  1.2035 +
  1.2036 +		// check that the card is readable (so we can ignore for empty card slots)
  1.2037 +		if ((di.iDriveName[registeredDriveNum].MatchF(_L("MultiMediaCard0")) == KErrNone) ||
  1.2038 +		    (di.iDriveName[registeredDriveNum].MatchF(_L("SDIOCard0")) == KErrNone))
  1.2039 +			{
  1.2040 +			
  1.2041 +			TBool TBLDChangedFlag;
  1.2042 +			TInt r = TBLD.Connect(aDrive, TBLDChangedFlag);
  1.2043 +//test.Printf(_L(" Connect returned %d\n"), r);
  1.2044 +			if (r == KErrNone)
  1.2045 +				{
  1.2046 +				r = TBLD.Caps(capsBuf);
  1.2047 +				localSerialNum.Set(caps.iSerialNum, caps.iSerialNumLength);
  1.2048 +				const TInt KSectSize = 512;
  1.2049 +				TBuf8<KSectSize> sect;
  1.2050 +				r = TBLD.Read(0, KSectSize, sect);
  1.2051 +//test.Printf(_L(" Read returned %d\n"), r);
  1.2052 +				
  1.2053 +				TBLD.Disconnect();
  1.2054 +				if (r == KErrNone)
  1.2055 +					break;
  1.2056 +				}
  1.2057 +			}
  1.2058 +		registeredDriveNum++;
  1.2059 +		}
  1.2060 +
  1.2061 +	if(aDrive == KMaxLocalDrives)
  1.2062 +		{
  1.2063 +		test.Printf(_L(" MMC Drive Not Found\r\n"));
  1.2064 +		return EFalse;
  1.2065 +		}
  1.2066 +
  1.2067 +	// Work out the file server drive number (which isn't necessarily the same 
  1.2068 +	// as the TBusLocalDrive drive number)
  1.2069 +	RFs theFs;
  1.2070 +	test(theFs.Connect() == KErrNone);
  1.2071 +
  1.2072 +	TInt i;
  1.2073 +	for (i = EDriveA; i < EDriveZ; i++)
  1.2074 +		{
  1.2075 +		TMediaSerialNumber serialNum;
  1.2076 +	    TInt r = theFs.GetMediaSerialNumber(serialNum, i);
  1.2077 +		TInt len = serialNum.Length();
  1.2078 +		TInt n;
  1.2079 +		for (n=0; n<len; n+=16)
  1.2080 +		{
  1.2081 +		TBuf16<16*3 +1> buf;
  1.2082 +			for (TInt m=n; m<n+16; m++)
  1.2083 +				{
  1.2084 +				TBuf16<3> hexBuf;
  1.2085 +				hexBuf.Format(_L("%02X "),serialNum[m]);
  1.2086 +				buf.Append(hexBuf);
  1.2087 +				}
  1.2088 +		buf.Append(_L("\n"));
  1.2089 +		test.Printf(buf);
  1.2090 +		}
  1.2091 +		if (serialNum.Compare(localSerialNum) == 0)
  1.2092 +			{
  1.2093 +			TVolumeInfo vi;
  1.2094 +	        r = theFs.Volume(vi, i);
  1.2095 +			TBool sizeMatch = (vi.iSize < caps.iSize);
  1.2096 +			if (sizeMatch)
  1.2097 +				{
  1.2098 +				aRFsDriveNum = i;
  1.2099 +				break;
  1.2100 +				}
  1.2101 +			}
  1.2102 +		
  1.2103 +		}
  1.2104 +	if (i == EDriveZ)
  1.2105 +		{
  1.2106 +		test.Printf(_L(" RFs MMC Drive Not Found\r\n"));
  1.2107 +		return EFalse;
  1.2108 +		}
  1.2109 +
  1.2110 +	theFs.Close();
  1.2111 +
  1.2112 +	return ETrue;
  1.2113 +	}
  1.2114 +
  1.2115 +
  1.2116 +LOCAL_D TBool ParseCommandLineArgs()
  1.2117 +	{
  1.2118 +	
  1.2119 +	TBuf<0x100> cmd;
  1.2120 +	User::CommandLine(cmd);
  1.2121 +	TLex lex(cmd);
  1.2122 +
  1.2123 +    for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken()))
  1.2124 +		{
  1.2125 +		if (token.CompareF(_L("-m"))== 0)
  1.2126 +			{
  1.2127 +			ManualMode = ETrue;
  1.2128 +			continue;
  1.2129 +			}
  1.2130 +		}
  1.2131 +	
  1.2132 +	if (ManualMode)
  1.2133 +		{
  1.2134 +		// Get the list of drives
  1.2135 +		TDriveInfoV1Buf diBuf;
  1.2136 +		UserHal::DriveInfo(diBuf);
  1.2137 +		TDriveInfoV1 &di=diBuf();
  1.2138 +		TInt driveCount = di.iTotalSupportedDrives;
  1.2139 +		
  1.2140 +		//Print the list of usable drives
  1.2141 +		test.Printf(_L("\nDRIVES USED AT PRESENT :\r\n"));
  1.2142 +
  1.2143 +		for (TInt i=0; i < driveCount; i++)
  1.2144 +			{
  1.2145 +			TBool flag=EFalse;
  1.2146 +			RLocalDrive d;
  1.2147 +			TInt r=d.Connect(i,flag);
  1.2148 +			//Not all the drives are used at present
  1.2149 +			if (r == KErrNotSupported)
  1.2150 +				continue;
  1.2151 +
  1.2152 +			test.Printf(_L("%d : DRIVE NAME  :%- 16S\r\n"), i, &di.iDriveName[i]);
  1.2153 +			}	
  1.2154 +		
  1.2155 +		test.Printf(_L("\r\nWarning - all data on removable drive will be lost.\r\n"));
  1.2156 +		test.Printf(_L("<<<Hit mmc drive number to continue>>>\r\n"));
  1.2157 +
  1.2158 +		TChar driveToTest;
  1.2159 +		driveToTest=(TUint)test.Getch();
  1.2160 +		DriveNumber=((TUint)driveToTest) - '0';
  1.2161 +		test(DriveNumber >= 1 && DriveNumber < di.iTotalSupportedDrives);
  1.2162 +		
  1.2163 +		return ETrue;
  1.2164 +		}
  1.2165 +	else
  1.2166 +		{
  1.2167 +		//Auto Mode
  1.2168 +		//Lets find an MMC Drive to Test with....		
  1.2169 +		return SetupDrivesForPlatform(DriveNumber, RFsDNum);
  1.2170 +		}
  1.2171 +	}
  1.2172 +
  1.2173 +
  1.2174 +GLDEF_C TInt E32Main()
  1.2175 +	{
  1.2176 +	test.Title();
  1.2177 +	test.Start(_L("Test the MultiMediaCard (MMC) media driver"));
  1.2178 +
  1.2179 +	if (!ParseCommandLineArgs())
  1.2180 +		{
  1.2181 +		test.Printf(_L("MMC Drive Not Found - Skipping test\r\n"));
  1.2182 +		test.End();
  1.2183 +		return(0);
  1.2184 +		}
  1.2185 +	
  1.2186 +	AllocateBuffers();
  1.2187 +
  1.2188 +	test.Printf(_L("Connect to local drive (%d)\n"),DriveNumber);
  1.2189 +
  1.2190 +	ChangeFlag=EFalse;
  1.2191 +	test(TheMmcDrive.Connect(DriveNumber,ChangeFlag)==KErrNone);
  1.2192 +
  1.2193 +	TTime startTime;
  1.2194 +	startTime.HomeTime();
  1.2195 +	
  1.2196 +	IsReadOnly = TestDriveInfo();
  1.2197 +
  1.2198 +	// The following line causes t_mmcdrv to jump to the tests that check if the
  1.2199 +	// mmc driver will carry on reading when the door is opened, but abort with
  1.2200 +	// KErrGeneral when it is not.	Enabling the goto here is useful because it
  1.2201 +	// allows the tester to skip the long read and write tests, which can take several
  1.2202 +	// minutes on a 16Mb card, and longer if tracing is enabled.  It also stops the test
  1.2203 +	// from returning when !mediaChangeSupported and not getting to the door opening tests.
  1.2204 +
  1.2205 +#if TEST_DOOR_CLOSE
  1.2206 +	goto doorTest;
  1.2207 +#endif
  1.2208 +	
  1.2209 +	for(TInt pass = 0; pass < TMMCDrive::EMaxTestModes; pass++) 
  1.2210 +		{
  1.2211 +		TInt r = KErrNone;
  1.2212 +		switch (pass)
  1.2213 +			{			
  1.2214 +			case 0 : r = TheMmcDrive.SetTestMode(TMMCDrive::ETestPartition); break;
  1.2215 +			case 1 : 
  1.2216 +				// don't trash partition table in automated mode because...
  1.2217 +				// cards in test rigs have often got deliberately small partition sizes to testing (!)
  1.2218 +				if (!ManualMode)
  1.2219 +					continue;
  1.2220 +				r = TheMmcDrive.SetTestMode(TMMCDrive::ETestWholeMedia); 
  1.2221 +				break; 
  1.2222 +			case 2 : {
  1.2223 +						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemory);
  1.2224 +						AllocateSharedBuffers(EFalse,EFalse);
  1.2225 +						break;
  1.2226 +					 }
  1.2227 +			case 3 : {
  1.2228 +						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryCache); 
  1.2229 +						AllocateSharedBuffers(EFalse, ETrue);
  1.2230 +						break;
  1.2231 +					 }
  1.2232 +			case 4 : {
  1.2233 +						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryFrag);
  1.2234 +						AllocateSharedBuffers(ETrue, EFalse);
  1.2235 +						break;
  1.2236 +			         }
  1.2237 +			default: {
  1.2238 +						r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryFragCache);
  1.2239 +						AllocateSharedBuffers(ETrue, ETrue);
  1.2240 +						break;
  1.2241 +			         }
  1.2242 +			}
  1.2243 +
  1.2244 +
  1.2245 +		if(r == KErrNone)
  1.2246 +			{
  1.2247 +			TestRead();
  1.2248 +			TestCapacity();
  1.2249 + 
  1.2250 +			if(IsReadOnly == EFalse)
  1.2251 +				{
  1.2252 +				TestMultipleBlockReads();
  1.2253 +				TestSectorReadWrite();
  1.2254 +				TestWrite();
  1.2255 +				TestBoundaries();
  1.2256 +				TestFormat();
  1.2257 +				}
  1.2258 +			}
  1.2259 +		
  1.2260 +		if (pass > 1)
  1.2261 +			{
  1.2262 +			// Shared memory Test Mode in use
  1.2263 +			DeAllocareSharedMemory();
  1.2264 +			}
  1.2265 +		}
  1.2266 +
  1.2267 +	if (mediaChangeSupported)
  1.2268 +		{
  1.2269 +		// Remainder of tests involve media change
  1.2270 +		TestMediaChange();
  1.2271 +		
  1.2272 +		#if TEST_DOOR_CLOSE
  1.2273 +doorTest:
  1.2274 +		#endif
  1.2275 +		test.Next(_L("Launching 1.0Mb Read to interrupt with media change.\n"));
  1.2276 +		TestHugeReadWrite(ETrue, 512 * 1024);
  1.2277 +
  1.2278 +		test.Next(_L("Launching 1.0Mb Write to interrupt with media change.\n"));
  1.2279 +		TestHugeReadWrite(EFalse, 512 * 1024);
  1.2280 +		}
  1.2281 +		
  1.2282 +	TTime endTime;
  1.2283 +	endTime.HomeTime();
  1.2284 +	TTimeIntervalMicroSeconds elapsed=endTime.MicroSecondsFrom(startTime);
  1.2285 +	test.Printf(_L("\n\r   (Elapsed time: %dmS)\r\n"),(elapsed.Int64()/1000));
  1.2286 +	
  1.2287 +	test.Printf(_L("Disconnect from local drive (%d)"),DriveNumber);
  1.2288 +	TheMmcDrive.Disconnect();
  1.2289 +
  1.2290 +	DeAllocateBuffers();
  1.2291 +
  1.2292 +	// Format card with a File System i.e. FAT
  1.2293 +	// Such that it is re-usable by next test
  1.2294 +	Format();
  1.2295 +	
  1.2296 +	test.End();
  1.2297 +
  1.2298 +	return(0);
  1.2299 +	}
  1.2300 +