kerneltest/e32test/lffs/tf_erase.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Tests erasing of Flash. Does not test suspending (see TF_SUSPEND)
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32std.h>
       
    19 #include <e32std_private.h>
       
    20 #include <e32svr.h>
       
    21 #include <e32test.h>
       
    22 #include "randgen.h"
       
    23 #include "user_config.h"
       
    24 
       
    25 RTest test( _L("TF_ERASE") );
       
    26 
       
    27 
       
    28 class CEraseTest : public CBase
       
    29 	{
       
    30 	public:
       
    31 		~CEraseTest();
       
    32 
       
    33 		void CreateL();
       
    34 
       
    35 		void DoTest();
       
    36 
       
    37 	private:
       
    38 		void DoSimpleTest();
       
    39 		void DoSimpleTest2();
       
    40 		void DoPseudoRandomTest();
       
    41 		void DoRangeTest();
       
    42 
       
    43 		TInt EraseOneBlock( TInt aBlockNumber );
       
    44 		TInt ZeroFillBlock( TInt aBlockNumber );
       
    45 		TBool ValidateBlock( TInt aBlockNumber, TUint32 aFillWord );
       
    46 
       
    47 
       
    48 	private:
       
    49 		TBusLocalDrive	iDrive;
       
    50 		TBool			iDriveOpened;
       
    51 
       
    52 		TInt			iFlashSize;
       
    53 		TInt			iBlockSize;
       
    54 		TInt			iBlockCount;
       
    55 
       
    56 		TBuf8<512>		iReadBuffer;
       
    57 
       
    58 	};
       
    59 
       
    60 
       
    61 CEraseTest::~CEraseTest()
       
    62 	{
       
    63 	if( iDriveOpened )
       
    64 		{
       
    65 		iDrive.Disconnect();
       
    66 		}
       
    67 	}
       
    68 
       
    69 
       
    70 
       
    71 void CEraseTest::CreateL()
       
    72 	{
       
    73 	//
       
    74 	// Load the device drivers
       
    75 	//
       
    76 #ifndef SKIP_PDD_LOAD
       
    77 	test.Printf( _L("Loading %S\n"), &KLfsDriverName );
       
    78 	r = User::LoadPhysicalDevice( KLfsDriverName );
       
    79 	test( KErrNone == r || KErrAlreadyExists == r );
       
    80 #endif
       
    81 
       
    82 #ifdef UNMOUNT_DRIVE
       
    83 	RFs fs;
       
    84 	test( KErrNone == fs.Connect() );
       
    85 #if 0
       
    86 	// XXX - not eka2
       
    87 	test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) );
       
    88 #endif
       
    89 	TFullName name;
       
    90 	fs.FileSystemName( name, KLffsLogicalDriveNumber );
       
    91 	if( name.Length() > 0 )
       
    92 		{
       
    93 		test.Printf( _L("Unmounting drive") );
       
    94 		test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) );
       
    95 		User::After( 2000000 );
       
    96 		test.Printf( _L("Drive unmounted") );
       
    97 		}
       
    98 	fs.Close();
       
    99 #endif
       
   100 
       
   101 	//
       
   102 	// Open a TBusLogicalDevice to drive
       
   103 	//
       
   104 	test.Printf( _L("Opening media channel\n") );
       
   105 	static TBool changedFlag = EFalse;
       
   106 	User::LeaveIfError( iDrive.Connect( KDriveNumber, changedFlag ) );
       
   107 	iDriveOpened = ETrue;
       
   108 
       
   109 	//
       
   110 	// Get size of Flash drive, block size, block count
       
   111 	//
       
   112 	TLocalDriveCapsV2Buf info;
       
   113     iDrive.Caps(info);
       
   114 	iFlashSize = I64LOW(info().iSize);
       
   115 	iBlockSize = info().iEraseBlockSize;
       
   116 	iBlockCount = iFlashSize / iBlockSize;
       
   117 
       
   118 	test.Printf( _L("Flash size is 0x%x bytes\n"), iFlashSize );
       
   119 	test.Printf( _L("Block size is 0x%x bytes\n"), iBlockSize );
       
   120 	test.Printf( _L("Block count is %d\n"), iBlockCount );
       
   121 
       
   122 	test.Printf( _L("CreateL complete\n") );
       
   123 	}
       
   124 
       
   125 
       
   126 void CEraseTest::DoTest()
       
   127 	//
       
   128 	// Main test dispatcher
       
   129 	//
       
   130 	{
       
   131 	test.Next( _L("Starting tests...") );
       
   132 	DoSimpleTest();
       
   133 	DoSimpleTest2();
       
   134 	DoPseudoRandomTest();
       
   135 	DoRangeTest();
       
   136 	}
       
   137 
       
   138 
       
   139 TInt CEraseTest::EraseOneBlock( TInt aBlockNumber )
       
   140 	//
       
   141 	// Erases block aBlockNumber on Flash
       
   142 	//
       
   143 	{
       
   144 	TInt blockBaseOffset = aBlockNumber * iBlockSize;
       
   145 
       
   146 	test.Printf( _L("Erasing block %d (offs=0x%x)\n"), aBlockNumber, blockBaseOffset );
       
   147 	
       
   148 	TInt r = iDrive.Format( blockBaseOffset, iBlockSize );
       
   149 
       
   150 	test.Printf( _L("... Format returned %d\n"), r );
       
   151 	return r;
       
   152 	}
       
   153 
       
   154 
       
   155 TBool CEraseTest::ValidateBlock( TInt aBlockNumber, TUint32 aFillWord )
       
   156 	//
       
   157 	// Checks that every word in block aBlockNumber has the value aFillWord
       
   158 	//
       
   159 	{
       
   160 	TUint offset = aBlockNumber * iBlockSize;
       
   161 	test.Printf( _L("Validating block %d (offs=0x%x)\n"), aBlockNumber, offset );
       
   162 	
       
   163 	TBool failed = EFalse;
       
   164 	const TInt readBufLen = iReadBuffer.MaxLength();
       
   165 
       
   166 	for( TInt len = iBlockSize; len > 0 && !failed ;)
       
   167 		{
       
   168 		TInt r = iDrive.Read( offset, readBufLen, iReadBuffer );
       
   169 		if( r != KErrNone )
       
   170 			{
       
   171 			test.Printf( _L("... FAIL: read failed (%d) at offset 0x%x\n"), r, offset );
       
   172 			test( KErrNone == r );
       
   173 			}
       
   174 		test( iReadBuffer.Length() == readBufLen );
       
   175 
       
   176 		TUint32* p = (TUint32*)iReadBuffer.Ptr();
       
   177 		for( TInt i = 0; i < readBufLen; i += 4 )
       
   178 			{
       
   179 			if( aFillWord != *p )
       
   180 				{
       
   181 				failed = ETrue;
       
   182 				test.Printf( _L("... FAILED: word @ offs=0x%x, read=0x%x, expected=0x%x\n"), 
       
   183 								offset+i, p[0], aFillWord );
       
   184 				break;
       
   185 				}
       
   186 			++p;
       
   187 			}
       
   188 		offset += readBufLen;
       
   189 		len -= readBufLen;
       
   190 		}
       
   191 	
       
   192 	return !failed;
       
   193 	}
       
   194 
       
   195 
       
   196 TInt CEraseTest::ZeroFillBlock( TInt aBlockNumber )
       
   197 	//
       
   198 	// Zero-fills an entire block
       
   199 	// The requires that writing works (so as a side-effect performs a
       
   200 	// very basic test of writing)
       
   201 	//
       
   202 	{
       
   203 	test.Printf( _L("Zero-filling block %d\n"), aBlockNumber );
       
   204 
       
   205 	//
       
   206 	// Create a buffer full of zeros
       
   207 	//
       
   208 	const TInt KZeroBufSize = 512;
       
   209 
       
   210 	TBuf8<KZeroBufSize> buf;
       
   211 	buf.FillZ( buf.MaxLength() );
       
   212 
       
   213 	//
       
   214 	// Write the data out to the Flash
       
   215 	//
       
   216 	TInt writeCount = iBlockSize / KZeroBufSize;
       
   217 	TInt r = KErrNone;
       
   218 	TInt blockBaseOffset = aBlockNumber * iBlockSize;
       
   219 	for( ; (writeCount > 0) && (KErrNone == r); writeCount-- )
       
   220 		{
       
   221 		r = iDrive.Write( blockBaseOffset, buf );
       
   222 		if( r != KErrNone )
       
   223 			{
       
   224 			test.Printf( _L("... FAIL: write failed (%d) at offset 0x%x\n"), r, blockBaseOffset );
       
   225 			}
       
   226 		blockBaseOffset += KZeroBufSize;
       
   227 		}
       
   228 
       
   229 	return r;
       
   230 	}
       
   231 
       
   232 
       
   233 void CEraseTest::DoSimpleTest()
       
   234 	//
       
   235 	// Simple erase test. This just zero-fills and then erases each block in turn
       
   236 	//
       
   237 	{
       
   238 	test.Next( _L("Simple test: erases each block in turn\n") );
       
   239 
       
   240 	for( TInt block = 0; block < iBlockCount; block++ )
       
   241 		{
       
   242 		test( KErrNone == ZeroFillBlock( block ) );
       
   243 		test( ValidateBlock( block, 0 ) );
       
   244 		test( KErrNone == EraseOneBlock( block ) );
       
   245 		test( ValidateBlock( block, 0xFFFFFFFF ) );
       
   246 		}
       
   247 	}
       
   248 
       
   249 void CEraseTest::DoSimpleTest2()
       
   250 	//
       
   251 	// Another simple erase test.
       
   252 	// This time we zero-fill all blocks first, then erase them all
       
   253 	//
       
   254 	{
       
   255 	test.Next( _L("Simple test2 : zero-fills whole Flash, then erases all blocks\n") );
       
   256 
       
   257 	for( TInt block = 0; block < iBlockCount; block++ )
       
   258 		{
       
   259 		test( KErrNone == ZeroFillBlock( block ) );
       
   260 		test( ValidateBlock( block, 0 ) );
       
   261 		}
       
   262 
       
   263 	for( TInt block = 0; block < iBlockCount; block++ )
       
   264 		{
       
   265 		test( KErrNone == EraseOneBlock( block ) );
       
   266 		test( ValidateBlock( block, 0xFFFFFFFF ) );
       
   267 		}
       
   268 	}
       
   269 
       
   270 
       
   271 
       
   272 void CEraseTest::DoPseudoRandomTest()
       
   273 	//
       
   274 	// Erases the blocks in pseudo-random order, zero-filling first
       
   275 	//
       
   276 	{
       
   277 	test.Next( _L("Test random erase order\n") );
       
   278 
       
   279 	TRandomGenerator random;
       
   280 #if 0
       
   281 	random.SetSeed( TInt64(0x1020466E, 0x3F9C0C00) );
       
   282 #else
       
   283 	random.SetSeed( 0x1020466E );
       
   284 #endif
       
   285 
       
   286 	for( TInt count = 0; count < 50; count++ )
       
   287 		{
       
   288 		TUint block = random.Next() % iBlockCount;
       
   289 		test( KErrNone == ZeroFillBlock( block ) );
       
   290 
       
   291 		test( ValidateBlock( block, 0 ) );
       
   292 
       
   293 		test( KErrNone == EraseOneBlock( block ) );
       
   294 
       
   295 		test( ValidateBlock( block, 0xFFFFFFFF ) );
       
   296 		}
       
   297 	}
       
   298 
       
   299 void CEraseTest::DoRangeTest()
       
   300 	//
       
   301 	// Simple erase test. This just zero-fills and then erases each block in turn
       
   302 	//
       
   303 	{
       
   304 	test.Next( _L("Range test: check that erase only affects erased block\n") );
       
   305 
       
   306 	//
       
   307 	// Pre-fill all blocks with zero
       
   308 	//
       
   309 	test.Printf( _L("Pre-zeroing blocks\n") );
       
   310 	for( TInt block = 0; block < iBlockCount; block++ )
       
   311 		{
       
   312 		test( KErrNone == ZeroFillBlock( block ) );
       
   313 		test( ValidateBlock( block, 0 ) );
       
   314 		}
       
   315 
       
   316 	//
       
   317 	// The test is to erase a block. Check it is erased and all
       
   318 	// other blocks are still zeros. Then we re-zero the block just
       
   319 	// erased and repeat test with next block
       
   320 	//
       
   321 	test.Printf( _L("Now testing erase...\n") );
       
   322 	for( TInt eraseBlock = 0; eraseBlock < iBlockCount; eraseBlock++ )
       
   323 		{
       
   324 		test( KErrNone == EraseOneBlock( eraseBlock ) );
       
   325 		test( ValidateBlock( eraseBlock, 0xFFFFFFFF ) );
       
   326 		
       
   327 		// check all other blocks are still zero
       
   328 		for( TInt j = 0; j < iBlockCount; j++ )
       
   329 			{
       
   330 			if( j != eraseBlock )
       
   331 				{
       
   332 				// test if not the one we just erased
       
   333 				test( ValidateBlock( j, 0 ) );
       
   334 				}
       
   335 			}
       
   336 
       
   337 		// Now zero-fill the block we just erased and move to next block
       
   338 		test( KErrNone == ZeroFillBlock( eraseBlock ) );
       
   339 		test( ValidateBlock( eraseBlock, 0 ) );
       
   340 		}
       
   341 
       
   342 	}
       
   343 
       
   344 
       
   345 TInt E32Main()
       
   346 	{
       
   347 	test.Title();
       
   348 	test.Start(_L("Testing media erase operations"));
       
   349 
       
   350 	CEraseTest eraseTest;
       
   351 	TRAPD( ret, eraseTest.CreateL() );
       
   352 	if( KErrNone == ret )
       
   353 		{
       
   354 		eraseTest.DoTest();
       
   355 		}
       
   356 
       
   357 	test.End();
       
   358 	return KErrNone;
       
   359 	}