diff -r 000000000000 -r 96e5fb8b040d kerneltest/e32test/lffs/tf_erase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/lffs/tf_erase.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,359 @@ +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Tests erasing of Flash. Does not test suspending (see TF_SUSPEND) +// +// + +#include +#include +#include +#include +#include "randgen.h" +#include "user_config.h" + +RTest test( _L("TF_ERASE") ); + + +class CEraseTest : public CBase + { + public: + ~CEraseTest(); + + void CreateL(); + + void DoTest(); + + private: + void DoSimpleTest(); + void DoSimpleTest2(); + void DoPseudoRandomTest(); + void DoRangeTest(); + + TInt EraseOneBlock( TInt aBlockNumber ); + TInt ZeroFillBlock( TInt aBlockNumber ); + TBool ValidateBlock( TInt aBlockNumber, TUint32 aFillWord ); + + + private: + TBusLocalDrive iDrive; + TBool iDriveOpened; + + TInt iFlashSize; + TInt iBlockSize; + TInt iBlockCount; + + TBuf8<512> iReadBuffer; + + }; + + +CEraseTest::~CEraseTest() + { + if( iDriveOpened ) + { + iDrive.Disconnect(); + } + } + + + +void CEraseTest::CreateL() + { + // + // Load the device drivers + // +#ifndef SKIP_PDD_LOAD + test.Printf( _L("Loading %S\n"), &KLfsDriverName ); + r = User::LoadPhysicalDevice( KLfsDriverName ); + test( KErrNone == r || KErrAlreadyExists == r ); +#endif + +#ifdef UNMOUNT_DRIVE + RFs fs; + test( KErrNone == fs.Connect() ); +#if 0 + // XXX - not eka2 + test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) ); +#endif + TFullName name; + fs.FileSystemName( name, KLffsLogicalDriveNumber ); + if( name.Length() > 0 ) + { + test.Printf( _L("Unmounting drive") ); + test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) ); + User::After( 2000000 ); + test.Printf( _L("Drive unmounted") ); + } + fs.Close(); +#endif + + // + // Open a TBusLogicalDevice to drive + // + test.Printf( _L("Opening media channel\n") ); + static TBool changedFlag = EFalse; + User::LeaveIfError( iDrive.Connect( KDriveNumber, changedFlag ) ); + iDriveOpened = ETrue; + + // + // Get size of Flash drive, block size, block count + // + TLocalDriveCapsV2Buf info; + iDrive.Caps(info); + iFlashSize = I64LOW(info().iSize); + iBlockSize = info().iEraseBlockSize; + iBlockCount = iFlashSize / iBlockSize; + + test.Printf( _L("Flash size is 0x%x bytes\n"), iFlashSize ); + test.Printf( _L("Block size is 0x%x bytes\n"), iBlockSize ); + test.Printf( _L("Block count is %d\n"), iBlockCount ); + + test.Printf( _L("CreateL complete\n") ); + } + + +void CEraseTest::DoTest() + // + // Main test dispatcher + // + { + test.Next( _L("Starting tests...") ); + DoSimpleTest(); + DoSimpleTest2(); + DoPseudoRandomTest(); + DoRangeTest(); + } + + +TInt CEraseTest::EraseOneBlock( TInt aBlockNumber ) + // + // Erases block aBlockNumber on Flash + // + { + TInt blockBaseOffset = aBlockNumber * iBlockSize; + + test.Printf( _L("Erasing block %d (offs=0x%x)\n"), aBlockNumber, blockBaseOffset ); + + TInt r = iDrive.Format( blockBaseOffset, iBlockSize ); + + test.Printf( _L("... Format returned %d\n"), r ); + return r; + } + + +TBool CEraseTest::ValidateBlock( TInt aBlockNumber, TUint32 aFillWord ) + // + // Checks that every word in block aBlockNumber has the value aFillWord + // + { + TUint offset = aBlockNumber * iBlockSize; + test.Printf( _L("Validating block %d (offs=0x%x)\n"), aBlockNumber, offset ); + + TBool failed = EFalse; + const TInt readBufLen = iReadBuffer.MaxLength(); + + for( TInt len = iBlockSize; len > 0 && !failed ;) + { + TInt r = iDrive.Read( offset, readBufLen, iReadBuffer ); + if( r != KErrNone ) + { + test.Printf( _L("... FAIL: read failed (%d) at offset 0x%x\n"), r, offset ); + test( KErrNone == r ); + } + test( iReadBuffer.Length() == readBufLen ); + + TUint32* p = (TUint32*)iReadBuffer.Ptr(); + for( TInt i = 0; i < readBufLen; i += 4 ) + { + if( aFillWord != *p ) + { + failed = ETrue; + test.Printf( _L("... FAILED: word @ offs=0x%x, read=0x%x, expected=0x%x\n"), + offset+i, p[0], aFillWord ); + break; + } + ++p; + } + offset += readBufLen; + len -= readBufLen; + } + + return !failed; + } + + +TInt CEraseTest::ZeroFillBlock( TInt aBlockNumber ) + // + // Zero-fills an entire block + // The requires that writing works (so as a side-effect performs a + // very basic test of writing) + // + { + test.Printf( _L("Zero-filling block %d\n"), aBlockNumber ); + + // + // Create a buffer full of zeros + // + const TInt KZeroBufSize = 512; + + TBuf8 buf; + buf.FillZ( buf.MaxLength() ); + + // + // Write the data out to the Flash + // + TInt writeCount = iBlockSize / KZeroBufSize; + TInt r = KErrNone; + TInt blockBaseOffset = aBlockNumber * iBlockSize; + for( ; (writeCount > 0) && (KErrNone == r); writeCount-- ) + { + r = iDrive.Write( blockBaseOffset, buf ); + if( r != KErrNone ) + { + test.Printf( _L("... FAIL: write failed (%d) at offset 0x%x\n"), r, blockBaseOffset ); + } + blockBaseOffset += KZeroBufSize; + } + + return r; + } + + +void CEraseTest::DoSimpleTest() + // + // Simple erase test. This just zero-fills and then erases each block in turn + // + { + test.Next( _L("Simple test: erases each block in turn\n") ); + + for( TInt block = 0; block < iBlockCount; block++ ) + { + test( KErrNone == ZeroFillBlock( block ) ); + test( ValidateBlock( block, 0 ) ); + test( KErrNone == EraseOneBlock( block ) ); + test( ValidateBlock( block, 0xFFFFFFFF ) ); + } + } + +void CEraseTest::DoSimpleTest2() + // + // Another simple erase test. + // This time we zero-fill all blocks first, then erase them all + // + { + test.Next( _L("Simple test2 : zero-fills whole Flash, then erases all blocks\n") ); + + for( TInt block = 0; block < iBlockCount; block++ ) + { + test( KErrNone == ZeroFillBlock( block ) ); + test( ValidateBlock( block, 0 ) ); + } + + for( TInt block = 0; block < iBlockCount; block++ ) + { + test( KErrNone == EraseOneBlock( block ) ); + test( ValidateBlock( block, 0xFFFFFFFF ) ); + } + } + + + +void CEraseTest::DoPseudoRandomTest() + // + // Erases the blocks in pseudo-random order, zero-filling first + // + { + test.Next( _L("Test random erase order\n") ); + + TRandomGenerator random; +#if 0 + random.SetSeed( TInt64(0x1020466E, 0x3F9C0C00) ); +#else + random.SetSeed( 0x1020466E ); +#endif + + for( TInt count = 0; count < 50; count++ ) + { + TUint block = random.Next() % iBlockCount; + test( KErrNone == ZeroFillBlock( block ) ); + + test( ValidateBlock( block, 0 ) ); + + test( KErrNone == EraseOneBlock( block ) ); + + test( ValidateBlock( block, 0xFFFFFFFF ) ); + } + } + +void CEraseTest::DoRangeTest() + // + // Simple erase test. This just zero-fills and then erases each block in turn + // + { + test.Next( _L("Range test: check that erase only affects erased block\n") ); + + // + // Pre-fill all blocks with zero + // + test.Printf( _L("Pre-zeroing blocks\n") ); + for( TInt block = 0; block < iBlockCount; block++ ) + { + test( KErrNone == ZeroFillBlock( block ) ); + test( ValidateBlock( block, 0 ) ); + } + + // + // The test is to erase a block. Check it is erased and all + // other blocks are still zeros. Then we re-zero the block just + // erased and repeat test with next block + // + test.Printf( _L("Now testing erase...\n") ); + for( TInt eraseBlock = 0; eraseBlock < iBlockCount; eraseBlock++ ) + { + test( KErrNone == EraseOneBlock( eraseBlock ) ); + test( ValidateBlock( eraseBlock, 0xFFFFFFFF ) ); + + // check all other blocks are still zero + for( TInt j = 0; j < iBlockCount; j++ ) + { + if( j != eraseBlock ) + { + // test if not the one we just erased + test( ValidateBlock( j, 0 ) ); + } + } + + // Now zero-fill the block we just erased and move to next block + test( KErrNone == ZeroFillBlock( eraseBlock ) ); + test( ValidateBlock( eraseBlock, 0 ) ); + } + + } + + +TInt E32Main() + { + test.Title(); + test.Start(_L("Testing media erase operations")); + + CEraseTest eraseTest; + TRAPD( ret, eraseTest.CreateL() ); + if( KErrNone == ret ) + { + eraseTest.DoTest(); + } + + test.End(); + return KErrNone; + }