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