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