kerneltest/e32test/pccd/t_pccdsr.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pccd/t_pccdsr.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,319 @@
+// Copyright (c) 1998-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:
+// e32test\pccd\t_pccdsr.cpp
+// Stress test a single sector of Compact Flash card (ATA).
+// 
+//
+
+
+//#define USE_F32_ACCESS
+#include <e32test.h>
+#include <e32svr.h>
+#include <e32hal.h>
+#include <e32uid.h>
+#if defined (USE_F32_ACCESS)
+#include <f32fsys.h>
+#include <f32file.h>
+#endif
+
+#define ATA_PDD_NAME _L("MEDATA")
+
+const TInt KAtaSectorSize=512;
+const TInt KMaxSectors=8;
+const TInt KMaxRdWrBufLen=(KAtaSectorSize*KMaxSectors); // 4K
+const TInt KHeapSize=0x4000;
+const TInt KMaxErr=8;
+
+#if defined (USE_F32_ACCESS)
+GLDEF_D	RFs TheFs;
+#else
+LOCAL_D	TBusLocalDrive TheDrive;
+LOCAL_D TBool ChangedFlag;
+#endif
+RTest test(_L("Local Drive Stress test"));
+LOCAL_D TBuf8<KMaxRdWrBufLen> wrBufPat1,wrBufPat2,rdBuf;
+
+enum TOper {ENone,EWrite,ERead,ECompare};
+class TErrInfo
+	{
+public:
+	TErrInfo();
+public:
+	TInt iError;
+	TOper iOperation;
+	TInt iCycle;
+	};
+
+class TResult
+	{
+public:
+	TResult();
+	void Display(CConsoleBase *aConsole, TInt aCycles);
+	void Add(TInt anError,TOper anOperation,TInt aCycle);
+public:
+	TInt iTotalErrs;
+	TErrInfo iFirstErr;
+	TErrInfo iLastErrs[KMaxErr];
+	TInt iNextFreeErr;
+	TBool iHadAnError;
+	};
+
+
+LOCAL_C TUint OperationToChar(TOper anOperation)
+//
+// Convert operation enum to corresponding display character
+//
+	{
+
+	switch(anOperation)
+		{
+		case EWrite:
+			return('W');
+		case ERead:
+			return('R');
+		case ECompare:
+			return('C');
+		default:
+			return('?');
+		}
+	}
+
+TErrInfo::TErrInfo()
+//
+// Constructor
+//
+	{
+
+	iError=KErrNone;
+	iOperation=ENone;
+	iCycle=0;
+	}
+
+TResult::TResult()
+//
+// Constructor
+//
+	{
+
+	iNextFreeErr=0;
+	iTotalErrs=0;
+	iHadAnError=EFalse;
+	}
+
+void TResult::Display(CConsoleBase *aConsole, TInt aCycles)
+//
+// Display test results
+//
+	{
+
+	TInt xStartPos=0;
+	TInt yStartPos=7;
+
+	aConsole->SetPos(xStartPos,yStartPos);
+	test.Printf(_L("CYCLES-> %07d   ERRORS-> %d"),aCycles,iTotalErrs);
+
+	aConsole->SetPos(xStartPos,yStartPos+1);
+	test.Printf(_L("FIRST ERROR-> "));
+	if (iHadAnError)
+		test.Printf(_L("Error:%d Oper:%c Cycle:%07d"),iFirstErr.iError,OperationToChar(iFirstErr.iOperation),iFirstErr.iCycle);
+
+	aConsole->SetPos(xStartPos,yStartPos+2);
+	test.Printf(_L("LAST ERRORS->"));
+	if (iHadAnError)
+		{
+		TInt i;
+		aConsole->SetPos(xStartPos+3,yStartPos+3);
+		test.Printf(_L("Error:  "));
+		for (i=0;(i<KMaxErr && iLastErrs[i].iOperation!=ENone);i++)
+			test.Printf(_L("% 7d,"),iLastErrs[i].iError);
+
+		aConsole->SetPos(xStartPos+3,yStartPos+4);
+		test.Printf(_L("Oper:   "));
+		for (i=0;(i<KMaxErr && iLastErrs[i].iOperation!=ENone);i++)
+			test.Printf(_L("      %c,"),OperationToChar(iLastErrs[i].iOperation));
+ 
+		aConsole->SetPos(xStartPos+3,yStartPos+5);
+		test.Printf(_L("Cycle:  "));
+		for (i=0;(i<KMaxErr && iLastErrs[i].iOperation!=ENone);i++)
+			test.Printf(_L("% 7d,"),iLastErrs[i].iCycle);
+		}
+
+	test.Printf(_L("\r\n"));
+	}
+
+void TResult::Add(TInt anError,TOper anOperation,TInt aCycle)
+//
+// Add a test result
+//
+	{
+
+	iTotalErrs++;
+	if (!iHadAnError)
+		{
+		iFirstErr.iError=anError;
+		iFirstErr.iOperation=anOperation;
+		iFirstErr.iCycle=aCycle;
+		iHadAnError=ETrue;
+		}
+	if (iNextFreeErr>=KMaxErr)
+		{
+		for (TInt i=0;i<(KMaxErr-1);i++)
+			iLastErrs[i]=iLastErrs[i+1];
+		iNextFreeErr=(KMaxErr-1);
+		}
+	iLastErrs[iNextFreeErr].iError=anError;
+	iLastErrs[iNextFreeErr].iOperation=anOperation;
+	iLastErrs[iNextFreeErr].iCycle=aCycle;
+	iNextFreeErr++;
+	}
+
+GLDEF_C TInt E32Main()
+    {
+	TBuf<64> b;
+
+	test.Title();
+	TDriveInfoV1Buf diBuf;
+	UserHal::DriveInfo(diBuf);
+	TDriveInfoV1 &di=diBuf();
+	test.Printf(_L("Select Local Drive (C-%c): "),'C'+(di.iTotalSupportedDrives-1));
+	TChar c;
+	TInt drv;
+	FOREVER
+		{
+		c=(TUint)test.Getch();
+		c.UpperCase();
+		drv=((TUint)c)-'C';
+		if (drv>=0&&drv<di.iTotalSupportedDrives)
+			break;
+		}
+	test.Printf(_L("%c:\r\n"),'C'+drv);
+
+	TInt rdWrLen;
+#if !defined (USE_F32_ACCESS)
+	test.Printf(_L("Select total sectors to write(1-8): "));
+	FOREVER
+		{
+		c=(TUint)test.Getch();
+		rdWrLen=((TUint)c)-'0';
+		if (rdWrLen>=1&&rdWrLen<=8)
+			break;
+		}
+	test.Printf(_L("%dSector(s)\r\n"),rdWrLen);
+	rdWrLen*=KAtaSectorSize;
+#else
+	rdWrLen=(KAtaSectorSize*2)+1;
+#endif
+
+	b.Format(_L("Init test on drive %c:"),'C'+drv);
+	test.Start(b);
+
+	TInt r;
+#if defined (USE_F32_ACCESS)
+	r=TheFs.Connect();
+	test(r==KErrNone);
+
+	RFile f;
+	b.Format(_L("%c:\\TEMP.BIN"),'C'+drv);
+	r=f.Replace(TheFs,b,EFileShareAny|EFileStream|EFileWrite);
+	test(r==KErrNone);
+	b.Format(_L("Start testing (%c:\\TEMP.BIN):"),'C'+drv);
+#else
+	r=User::LoadPhysicalDevice(ATA_PDD_NAME);
+	test(r==KErrNone || r==KErrAlreadyExists);
+
+	ChangedFlag=EFalse;
+	TheDrive.Connect(drv,ChangedFlag);
+
+	TLocalDriveCapsV2Buf info;
+	test(TheDrive.Caps(info)==KErrNone);
+	test(info().iType==EMediaHardDisk);
+	TInt trgPos=I64LOW(info().iSize)-rdWrLen;	  // Hammer the very end of the disk
+	b.Format(_L("Start testing (sector %xH):"),trgPos/KAtaSectorSize);
+#endif
+
+	test.Next(b);
+	wrBufPat1.SetLength(rdWrLen);
+	TInt j;
+	for (j=0;j<rdWrLen;j++)
+		wrBufPat1[j]=(TUint8)j;
+	wrBufPat2.SetLength(rdWrLen);
+	for (j=0;j<rdWrLen;j++)
+		wrBufPat2[j]=(TUint8)((rdWrLen-1)-j);
+
+	TInt cycles=0;
+	TResult results;
+	TBool toggleTest=EFalse;
+
+	TRequestStatus kStat;
+	test.Console()->Read(kStat);
+	FOREVER
+		{
+		if ((cycles%10)==0)
+			results.Display(test.Console(),cycles);
+
+		TInt res;
+#if defined (USE_F32_ACCESS)
+		TInt len=(toggleTest)?rdWrLen:1;
+
+		wrBufPat1.SetLength(len);
+		if ((res=f.SetSize(len))==KErrNone)
+			res=f.Write(0,wrBufPat1);		// Write test (Pos=0)
+		if (res!=KErrNone)
+			results.Add(res,EWrite,cycles);
+
+		// Read test
+		rdBuf.Fill(0,len);
+		res=f.Read(0,rdBuf,len);
+		if (res!=KErrNone)
+			results.Add(res,ERead,cycles);
+		if (rdBuf.Compare(wrBufPat1)!=0)
+			results.Add(0,ECompare,cycles);
+#else
+		TDes8* wrBuf=(toggleTest)?&wrBufPat2:&wrBufPat1; // Change pattern written
+		
+		res=TheDrive.Write(trgPos,*wrBuf);	// Write test
+		if (res!=KErrNone)
+			results.Add(res,EWrite,cycles);
+		
+		rdBuf.Fill(0,rdWrLen);
+		res=TheDrive.Read(trgPos,rdWrLen,rdBuf);	// Read test
+		if (res!=KErrNone)
+			results.Add(res,ERead,cycles);
+		if (rdBuf.Compare(*wrBuf)!=0)
+			results.Add(0,ECompare,cycles);
+#endif
+		cycles++;
+		toggleTest^=0x01;
+
+		if (kStat!=KRequestPending)
+			{
+			TKeyCode c=test.Console()->KeyCode();
+			if (c==EKeySpace)
+				break;
+			test.Console()->Read(kStat);
+			}
+		}
+
+	test.Next(_L("Close"));
+#if defined (USE_F32_ACCESS)
+	f.Close();
+	TheFs.Close();
+#else
+	TheDrive.Disconnect();
+#endif
+
+	test.End();
+	return(0);
+	}
+