kerneltest/f32test/shostmassstorage/msman/test/cblockdevicetester.cpp
changeset 0 a41df078684a
child 297 b2826f67641f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/shostmassstorage/msman/test/cblockdevicetester.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,679 @@
+// Copyright (c) 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:
+//
+
+
+#include <e32def.h>
+#include <e32cmn.h>
+#include <f32file.h>
+#include <e32test.h>
+#include <e32math.h>
+
+#include "tmslog.h"
+#include "cblockdevicetester.h"
+
+extern RTest test;
+extern RFs fsSession;
+
+
+const TInt KTestCaseDataOffset = 9;
+_LIT8(KTxtTestCaseOutPreamble,  "5555AAAA");
+_LIT8(KTxtTestCaseInPreamble,   "AAAA5555");
+_LIT8(KTxtTestCase,         "T");
+_LIT8(KTxtTestEnable,       "E");
+_LIT8(KTxtTestSenseError,   "S");
+_LIT8(KTxtTestConfig,       "C");
+
+
+void TLocalBuffer::Init()
+    {
+    __MSFNSLOG
+    TInt64 rndSeed = 123456789;
+
+    //-- initialize buffer with random rubbish
+    iBuffer.SetMax();
+    for (TInt i = 0; i < KSize; ++i)
+        {
+        iBuffer[i] = static_cast<TUint8>(Math::Rand(rndSeed));
+        }
+
+    test.Printf(_L("Test area size is %x blocks\n"), KSizeInBlocks);
+    }
+
+
+void TLocalBuffer::Update(TInt aPos, TUint aLen)
+    {
+    // complement data
+    for (TInt i = 0; i < aLen; i++, aPos++)
+        {
+        iBuffer[aPos] = ~iBuffer[aPos];
+        }
+    }
+
+
+RTargetMedia::RTargetMedia(TInt aDriveNumber)
+:   iDriveNumber(aDriveNumber)
+    {
+    __MSFNSLOG
+    }
+
+
+void RTargetMedia::OpenL()
+    {
+    __MSFNSLOG
+    User::LeaveIfError(iRawDisk.Open(fsSession, iDriveNumber));
+    }
+
+
+void RTargetMedia::Close()
+    {
+    __MSFNSLOG
+    iRawDisk.Close();
+    }
+
+
+TInt RTargetMedia::MediaRawWrite(TPos aPos, const TDesC8& aData)
+    {
+    __MSFNSLOG
+    return iRawDisk.Write(aPos, (TDesC8&)aData);
+    }
+
+
+TInt RTargetMedia::MediaRawRead(TPos aPos, TUint32 aLen, TDes8& aData)
+    {
+    __MSFNSLOG
+    aData.SetMax();
+    TPtr8 ptr = aData.LeftTPtr(aLen);
+    TInt err = iRawDisk.Read(aPos, ptr);
+    aData.SetLength(aLen);
+    return err;
+    }
+
+
+RTargetDrive::RTargetDrive(TInt aDriveNumber)
+:   RTargetMedia(aDriveNumber)
+    {
+    }
+
+TInt RTargetDrive::OpenTestAreaL(const TDesC8& aData)
+    {
+    __MSFNSLOG
+    RTargetMedia::OpenL();
+    iStartLba = 0x20;
+
+    iSource.Set(aData);
+    test.Printf(_L("Test area located @ LBA=%x\n"), iStartLba);
+
+    return MediaRawWrite(StartPos(), iSource);
+    }
+
+
+TInt RTargetDrive::Update(TInt aPos, TUint aLen)
+    {
+    __MSFNSLOG
+    TPtrC8 ptr = iSource.Mid(aPos, aLen);
+    TPos targetPos = TargetPos(aPos);
+    return MediaRawWrite(targetPos, ptr);
+    }
+
+
+TInt RTargetDrive::Verify()
+    {
+    __MSFNLOG
+    TInt res = MediaRawRead(StartPos(), iSource.Length(), iTmpBuffer);
+    if (res)
+        return res;
+
+    res = iTmpBuffer.Compare(iSource);
+    return res == 0 ? KErrNone : KErrCorrupt;
+    }
+
+TInt RTargetDrive::Verify(TInt aPos, TUint aLen)
+    {
+    __MSFNSLOG
+    TPos pos = TargetPos(aPos);
+    TInt res = MediaRawRead(pos, aLen, iTmpBuffer);
+    if (res)
+        return res;
+
+    iTmpBuffer.SetLength(aLen);
+    TPtrC8 ptr = iSource.Mid(aPos, aLen);
+
+    res = iTmpBuffer.Compare(ptr);
+    return res == 0 ? KErrNone : KErrCorrupt;
+    }
+
+
+TInt RTargetDrive::VerifyBlock(TLba aLba, TLba aBlocks)
+    {
+    __MSFNSLOG
+    return Verify(TLbaUtils::Pos(aLba), TLbaUtils::Length(aBlocks));
+    }
+
+
+_LIT(KTxtControlFile, "ControlFile.txt");
+static const TChar KFillChar = 'x';
+
+TTargetTestArea::TTargetTestArea(RTargetMedia& aMedia)
+:   iTargetMedia(aMedia)
+    {
+    __MSFNLOG
+    }
+
+void TTargetTestArea::CreateControlFile()
+    {
+    __MSFNLOG
+    iStartLba = -1;
+    static const TInt KBlockSize = 0x200;
+    static const TInt KFileSize = KBlockSize * 8;
+
+    RFile file;
+
+    TBuf8<KFileSize> testData;
+    testData.Fill(KFillChar, KFileSize);
+
+    // write control file
+    TInt err = file.Replace(fsSession, KTxtControlFile, EFileStream);
+    test(err == KErrNone);
+
+    err = file.Write(testData);
+    test(err == KErrNone);
+
+    file.Close();
+    }
+
+
+void TTargetTestArea::RemoveControlFile()
+    {
+    __MSFNLOG
+    TInt err = fsSession.Delete(KTxtControlFile);
+    test(err == KErrNone);
+    }
+
+
+void TTargetTestArea::FindBlockStartL()
+    {
+    __MSFNLOG
+    iTargetMedia.OpenL();
+    // search for first block
+    TBuf8<KBlockSize> readBlock;
+    TBuf8<KBlockSize> refBlock;
+    refBlock.Fill(KFillChar, KBlockSize);
+
+    TInt err = KErrNone;
+    TInt lba;
+    for (lba = 0; ;lba++)
+        {
+        err = iTargetMedia.MediaRawRead(lba*KBlockSize, KBlockSize, readBlock);
+
+        if (err != KErrNone)
+            {
+            lba = -1;
+            break;
+            }
+
+        if (readBlock == refBlock)
+            {
+            break;
+            }
+        }
+
+    iStartLba = lba;
+    iTargetMedia.Close();
+    test.Printf(_L("Block found at 0x%x"), lba);
+    }
+
+
+TInt TTargetTestArea::WriteBlockL(TBuf8<KBlockSize>& aBlock)
+    {
+    __MSFNLOG
+    iTargetMedia.OpenL();
+    TInt err = iTargetMedia.MediaRawWrite(iStartLba * KBlockSize, aBlock);
+    iTargetMedia.Close();
+    return err;
+    }
+
+
+TInt TTargetTestArea::ReadBlockL(TBuf8<KBlockSize>& aBlock)
+    {
+    __MSFNLOG
+    iTargetMedia.OpenL();
+    TInt err = iTargetMedia.MediaRawRead(iStartLba * KBlockSize, KBlockSize, aBlock);
+    iTargetMedia.Close();
+    return err;
+    }
+
+
+RBlockTargetMedia::RBlockTargetMedia(TInt aDriveNumber)
+:   RTargetMedia(aDriveNumber)
+    {
+    __MSFNSLOG
+    }
+
+
+void RBlockTargetMedia::OpenL()
+    {
+    __MSFNSLOG
+    RTargetMedia::OpenL();
+
+    TInt64 rndSeed = 123456789;
+
+    //-- initialize buffer with random rubbish
+    iBlockData.SetMax();
+    for (TInt i = 0; i < iBlockData.Length(); ++i)
+        {
+        iBlockData[i] = static_cast<TUint8>(Math::Rand(rndSeed));
+        }
+    }
+
+
+TInt RBlockTargetMedia::WriteBlock(TLba aLba)
+    {
+    __MSFNSLOG
+    TPos pos = TLbaUtils::Pos(aLba);
+    return iRawDisk.Write(pos, (TDesC8&)iBlockData);
+    }
+
+
+TInt RBlockTargetMedia::ReadBlock(TLba aLba)
+    {
+    __MSFNSLOG
+    TBuf8<KBlockSize> blockData;
+    TPos pos = TLbaUtils::Pos(aLba);
+    blockData.SetMax();
+    TInt err = iRawDisk.Read(pos, blockData);
+    return err;
+    }
+
+
+CBlockDeviceTester* CBlockDeviceTester::NewL(TInt aDriveNumber)
+    {
+    __MSFNSLOG
+	CBlockDeviceTester* r = new (ELeave) CBlockDeviceTester(aDriveNumber);
+	CleanupStack::PushL(r);
+
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+    }
+
+
+void CBlockDeviceTester::ConstructL()
+    {
+    __MSFNLOG
+    TVolumeInfo volumeInfo;
+
+    User::LeaveIfError(fsSession.Volume(volumeInfo, iDriveNumber));
+    test.Printf(_L("Drive=%d Size = %lx\n"), iDriveNumber, volumeInfo.iSize);
+    iDriveSizeInBlocks = volumeInfo.iSize / KBlockSize;
+    iLocalBuffer.Init();
+    iTargetDrive.OpenTestAreaL(iLocalBuffer.Buffer());
+    }
+
+
+CBlockDeviceTester::CBlockDeviceTester(TInt aDriveNumber)
+:   iDriveNumber(aDriveNumber),
+    iTargetDrive(aDriveNumber)
+    {
+    __MSFNLOG
+    }
+
+
+CBlockDeviceTester::~CBlockDeviceTester()
+    {
+    __MSFNLOG
+    iTargetDrive.Close();
+    }
+
+
+void CBlockDeviceTester::OpenDriveL()
+    {
+    iTargetDrive.OpenL();
+    }
+
+void CBlockDeviceTester::CloseDrive()
+    {
+    iTargetDrive.Close();
+    }
+
+
+
+TInt CBlockDeviceTester::VerifyDrive()
+    {
+    __MSFNLOG
+    return iTargetDrive.Verify();
+    }
+
+
+TInt CBlockDeviceTester::Update(TPos aPos, TUint aLen)
+    {
+    __MSFNLOG
+    iLocalBuffer.Update(aPos, aLen);
+    return iTargetDrive.Update(aPos, aLen);
+    }
+
+
+TInt CBlockDeviceTester::UpdateBlock(TLba aLba, TLba aBlocks)
+    {
+    __MSFNLOG
+    return Update(TLbaUtils::Pos(aLba), TLbaUtils::Length(aBlocks));
+    }
+
+
+TInt CBlockDeviceTester::Verify(TPos aPos, TUint aLen)
+    {
+    __MSFNLOG
+    return iTargetDrive.Verify(aPos, aLen);
+    }
+
+TInt CBlockDeviceTester::VerifyBlock(TLba aLba, TLba aBlocks)
+    {
+    __MSFNLOG
+    return iTargetDrive.VerifyBlock(aLba, aBlocks);
+    }
+
+/**
+ * CBotTester
+ */
+CBotTester* CBotTester::NewL(TInt aDriveNumber)
+    {
+    __MSFNSLOG
+	CBotTester* r = new (ELeave) CBotTester(aDriveNumber);
+	CleanupStack::PushL(r);
+
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+    }
+
+
+void CBotTester::ConstructL()
+    {
+    __MSFNLOG
+
+    CBlockDeviceTester::ConstructL();
+
+    iCmdBuffer.Append(KTxtTestCaseOutPreamble);
+    iCmdBuffer.Append(KTxtTestCase);
+    iCmdBuffer.AppendFill('t', iCmdBuffer.MaxLength() - iCmdBuffer.Length());
+
+    iOutEnableBuffer.Append(KTxtTestCaseOutPreamble);
+    iOutEnableBuffer.Append(KTxtTestEnable);
+    iOutEnableBuffer.AppendFill('o', iOutEnableBuffer.MaxLength() - iOutEnableBuffer.Length());
+
+    iInEnableBuffer.Append(KTxtTestCaseInPreamble);
+    iInEnableBuffer.Append(KTxtTestEnable);
+    iInEnableBuffer.AppendFill('i', iInEnableBuffer.MaxLength() - iInEnableBuffer.Length());
+    }
+
+
+CBotTester::CBotTester(TInt aDriveNumber)
+:   CBlockDeviceTester(aDriveNumber)
+    {
+    __MSFNLOG
+    }
+
+
+CBotTester::~CBotTester()
+    {
+    __MSFNLOG
+    iTargetDrive.Close();
+    }
+
+
+TInt CBotTester::SetTest(TTestCase aTestCase)
+    {
+    __MSFNLOG
+    iCmdBuffer[KTestCaseDataOffset] = static_cast<TUint8>(aTestCase);
+
+    TPos pos = KSetTestPos;
+    return iTargetDrive.MediaRawWrite(pos, iCmdBuffer);
+    }
+
+
+TInt CBotTester::WriteEnableFile()
+    {
+    __MSFNLOG
+    TPos pos = KWriteEnableFilePos;
+    return iTargetDrive.MediaRawWrite(pos, iOutEnableBuffer);
+    }
+
+
+TInt CBotTester::InitReadEnableFile()
+    {
+    __MSFNLOG
+    TPos pos = KReadEnableFilePos;
+    return iTargetDrive.MediaRawWrite(pos, iInEnableBuffer);
+    }
+
+
+TInt CBotTester::ReadEnableFile()
+    {
+    __MSFNLOG
+    TBuf8<KInEnableBufferSize> readBuf(KInEnableBufferSize);
+    TPos pos = KReadEnableFilePos;
+    return iTargetDrive.MediaRawRead(pos, readBuf.Size(), readBuf);
+    }
+
+
+/**
+ * CSbcErrTester
+ */
+CSbcErrTester* CSbcErrTester::NewL(TInt aDriveNumber)
+    {
+    __MSFNSLOG
+	CSbcErrTester* r = new (ELeave) CSbcErrTester(aDriveNumber);
+	CleanupStack::PushL(r);
+
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+    }
+
+
+void CSbcErrTester::ConstructL()
+    {
+    __MSFNLOG
+
+    CBlockDeviceTester::ConstructL();
+
+    iCmdBuffer.Append(KTxtTestCaseOutPreamble);
+    iCmdBuffer.Append(KTxtTestCase);
+    iCmdBuffer.AppendFill('t', iCmdBuffer.MaxLength() - iCmdBuffer.Length());
+
+    iEnableBuffer.Append(KTxtTestCaseOutPreamble);
+    iEnableBuffer.Append(KTxtTestEnable);
+    iEnableBuffer.AppendFill('e', iEnableBuffer.MaxLength() - iEnableBuffer.Length());
+
+    iSenseErrorBuffer.Append(KTxtTestCaseOutPreamble);
+    iSenseErrorBuffer.Append(KTxtTestSenseError);
+    iSenseErrorBuffer.AppendFill('s', iSenseErrorBuffer.MaxLength() - iSenseErrorBuffer.Length());
+    }
+
+
+CSbcErrTester::CSbcErrTester(TInt aDriveNumber)
+:   CBlockDeviceTester(aDriveNumber)
+    {
+    __MSFNLOG
+    }
+
+
+CSbcErrTester::~CSbcErrTester()
+    {
+    __MSFNLOG
+    iTargetDrive.Close();
+    }
+
+
+TInt CSbcErrTester::WriteTestFile()
+    {
+    __MSFNLOG
+    TPos pos = KWriteTestFilePos;
+    return iTargetDrive.MediaRawWrite(pos, iEnableBuffer);
+    }
+
+
+TInt CSbcErrTester::ReadTestFile()
+    {
+    __MSFNLOG
+    TBuf8<KEnableBufferSize> readBuf(KEnableBufferSize);
+    TPos pos = KReadTestFilePos;
+    TInt err = iTargetDrive.MediaRawRead(pos, readBuf.Size(), readBuf);
+    return err;
+    }
+
+
+TInt CSbcErrTester::WriteSenseErrorFile(TTestSenseError aTestSenseError)
+    {
+    __MSFNLOG
+    iSenseErrorBuffer[KTestCaseDataOffset] = static_cast<TUint8>(aTestSenseError);
+    TPos pos = KSenseErrorFile;
+    return iTargetDrive.MediaRawWrite(pos, iSenseErrorBuffer);
+    }
+
+
+CWrPrTester* CWrPrTester::NewL(TInt aDriveNumber)
+    {
+    __MSFNSLOG
+	CWrPrTester* r = new (ELeave) CWrPrTester(aDriveNumber);
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+    }
+
+
+void CWrPrTester::ConstructL()
+    {
+    __MSFNLOG
+    iCmdBuffer.Append(KTxtTestCaseOutPreamble);
+    iCmdBuffer.Append(KTxtTestConfig);
+    iCmdBuffer.AppendFill('c', iCmdBuffer.MaxLength() - iCmdBuffer.Length());
+
+    iInCmdBuffer.Append(KTxtTestCaseInPreamble);
+    iInCmdBuffer.Append(KTxtTestConfig);
+    iInCmdBuffer.AppendFill('c', iInCmdBuffer.MaxLength() - iInCmdBuffer.Length());
+
+    iTargetTestArea.CreateControlFile();
+    iTargetTestArea.FindBlockStartL();
+    }
+
+
+CWrPrTester::CWrPrTester(TInt aDriveNumber)
+:   iTargetMedia(aDriveNumber),
+    iTargetTestArea(iTargetMedia)
+    {
+    __MSFNLOG
+    }
+
+
+CWrPrTester::~CWrPrTester()
+    {
+    __MSFNLOG
+    iTargetTestArea.RemoveControlFile();
+    }
+
+
+void CWrPrTester::SetWriteProtectL()
+    {
+    __MSFNLOG
+    // first write WrPr CLR Control block to media to enable setting to be
+    // cleared
+    iInCmdBuffer[KTestCaseDataOffset] = ETestConfigMediaWpClr;
+    TInt err = iTargetTestArea.WriteBlockL(iInCmdBuffer);
+    User::LeaveIfError(err);
+
+    // Now write WrPr Set Control block to test client
+    iCmdBuffer[KTestCaseDataOffset] = ETestConfigMediaWpSet;
+    iTargetMedia.OpenL();
+    err = iTargetMedia.MediaRawWrite(KCmdPos, iCmdBuffer);
+    User::LeaveIfError(err);
+    iTargetMedia.Close();
+    }
+
+
+void CWrPrTester::ClrWriteProtectL()
+    {
+    __MSFNLOG
+    test.Printf(_L("Clearing WRITE PROTECT"));
+    TInt err = KErrNone;
+    // Write protect so read the control file from the drive
+    TBuf8<KCmdBufferSize> buffer;
+    buffer.SetLength(KCmdBufferSize);
+    iTargetTestArea.ReadBlockL(buffer);
+
+    if (buffer != iInCmdBuffer)
+        {
+        err = KErrCorrupt;
+        }
+    User::LeaveIfError(err);
+    }
+
+
+TInt CWrPrTester::SetRemovableL()
+    {
+    __MSFNLOG
+    iCmdBuffer[KTestCaseDataOffset] = ETestConfigMediaRmbSet;
+    iTargetMedia.OpenL();
+    TInt err = iTargetMedia.MediaRawWrite(KCmdPos, iCmdBuffer);
+    iTargetMedia.Close();
+    return err;
+    }
+
+TInt CWrPrTester::ClrRemovableL()
+    {
+    __MSFNLOG
+    iCmdBuffer[KTestCaseDataOffset] = ETestConfigMediaRmbClr;
+    iTargetMedia.OpenL();
+    TInt err = iTargetMedia.MediaRawWrite(KCmdPos, iCmdBuffer);
+    iTargetMedia.Close();
+    return err;
+    }
+
+
+TInt CWrPrTester::WriteReadTestL()
+    {
+    __MSFNLOG
+    TInt err = KErrNone;
+    TBuf8<KCmdBufferSize> wrBuffer;
+
+    wrBuffer.SetMax();
+    for (TInt i = 0; i < KCmdBufferSize; i++)
+        {
+        wrBuffer[i] = i;
+        }
+
+    err = iTargetTestArea.WriteBlockL(wrBuffer);
+    if (err == KErrNone)
+        {
+        TBuf8<KCmdBufferSize> rdBuffer;
+        rdBuffer.SetMax();
+        err = iTargetTestArea.ReadBlockL(rdBuffer);
+        User::LeaveIfError(err);
+
+        if (wrBuffer != rdBuffer)
+            {
+            err = KErrCorrupt;
+            }
+        }
+
+    if (err)
+        {
+        test.Printf(_L("WriteRead test returned %d\n"), err);
+        }
+    return err;
+    }
+
+
+