// Copyright (c) 1996-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_crrdrv.cpp
// Test the Compact Rom (Programmable) card media driver
//
//
#include <e32test.h>
#include <e32svr.h>
#include <e32uid.h>
#define TWOMEG
LOCAL_D RTest test(_L("T_CRRDRV"));
#if defined (__MARM__)
const TInt KTestBufLen=0x100;
#define PDD_NAME _L("MEDCRR")
const TInt KDriveNumber=1; // D:
#if defined (TWOMEG)
const TInt KMaxDriveLen=0x00200000; // 2M
#else
const TInt KMaxDriveLen=0x00600000; // 6M
#endif
const TUint16 KMagicSum=0x1234;
const TInt KCRomPrivateAreaLen=0x800; // 1st 2K of CRom contains CIS
const TInt KCRomCisDataLength=0xD0;
LOCAL_D TBuf8<KTestBufLen> wrBuf,rdBuf;
#if defined (TWOMEG)
LOCAL_D const TText8 CompactRomCisData[KCRomCisDataLength]={
0x01,0xff,0x03,0xff,0x1c,0xff,0x01,0xff,0xff,0xff,0x1c,0xff,0x04,0xff,0x02,0xff,
0x1b,0xff,0x01,0xff,0xff,0xff,0x20,0xff,0x04,0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0x00,0xff,0x15,0xff,0x24,0xff,0x05,0xff,0x00,0xff,0x50,0xff,0x73,0xff,0x69,0xff,
0x6f,0xff,0x6e,0xff,0x20,0xff,0x50,0xff,0x4c,0xff,0x43,0xff,0x00,0xff,0x43,0xff,
0x6f,0xff,0x6d,0xff,0x70,0xff,0x61,0xff,0x63,0xff,0x74,0xff,0x20,0xff,0x52,0xff,
0x6f,0xff,0x6d,0xff,0x20,0xff,0x43,0xff,0x61,0xff,0x72,0xff,0x64,0xff,0x00,0xff,
0x56,0xff,0x30,0xff,0x2e,0xff,0x30,0xff,0x30,0xff,0x00,0xff,0xff,0xff,0x80,0xff,
0x03,0xff,0x58,0xff,0x06,0xff,0xff,0xff,0x21,0xff,0x02,0xff,0x01,0xff,0x00,0xff,
0x40,0xff,0x0b,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x08,0xff,0x00,0xff,0x00,0xff,
0x00,0xff,0x00,0xff,0x01,0xff,0x00,0xff,0x00,0xff,0x41,0xff,0x0a,0xff,0x01,0xff,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xf8,0xff,0x1f,0xff,
0x00,0xff,0x14,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
#else
LOCAL_D const TText8 CompactRomCisData[KCRomCisDataLength]={
0x01,0xff,0x03,0xff,0x1c,0xff,0x01,0xff,0xff,0xff,0x1c,0xff,0x04,0xff,0x02,0xff,
0x1b,0xff,0x01,0xff,0xff,0xff,0x20,0xff,0x04,0xff,0x00,0xff,0x00,0xff,0x00,0xff,
0x00,0xff,0x15,0xff,0x24,0xff,0x05,0xff,0x00,0xff,0x50,0xff,0x73,0xff,0x69,0xff,
0x6f,0xff,0x6e,0xff,0x20,0xff,0x50,0xff,0x4c,0xff,0x43,0xff,0x00,0xff,0x43,0xff,
0x6f,0xff,0x6d,0xff,0x70,0xff,0x61,0xff,0x63,0xff,0x74,0xff,0x20,0xff,0x52,0xff,
0x6f,0xff,0x6d,0xff,0x20,0xff,0x43,0xff,0x61,0xff,0x72,0xff,0x64,0xff,0x00,0xff,
0x56,0xff,0x30,0xff,0x2e,0xff,0x30,0xff,0x30,0xff,0x00,0xff,0xff,0xff,0x80,0xff,
0x0b,0xff,0x58,0xff,0x06,0xff,0x08,0xff,0x76,0xff,0x58,0xff,0x06,0xff,0x08,0xff,
0x76,0xff,0x58,0xff,0x06,0xff,0xff,0xff,0x21,0xff,0x02,0xff,0x01,0xff,0x00,0xff,
0x40,0xff,0x0b,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x08,0xff,0x00,0xff,0x00,0xff,
0x00,0xff,0x00,0xff,0x01,0xff,0x00,0xff,0x00,0xff,0x41,0xff,0x0a,0xff,0x01,0xff,
0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xf8,0xff,0x5f,0xff,
0x00,0xff,0x14,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
#endif
/* A sample multifunction CIS to test out tuple parsing by blowing onto CRom card.
const TInt KMfcCisDataLen=0x180;
LOCAL_D const TText8 MfcCisData[KMfcCisDataLen]={
0x13,0xff,0x03,0xff,0x43,0xff,0x49,0xff,0x53,0xff,0x06,0xff,0x10,0xff,0x03,0xff,
0x00,0xff,0x30,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x60,0xff,0x00,0xff,
0x00,0xff,0x00,0xff,0x00,0xff,0x90,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x01,0xff,0x03,0xff,0xda,0xff,0x00,0xff,0xff,0xff,0x1c,0xff,0x04,0xff,0x02,0xff,
0xda,0xff,0x00,0xff,0xff,0xff,0x21,0xff,0x02,0xff,0x02,0xff,0x00,0xff,0x1a,0xff,
0x05,0xff,0x01,0xff,0x01,0xff,0x00,0xff,0x02,0xff,0x0f,0xff,0x1b,0xff,0x07,0xff,
0xc1,0xff,0x41,0xff,0x09,0xff,0x01,0xff,0xb5,0xff,0x1e,0xff,0x49,0xff,0x14,0xff,
0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x01,0xff,0x03,0xff,0xda,0xff,0x00,0xff,0xff,0xff,0x1c,0xff,0x04,0xff,0x02,0xff,
0xda,0xff,0x00,0xff,0xff,0xff,0x21,0xff,0x02,0xff,0x06,0xff,0x00,0xff,0x1a,0xff,
0x05,0xff,0x01,0xff,0x02,0xff,0x00,0xff,0x04,0xff,0x0f,0xff,0x1b,0xff,0x06,0xff,
0xc2,0xff,0x41,0xff,0x09,0xff,0x01,0xff,0x55,0xff,0x49,0xff,0x14,0xff,0x00,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x01,0xff,0x03,0xff,0xda,0xff,0x00,0xff,0xff,0xff,0x1c,0xff,0x04,0xff,0x02,0xff,
0xda,0xff,0x00,0xff,0xff,0xff,0x21,0xff,0x02,0xff,0x03,0xff,0x00,0xff,0x1a,0xff,
0x05,0xff,0x01,0xff,0x03,0xff,0x00,0xff,0x06,0xff,0x0f,0xff,0x1b,0xff,0x06,0xff,
0xc3,0xff,0x41,0xff,0x09,0xff,0x01,0xff,0x55,0xff,0x49,0xff,0x14,0xff,0x00,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
}; */
LOCAL_C void ProgressBar(TInt aPos,TInt anEndPos,TInt anXPos)
//
// Display progress of local drive operation on screen (1-16 dots)
//
{
static TInt prev;
TInt curr;
if ((curr=(aPos-1)/(anEndPos>>4))>prev)
{ // Update progress bar
test.Console()->SetPos(anXPos);
for (TInt i=curr;i>=0;i--)
test.Printf(_L("."));
}
prev=curr;
}
GLDEF_C TInt E32Main()
{
TInt i;
TBuf<32> b;
test.Title();
// UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change (in case normal CROM driver open on target).
User::After(300000); // Allow 0.3s for controller to detect door closed.
test.Start(_L("Load CROM(repro) Media Driver"));
TInt r=User::LoadPhysicalDevice(PDD_NAME);
test(r==KErrNone||r==KErrAlreadyExists);
b.Format(_L("Connect to local drive (%c:)"),KDriveNumber+'C');
test.Next(b);
TBusLocalDrive theCRomDrive;
TBool changeFlag=FALSE;
test(theCRomDrive.Connect(KDriveNumber,changeFlag)==KErrNone);
test.Next(_L("CROM drive: capabilities"));
// UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change (in case normal CROM driver open on target).
User::After(300000); // Allow 0.3s for controller to detect door closed.
TLocalDriveCapsV2Buf info;
test(theCRomDrive.Caps(info)==KErrNone);
test(info().iSize==(TInt64)KMaxDriveLen);
test(info().iType==EMediaFlash);
test(info().iConnectionBusType==EConnectionBusInternal);
test(info().iDriveAtt==(KDriveAttLocal|KDriveAttRemovable));
test(info().iMediaAtt==KMediaAttFormattable);
test(info().iFileSystemId==KDriveFileSysFAT);
test.Next(_L("CROM drive: format"));
TFormatInfo fi;
test.Printf(_L("Formatting "));
TInt ret;
while((ret=theCRomDrive.Format(fi))!=KErrEof)
{
ProgressBar((fi.i512ByteSectorsFormatted<<9),KMaxDriveLen,11);
test(ret==KErrNone);
}
test.Printf(_L("\r\nReading "));
TInt len;
TInt msgHandle = KLocalMessageHandle;
for (i=0;i<KMaxDriveLen;i+=len)
{
ProgressBar(i,KMaxDriveLen,11);
len=Min(KTestBufLen,(KMaxDriveLen-i));
rdBuf.Fill(0x55,len); // Sets length too
test(theCRomDrive.Read(i,len,&rdBuf,msgHandle,0)==KErrNone);
wrBuf.Fill(0xFF,len); // Sets length too
if ((ret=rdBuf.Compare(wrBuf))!=0)
{
test.Printf(_L(" (C:%d@%xH)\r\n"),ret,i);
test(0);
}
}
test.Printf(_L("\r\n"));
wrBuf.SetLength(KTestBufLen);
for (i=0;i<KTestBufLen;i++)
wrBuf[i]=(TUint8)i;
/*
test.Next(_L("CROM drive: Write at start of Drive"));
test(theCRomDrive.Write(0,KTestBufLen,&wrBuf,msgHandle,0)==KErrNone);
rdBuf.Fill(0,KTestBufLen);
test(theCRomDrive.Read(0,KTestBufLen,&rdBuf,msgHandle,0)==KErrNone);
test(rdBuf.Compare(wrBuf)==0);
test.Next(_L("CROM drive: Write at end of Drive"));
test(theCRomDrive.Write(KMaxDriveLen-KTestBufLen,KTestBufLen,&wrBuf,msgHandle,0)==KErrNone);
rdBuf.Fill(0,KTestBufLen);
test(theCRomDrive.Read(KMaxDriveLen-KTestBufLen,KTestBufLen,&rdBuf,msgHandle,0)==KErrNone);
test(rdBuf.Compare(wrBuf)==0);
test.Next(_L("CROM drive: Write across 64K block boundary"));
test(theCRomDrive.Write((0x10000-(KTestBufLen>>1)),KTestBufLen,&wrBuf,msgHandle,0)==KErrNone);
rdBuf.Fill(0,KTestBufLen);
test(theCRomDrive.Read((0x10000-(KTestBufLen>>1)),KTestBufLen,&rdBuf,msgHandle,0)==KErrNone);
test(rdBuf.Compare(wrBuf)==0);
test.Next(_L("CROM drive: Write across 28F016 device boundary"));
test(theCRomDrive.Write((0x200000-(KTestBufLen>>1)),KTestBufLen,&wrBuf,msgHandle,0)==KErrNone);
rdBuf.Fill(0,KTestBufLen);
test(theCRomDrive.Read((0x200000-(KTestBufLen>>1)),KTestBufLen,&rdBuf,msgHandle,0)==KErrNone);
test(rdBuf.Compare(wrBuf)==0);
*/
test.Next(_L("CROM drive: Write/Read the entire disk"));
TInt rdwrTestLen=(KTestBufLen-3); // Test it works off word boundary
TUint *p=(TUint*)&wrBuf[0];
TInt j;
test.Printf(_L("Writing "));
for (i=0,j=0;i<KMaxDriveLen;i+=len,j++)
{
ProgressBar(i,KMaxDriveLen,11);
len=Min(rdwrTestLen,(KMaxDriveLen-i));
(*p)=j;
test(theCRomDrive.Write(i,len,&wrBuf,msgHandle,0)==KErrNone);
}
test.Printf(_L("\r\nReading "));
for (i=0,j=0;i<KMaxDriveLen;i+=len,j++)
{
ProgressBar(i,KMaxDriveLen,11);
len=Min(rdwrTestLen,(KMaxDriveLen-i));
rdBuf.Fill(0,len);
if ((ret=theCRomDrive.Read(i,len,&rdBuf,msgHandle,0))!=KErrNone)
{
test.Printf(_L(" (R:%d@%xH)\r\n"),ret,j);
test(0);
}
(*p)=j;
wrBuf.SetLength(len);
if ((ret=rdBuf.Compare(wrBuf))!=0)
{
test.Printf(_L(" (C:%d@%xH)\r\n"),ret,j);
test(0);
}
}
test.Printf(_L("\r\n"));
test.Next(_L("CROM drive: Re-format"));
test.Printf(_L("Formatting "));
while((ret=theCRomDrive.Format(fi))!=KErrEof)
{
ProgressBar((fi.i512ByteSectorsFormatted<<9),KMaxDriveLen,11);
test(ret==KErrNone);
}
test.Printf(_L("\r\n"));
test.Next(_L("CROM drive: Write CIS at start of Drive"));
TPtrC8 buf(&CompactRomCisData[0],KCRomCisDataLength);
// TPtrC8 buf(&MfcCisData[0],KMfcCisDataLen); // ???
test(theCRomDrive.Write(0,buf)==KErrNone);
rdBuf.Fill(0,KTestBufLen);
test(theCRomDrive.Read(0,KCRomCisDataLength,rdBuf)==KErrNone);
test(rdBuf.Compare(buf)==0);
test.Next(_L("Calculating & writing checksum"));
TUint16 checksum=0; // 16bit arithmetic
test.Printf(_L("Reading"));
for (i=0;i<KMaxDriveLen;i+=len)
{
ProgressBar(i,KMaxDriveLen,11);
len=Min(KTestBufLen,(KMaxDriveLen-i));
test(theCRomDrive.Read(i,len,rdBuf)==KErrNone);
test((len%2)==0); // 16bit checksum - length must never be odd
for (TInt j=0;j<len;j+=2)
checksum+=*(TUint16*)(rdBuf.Ptr()+j);
}
checksum-=0xFFFF; // Subtract for checksum itself
TUint16 adjust=KMagicSum-checksum;
test.Printf(_L("\r\n (CS:%xH)\r\n"),adjust);
TPtrC8 cs((TUint8*)&adjust,2);
test(theCRomDrive.Write(KCRomPrivateAreaLen-2,cs)==KErrNone);
test.Next(_L("CROM drive: Caps following media change"));
// UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change
User::After(300000); // Allow 0.3s after power down for controller to detect door closed.
test(changeFlag!=FALSE);
test(theCRomDrive.Caps(info)==KErrNone);
test(info().iSize==(TInt64)KMaxDriveLen);
test(info().iType==EMediaFlash);
b.Format(_L("Disconnect from local drive (%c:)"),KDriveNumber+'C');
test.Next(b);
theCRomDrive.Disconnect();
TFindPhysicalDevice fDr;
test.Next(_L("Unload CROM(prog) Media Driver"));
TFullName drivName;
fDr.Find(_L("Media.RomPrg"));
test(fDr.Next(drivName)==KErrNone);
test(User::FreePhysicalDevice(drivName)==KErrNone);
// UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change (allow normal CROM driver on next target access).
test.End();
return(0);
}
#else
TInt E32Main()
{
test.Title();
test.Start(_L("T_CRRDRV only runs under ARM build."));
test.End();
return(KErrNone);
}
#endif