First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Tests erasing of Flash. Does not test suspending (see TF_SUSPEND)
19 #include <e32std_private.h>
23 #include "user_config.h"
25 RTest test( _L("TF_ERASE") );
28 class CEraseTest : public CBase
40 void DoPseudoRandomTest();
43 TInt EraseOneBlock( TInt aBlockNumber );
44 TInt ZeroFillBlock( TInt aBlockNumber );
45 TBool ValidateBlock( TInt aBlockNumber, TUint32 aFillWord );
49 TBusLocalDrive iDrive;
56 TBuf8<512> iReadBuffer;
61 CEraseTest::~CEraseTest()
71 void CEraseTest::CreateL()
74 // Load the device drivers
77 test.Printf( _L("Loading %S\n"), &KLfsDriverName );
78 r = User::LoadPhysicalDevice( KLfsDriverName );
79 test( KErrNone == r || KErrAlreadyExists == r );
84 test( KErrNone == fs.Connect() );
87 test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) );
90 fs.FileSystemName( name, KLffsLogicalDriveNumber );
91 if( name.Length() > 0 )
93 test.Printf( _L("Unmounting drive") );
94 test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) );
95 User::After( 2000000 );
96 test.Printf( _L("Drive unmounted") );
102 // Open a TBusLogicalDevice to drive
104 test.Printf( _L("Opening media channel\n") );
105 static TBool changedFlag = EFalse;
106 User::LeaveIfError( iDrive.Connect( KDriveNumber, changedFlag ) );
107 iDriveOpened = ETrue;
110 // Get size of Flash drive, block size, block count
112 TLocalDriveCapsV2Buf info;
114 iFlashSize = I64LOW(info().iSize);
115 iBlockSize = info().iEraseBlockSize;
116 iBlockCount = iFlashSize / iBlockSize;
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 );
122 test.Printf( _L("CreateL complete\n") );
126 void CEraseTest::DoTest()
128 // Main test dispatcher
131 test.Next( _L("Starting tests...") );
134 DoPseudoRandomTest();
139 TInt CEraseTest::EraseOneBlock( TInt aBlockNumber )
141 // Erases block aBlockNumber on Flash
144 TInt blockBaseOffset = aBlockNumber * iBlockSize;
146 test.Printf( _L("Erasing block %d (offs=0x%x)\n"), aBlockNumber, blockBaseOffset );
148 TInt r = iDrive.Format( blockBaseOffset, iBlockSize );
150 test.Printf( _L("... Format returned %d\n"), r );
155 TBool CEraseTest::ValidateBlock( TInt aBlockNumber, TUint32 aFillWord )
157 // Checks that every word in block aBlockNumber has the value aFillWord
160 TUint offset = aBlockNumber * iBlockSize;
161 test.Printf( _L("Validating block %d (offs=0x%x)\n"), aBlockNumber, offset );
163 TBool failed = EFalse;
164 const TInt readBufLen = iReadBuffer.MaxLength();
166 for( TInt len = iBlockSize; len > 0 && !failed ;)
168 TInt r = iDrive.Read( offset, readBufLen, iReadBuffer );
171 test.Printf( _L("... FAIL: read failed (%d) at offset 0x%x\n"), r, offset );
172 test( KErrNone == r );
174 test( iReadBuffer.Length() == readBufLen );
176 TUint32* p = (TUint32*)iReadBuffer.Ptr();
177 for( TInt i = 0; i < readBufLen; i += 4 )
179 if( aFillWord != *p )
182 test.Printf( _L("... FAILED: word @ offs=0x%x, read=0x%x, expected=0x%x\n"),
183 offset+i, p[0], aFillWord );
188 offset += readBufLen;
196 TInt CEraseTest::ZeroFillBlock( TInt aBlockNumber )
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)
203 test.Printf( _L("Zero-filling block %d\n"), aBlockNumber );
206 // Create a buffer full of zeros
208 const TInt KZeroBufSize = 512;
210 TBuf8<KZeroBufSize> buf;
211 buf.FillZ( buf.MaxLength() );
214 // Write the data out to the Flash
216 TInt writeCount = iBlockSize / KZeroBufSize;
218 TInt blockBaseOffset = aBlockNumber * iBlockSize;
219 for( ; (writeCount > 0) && (KErrNone == r); writeCount-- )
221 r = iDrive.Write( blockBaseOffset, buf );
224 test.Printf( _L("... FAIL: write failed (%d) at offset 0x%x\n"), r, blockBaseOffset );
226 blockBaseOffset += KZeroBufSize;
233 void CEraseTest::DoSimpleTest()
235 // Simple erase test. This just zero-fills and then erases each block in turn
238 test.Next( _L("Simple test: erases each block in turn\n") );
240 for( TInt block = 0; block < iBlockCount; block++ )
242 test( KErrNone == ZeroFillBlock( block ) );
243 test( ValidateBlock( block, 0 ) );
244 test( KErrNone == EraseOneBlock( block ) );
245 test( ValidateBlock( block, 0xFFFFFFFF ) );
249 void CEraseTest::DoSimpleTest2()
251 // Another simple erase test.
252 // This time we zero-fill all blocks first, then erase them all
255 test.Next( _L("Simple test2 : zero-fills whole Flash, then erases all blocks\n") );
257 for( TInt block = 0; block < iBlockCount; block++ )
259 test( KErrNone == ZeroFillBlock( block ) );
260 test( ValidateBlock( block, 0 ) );
263 for( TInt block = 0; block < iBlockCount; block++ )
265 test( KErrNone == EraseOneBlock( block ) );
266 test( ValidateBlock( block, 0xFFFFFFFF ) );
272 void CEraseTest::DoPseudoRandomTest()
274 // Erases the blocks in pseudo-random order, zero-filling first
277 test.Next( _L("Test random erase order\n") );
279 TRandomGenerator random;
281 random.SetSeed( TInt64(0x1020466E, 0x3F9C0C00) );
283 random.SetSeed( 0x1020466E );
286 for( TInt count = 0; count < 50; count++ )
288 TUint block = random.Next() % iBlockCount;
289 test( KErrNone == ZeroFillBlock( block ) );
291 test( ValidateBlock( block, 0 ) );
293 test( KErrNone == EraseOneBlock( block ) );
295 test( ValidateBlock( block, 0xFFFFFFFF ) );
299 void CEraseTest::DoRangeTest()
301 // Simple erase test. This just zero-fills and then erases each block in turn
304 test.Next( _L("Range test: check that erase only affects erased block\n") );
307 // Pre-fill all blocks with zero
309 test.Printf( _L("Pre-zeroing blocks\n") );
310 for( TInt block = 0; block < iBlockCount; block++ )
312 test( KErrNone == ZeroFillBlock( block ) );
313 test( ValidateBlock( block, 0 ) );
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
321 test.Printf( _L("Now testing erase...\n") );
322 for( TInt eraseBlock = 0; eraseBlock < iBlockCount; eraseBlock++ )
324 test( KErrNone == EraseOneBlock( eraseBlock ) );
325 test( ValidateBlock( eraseBlock, 0xFFFFFFFF ) );
327 // check all other blocks are still zero
328 for( TInt j = 0; j < iBlockCount; j++ )
330 if( j != eraseBlock )
332 // test if not the one we just erased
333 test( ValidateBlock( j, 0 ) );
337 // Now zero-fill the block we just erased and move to next block
338 test( KErrNone == ZeroFillBlock( eraseBlock ) );
339 test( ValidateBlock( eraseBlock, 0 ) );
348 test.Start(_L("Testing media erase operations"));
350 CEraseTest eraseTest;
351 TRAPD( ret, eraseTest.CreateL() );
352 if( KErrNone == ret )