kerneltest/e32test/pccd/t_atadrv.cpp
changeset 0 a41df078684a
child 33 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1996-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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32test\pccd\t_atadrv.cpp
       
    15 // Test the Compact Flash card (ATA) media driver
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <e32test.h>
       
    20 #include <e32svr.h>
       
    21 #include <e32hal.h>
       
    22 #include <e32uid.h>
       
    23 #include <hal.h>
       
    24 #include <e32def.h>
       
    25 #include <e32def_private.h>
       
    26 
       
    27 const TInt KAtaSectorSize=512;
       
    28 const TInt KAtaSectorShift=9;
       
    29 const TUint KAtaSectorMask=0xFFFFFE00;
       
    30 const TInt KSectBufSizeInSectors=8;
       
    31 const TInt KSectBufSizeInBytes=(KSectBufSizeInSectors<<KAtaSectorShift);
       
    32 const TInt KRdWrBufLen=(KSectBufSizeInBytes+KAtaSectorSize); // 4.5K - exceeds driver local buffer size
       
    33 
       
    34 const TInt KShortFormatInSectors=1;
       
    35 const TInt KShortFormatInBytes=(KShortFormatInSectors<<KAtaSectorShift);
       
    36 const TInt KLongFormatInSectors=KSectBufSizeInSectors+1;	// 4.5K - exceeds driver local buffer size
       
    37 const TInt KLongFormatInBytes=(KLongFormatInSectors<<KAtaSectorShift);
       
    38 
       
    39 const TInt KHeapSize=0x4000;
       
    40 const TInt KAtaIdleCurrentInMilliAmps=1; 
       
    41 
       
    42 #define PDD_NAME _L("MEDATA")
       
    43 
       
    44 LOCAL_D RTest test(_L("T_ATADRV"));
       
    45 LOCAL_D RTest nTest(_L("This thread doesn't disconnect"));
       
    46 LOCAL_D TBool ChangeFlag;
       
    47 LOCAL_D TBool SecThreadChangeFlag;
       
    48 LOCAL_D TBuf8<KRdWrBufLen> wrBuf,rdBuf;
       
    49 LOCAL_D TInt DriveNumber;
       
    50 
       
    51 const TInt KSingSectorNo=1;
       
    52 void singleSectorRdWrTest(TBusLocalDrive &aDrv,TInt aSectorOffset,TInt aLen)
       
    53 //
       
    54 // Perform a write / read test on a single sector (KSingSectorNo). Verify that the
       
    55 // write / read back is successful and that the rest of the sector is unchanged.
       
    56 //
       
    57 	{
       
    58 
       
    59 	TBuf8<KAtaSectorSize> saveBuf;
       
    60 	test.Start(_L("Single sector write/read test"));
       
    61 	test(aSectorOffset+aLen<=KAtaSectorSize);
       
    62 
       
    63 	// Now save state of sector before we write to it
       
    64 	TInt secStart=(KSingSectorNo<<KAtaSectorShift);
       
    65  	test(aDrv.Read(secStart,KAtaSectorSize,saveBuf)==KErrNone);
       
    66 
       
    67 	// Write zero's to another sector altogether (to ensure drivers 
       
    68 	// local buffer hasn't already got test pattern we expect).
       
    69 	wrBuf.Fill(0,KAtaSectorSize);
       
    70 	test(aDrv.Write((KSingSectorNo+4)<<KAtaSectorShift,wrBuf)==KErrNone);
       
    71 
       
    72 	// Write / read back sector in question
       
    73 	wrBuf.SetLength(aLen);
       
    74 	for (TInt i=0;i<aLen;i++)
       
    75 		wrBuf[i]=(TUint8)(0xFF-i);
       
    76 	test(aDrv.Write((secStart+aSectorOffset),wrBuf)==KErrNone);
       
    77 	rdBuf.Fill(0,aLen);
       
    78  	test(aDrv.Read((secStart+aSectorOffset),aLen,rdBuf)==KErrNone);
       
    79   	test(rdBuf.Compare(wrBuf)==0);
       
    80 
       
    81 	// Now check the rest of the sector is unchanged
       
    82 	rdBuf.Fill(0,KAtaSectorSize);
       
    83  	test(aDrv.Read(secStart,KAtaSectorSize,rdBuf)==KErrNone);
       
    84 	saveBuf.Replace(aSectorOffset,aLen,wrBuf);
       
    85   	test(rdBuf.Compare(saveBuf)==0);
       
    86 	test.End();
       
    87 	}
       
    88 
       
    89 const TInt KMultSectorNo=2; 
       
    90 void MultipleSectorRdWrTest(TBusLocalDrive &aDrv,TInt aFirstSectorOffset,TInt aLen)
       
    91 //
       
    92 // Perform a write / read test over multiple sectors (starting within sector KMultSectorNo).
       
    93 // Verify that the write / read back is successful and that the remainder of the first and
       
    94 // last sectors are not affected.
       
    95 //
       
    96 	{
       
    97 
       
    98 	TBuf8<KAtaSectorSize> saveBuf1;
       
    99 	TBuf8<KAtaSectorSize> saveBuf2;
       
   100 	test.Start(_L("Multiple sector write/read test"));
       
   101 	test(aFirstSectorOffset<KAtaSectorSize&&aLen<=KRdWrBufLen);
       
   102 
       
   103 	// If not starting on sector boundary then save 1st sector to check rest of 1st sector is unchanged
       
   104 	TInt startSecPos=(KMultSectorNo<<KAtaSectorShift);
       
   105 	if (aFirstSectorOffset!=0)
       
   106  		test(aDrv.Read(startSecPos,KAtaSectorSize,saveBuf1)==KErrNone);
       
   107 
       
   108 	// If not ending on sector boundary then save last sector to check rest of last sector is unchanged
       
   109 	TInt endOffset=(aFirstSectorOffset+aLen)&(~KAtaSectorMask);
       
   110 	TInt endSecPos=((startSecPos+aFirstSectorOffset+aLen)&KAtaSectorMask);
       
   111 	if (endOffset)
       
   112  		test(aDrv.Read(endSecPos,KAtaSectorSize,saveBuf2)==KErrNone);
       
   113 	
       
   114 	// Write zero's to another sector altogether (to ensure drivers 
       
   115 	// local buffer hasn't already got test pattern we expect).
       
   116 	wrBuf.Fill(0,KSectBufSizeInBytes);
       
   117 	test(aDrv.Write((KMultSectorNo+20)<<KAtaSectorShift,wrBuf)==KErrNone);
       
   118 	
       
   119 	wrBuf.SetLength(aLen);
       
   120 	for (TInt i=0;i<aLen;i++)
       
   121 		wrBuf[i]=(TUint8)(0xFF-i);
       
   122 	test(aDrv.Write((startSecPos+aFirstSectorOffset),wrBuf)==KErrNone);
       
   123 	rdBuf.Fill(0,aLen);
       
   124  	test(aDrv.Read((startSecPos+aFirstSectorOffset),aLen,rdBuf)==KErrNone);
       
   125   	test(rdBuf.Compare(wrBuf)==0);
       
   126 
       
   127 	// Check rest of first sector involved is unchanged (if offset specified)
       
   128 	if (aFirstSectorOffset!=0)
       
   129 		{
       
   130 		rdBuf.Fill(0,KAtaSectorSize);
       
   131  		test(aDrv.Read(startSecPos,KAtaSectorSize,rdBuf)==KErrNone);
       
   132 		wrBuf.SetLength(KAtaSectorSize-aFirstSectorOffset);
       
   133 		saveBuf1.Replace(aFirstSectorOffset,(KAtaSectorSize-aFirstSectorOffset),wrBuf);
       
   134   		test(rdBuf.Compare(saveBuf1)==0);
       
   135 		}
       
   136 
       
   137 	// Check rest of last sector involved is unchanged (if not ending on sector boundary)
       
   138 	if (endOffset)
       
   139 		{
       
   140 		rdBuf.Fill(0,KAtaSectorSize);
       
   141  		test(aDrv.Read(endSecPos,KAtaSectorSize,rdBuf)==KErrNone);
       
   142 		wrBuf.SetLength(aLen);
       
   143 		wrBuf.Delete(0,aLen-endOffset);
       
   144 		saveBuf2.Replace(0,endOffset,wrBuf);
       
   145   		test(rdBuf.Compare(saveBuf2)==0);
       
   146 		}
       
   147 	test.End();
       
   148 	}
       
   149 
       
   150 LOCAL_C TInt dontDisconnectThread(TAny*)
       
   151 	{
       
   152 
       
   153 	TBusLocalDrive anotherAtaDrive;
       
   154 	nTest.Title();
       
   155 
       
   156 	nTest.Start(_L("Connect to internal drive"));
       
   157 	anotherAtaDrive.Connect(DriveNumber,SecThreadChangeFlag);
       
   158 
       
   159 	nTest.Next(_L("Capabilities"));
       
   160 	TLocalDriveCapsV2 info;
       
   161 	TPckg<TLocalDriveCapsV2> infoPckg(info);
       
   162 	nTest(anotherAtaDrive.Caps(infoPckg)==KErrNone);
       
   163 	nTest(info.iType==EMediaHardDisk);
       
   164 
       
   165     nTest.End();
       
   166 	return(KErrNone);
       
   167 	}
       
   168 
       
   169 LOCAL_C void ProgressBar(TInt aPos,TInt anEndPos,TInt anXPos)
       
   170 //
       
   171 // Display progress of local drive operation on screen (1-16 dots)
       
   172 //
       
   173 	{
       
   174 	static TInt prev;
       
   175 	TInt curr;
       
   176 	if ((curr=(aPos-1)/(anEndPos>>4))>prev)
       
   177 		{ // Update progress bar
       
   178 		test.Console()->SetPos(anXPos);
       
   179 		for (TInt i=curr;i>=0;i--)
       
   180 			test.Printf(_L("."));
       
   181 		}
       
   182 	prev=curr;
       
   183 	}
       
   184 
       
   185 #pragma warning( disable : 4702 ) // unreachable code
       
   186 
       
   187 GLDEF_C TInt E32Main()
       
   188     {
       
   189 	TInt i;
       
   190 	TBuf<64> b;
       
   191 
       
   192 	TDriveInfoV1Buf diBuf;
       
   193 	UserHal::DriveInfo(diBuf);
       
   194 	TDriveInfoV1 &di=diBuf();
       
   195 	test.Title();
       
   196 	test.Start(_L("Test the Compact Flash card (ATA) media drive"));
       
   197 	test.Printf(_L("DRIVES PRESENT  :%d\r\n"),di.iTotalSupportedDrives);
       
   198 	test.Printf(_L("1ST DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[0]);
       
   199 	test.Printf(_L("2ND DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[1]);
       
   200 	test.Printf(_L("3RD DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[2]);
       
   201 	test.Printf(_L("4TH DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[3]);
       
   202 	test.Printf(_L("5TH DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[4]);
       
   203 	test.Printf(_L("6TH DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[5]);
       
   204 	test.Printf(_L("7TH DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[6]);
       
   205 	test.Printf(_L("8TH DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[7]);
       
   206 	test.Printf(_L("9TH DRIVE NAME  :%- 16S\r\n"),&di.iDriveName[8]);
       
   207 
       
   208 	test.Printf(_L("\r\nWarning - all data on removable drive will be lost.\r\n"));
       
   209 	test.Printf(_L("<<<Hit D to continue>>>\r\n"));
       
   210 	TChar c=(TUint)test.Getch();
       
   211 	c.UpperCase();
       
   212 	DriveNumber=((TUint)c)-'C';
       
   213 	test(DriveNumber >= 1 && DriveNumber < di.iTotalSupportedDrives);
       
   214 
       
   215 #if defined (__WINS__)
       
   216 	// Connect to all the local drives first as will be the case in ARM
       
   217 	TBusLocalDrive Drive[KMaxLocalDrives];
       
   218 	TBool DriveFlag[KMaxLocalDrives];
       
   219 	for (i=0;i<KMaxLocalDrives;i++)
       
   220 		Drive[i].Connect(i,DriveFlag[i]);
       
   221 #endif
       
   222 
       
   223 	test.Next(_L("Load ATA Media Driver"));
       
   224 	TInt r=User::LoadPhysicalDevice(PDD_NAME);
       
   225 	test(r==KErrNone||r==KErrAlreadyExists);
       
   226 
       
   227     test.Next(_L("Read machine information"));
       
   228 	TInt mid;
       
   229 	r=HAL::Get(HAL::EMachineUid,mid);
       
   230 	test(r==KErrNone);
       
   231 	TBool mediaChangeSupported=EFalse;
       
   232 
       
   233 	b.Format(_L("Connect to local drive (%c:)"),DriveNumber+'C');
       
   234 	test.Next(b);
       
   235 	TBusLocalDrive theAtaDrive;
       
   236 	ChangeFlag=EFalse;
       
   237 	test(theAtaDrive.Connect(DriveNumber,ChangeFlag)==KErrNone);
       
   238 	if (mediaChangeSupported)
       
   239 		{
       
   240 		theAtaDrive.ForceMediaChange();	// Generate media change to reset PC Card current consumption
       
   241 		User::After(300000);			// Allow 0.3s after power down for controller to detect door closed.
       
   242 		}
       
   243 //	TSupplyInfoV1Buf supply1;
       
   244 //	test(UserHal::SupplyInfo(supply1)==KErrNone);
       
   245 
       
   246 	test.Next(_L("ATA drive: Capabilities"));
       
   247 	TInt diskSize;
       
   248 	TTime startTime;
       
   249 	startTime.HomeTime();
       
   250 	TLocalDriveCapsV2 info;
       
   251 	TPckg<TLocalDriveCapsV2> infoPckg(info);
       
   252 	test(theAtaDrive.Caps(infoPckg)==KErrNone);
       
   253 	diskSize=I64LOW(info.iSize);
       
   254 	test.Printf( _L("Check drive size: %d\r\n"),diskSize);
       
   255 #if defined (__WINS__)
       
   256 	test.Printf(_L("Check hidden sectors (=0): %d\r\n"),info.iHiddenSectors);
       
   257 #else
       
   258 	test.Printf(_L("Check hidden sectors (=16/32): %d\r\n"),info.iHiddenSectors);
       
   259 #endif
       
   260 	// test.Getch();
       
   261 	test(info.iType==EMediaHardDisk);
       
   262 	test(info.iBattery==EBatNotSupported);
       
   263 	test(info.iDriveAtt==(TUint)(KDriveAttLocal|KDriveAttRemovable));
       
   264 	test(info.iMediaAtt==KMediaAttFormattable);
       
   265 	test(info.iFileSystemId==KDriveFileSysFAT);
       
   266 //	TSupplyInfoV1Buf supply2;
       
   267 //	test(UserHal::SupplyInfo(supply2)==KErrNone);
       
   268 //	if (mediaChangeSupported)
       
   269 //		test(supply2().iCurrentConsumptionMilliAmps==supply1().iCurrentConsumptionMilliAmps+KAtaIdleCurrentInMilliAmps); // Snowball idle current is zero
       
   270 
       
   271 	b.Format(_L("ATA drive: Sector RdWr(%d)"),KAtaSectorSize);
       
   272 	test.Next(b);
       
   273 	TInt len;
       
   274 	wrBuf.SetLength(KAtaSectorSize);
       
   275 	TUint *p=(TUint*)&wrBuf[0];
       
   276 	for (i=0;i<KAtaSectorSize;i++)
       
   277 		wrBuf[i]=(TUint8)i;
       
   278 
       
   279 	test.Printf(_L("Writing    "));
       
   280 	for (i=0;i<diskSize;i+=len)	 // B - Sector wr/rd on sector boundary
       
   281 		{
       
   282 		ProgressBar(i,diskSize,11);
       
   283 		len=Min(KAtaSectorSize,(diskSize-i));
       
   284 		(*p)=(i/KAtaSectorSize);
       
   285 		wrBuf.SetLength(len);
       
   286 		test(theAtaDrive.Write(i,wrBuf)==KErrNone);
       
   287 		}
       
   288 	test.Printf(_L("\r\nReading    "));
       
   289 	for (i=0;i<diskSize;i+=len)
       
   290 		{
       
   291 		ProgressBar(i,diskSize,11);
       
   292 		len=Min(KAtaSectorSize,(diskSize-i));
       
   293 		rdBuf.Fill(0,len);
       
   294  		test(theAtaDrive.Read(i,len,rdBuf)==KErrNone);
       
   295 		(*p)=(i/KAtaSectorSize);
       
   296 		wrBuf.SetLength(len);
       
   297   	    test(rdBuf.Compare(wrBuf)==0);
       
   298 		}
       
   299 	test.Printf(_L("\r\n"));
       
   300 
       
   301 	b.Format(_L("ATA drive: Short RdWr(1) (%dbytes at %d)"),25,0); 
       
   302 	test.Next(b);
       
   303 	singleSectorRdWrTest(theAtaDrive,0,25); // A - Sub-sector wr/rd at sector start
       
   304 
       
   305 	b.Format(_L("ATA drive: Short RdWr(2) (%dbytes at %d)"),16,277); 
       
   306 	test.Next(b);
       
   307 	singleSectorRdWrTest(theAtaDrive,277,16); // E - Sub-sector wr/rd in mid sector
       
   308 
       
   309 	b.Format(_L("ATA drive: Short RdWr(3) (%dbytes at %d)"),100,412); 
       
   310 	test.Next(b);
       
   311 	singleSectorRdWrTest(theAtaDrive,412,100); // F - Sub-sector wr/rd at sector end
       
   312 
       
   313 	b.Format(_L("ATA drive: Long RdWr(1) (%dbytes at %d)"),KAtaSectorSize+15,0);
       
   314 	test.Next(b);
       
   315 	MultipleSectorRdWrTest(theAtaDrive,0,KAtaSectorSize+15); // C - Long wr/rd starting on sector boundary
       
   316 
       
   317 	b.Format(_L("ATA drive: Long RdWr(2) (%dbytes at %d)"),(KAtaSectorSize<<1),0);
       
   318 	test.Next(b);
       
   319 	MultipleSectorRdWrTest(theAtaDrive,0,(KAtaSectorSize<<1)); // D - Long wr/rd starting/ending on sector boundary
       
   320 
       
   321 	b.Format(_L("ATA drive: Long RdWr(3) (%dbytes at %d)"),KAtaSectorSize+3,509);
       
   322 	test.Next(b);
       
   323 	MultipleSectorRdWrTest(theAtaDrive,509,KAtaSectorSize+3); // H -  - Long wr/rd ending on sector boundary
       
   324 
       
   325 	b.Format(_L("ATA drive: Long RdWr(4) (%dbytes at %d)"),(KAtaSectorSize<<1),508);
       
   326 	test.Next(b);
       
   327 	MultipleSectorRdWrTest(theAtaDrive,508,(KAtaSectorSize<<1));
       
   328 
       
   329 	b.Format(_L("ATA drive: Sector RdWr across sector boundary(%dbytes at %d)"),KAtaSectorSize,508);
       
   330 	test.Next(b);
       
   331 	MultipleSectorRdWrTest(theAtaDrive,508,KAtaSectorSize); // G - Sector wr/rd over sector boundary
       
   332 
       
   333   	b.Format(_L("ATA drive: Very long RdWr(1) (%dbytes at %d)"),KRdWrBufLen,0);
       
   334 	test.Next(b);
       
   335 	MultipleSectorRdWrTest(theAtaDrive,0,KRdWrBufLen); // Exceeds driver's buffer, starts/ends on sector boundary
       
   336 
       
   337   	b.Format(_L("ATA drive: Very long RdWr(2) (%dbytes at %d)"),(KRdWrBufLen-KAtaSectorSize+5),507);
       
   338 	test.Next(b);
       
   339 	MultipleSectorRdWrTest(theAtaDrive,507,(KRdWrBufLen-KAtaSectorSize+5)); // Exceeds driver's buffer, ends on sector boundary
       
   340 
       
   341   	b.Format(_L("ATA drive: Very long RdWr(3) (%dbytes at %d)"),KRdWrBufLen,10);
       
   342 	test.Next(b);
       
   343 	MultipleSectorRdWrTest(theAtaDrive,10,KRdWrBufLen); // Exceeds driver's buffer, starts/ends off sector boundary
       
   344 
       
   345   	b.Format(_L("ATA drive: Very long RdWr(4) (%dbytes at %d)"),(KRdWrBufLen-3),0);
       
   346 	test.Next(b);
       
   347 	MultipleSectorRdWrTest(theAtaDrive,0,KRdWrBufLen-3); // Exceeds driver's buffer, starts on sector boundary
       
   348 
       
   349   	b.Format(_L("ATA drive: Very long RdWr(5) (%dbytes at %d)"),(KRdWrBufLen-KAtaSectorSize),27);
       
   350 	test.Next(b);
       
   351 	MultipleSectorRdWrTest(theAtaDrive,27,(KRdWrBufLen-KAtaSectorSize)); // Exceeds driver's buffer (due to start offset), starts/ends off sector boundary
       
   352 
       
   353   	b.Format(_L("ATA drive: Very long RdWr(6) (%dbytes at %d)"),(KRdWrBufLen-KAtaSectorSize-3),0);
       
   354 	test.Next(b);
       
   355 	MultipleSectorRdWrTest(theAtaDrive,0,KRdWrBufLen-KAtaSectorSize-3); // Equals driver's buffer, starts on sector boundary
       
   356 
       
   357   	b.Format(_L("ATA drive: Very long RdWr(7) (%dbytes at %d)"),(KRdWrBufLen-3),3);
       
   358 	test.Next(b);
       
   359 	MultipleSectorRdWrTest(theAtaDrive,3,KRdWrBufLen-3); // Equals driver's buffer, ends on sector boundary
       
   360 /*
       
   361 	test.Next(_L("ATA drive: Inter-thread RdWr"));
       
   362 	RThread dummyThread;
       
   363 	dummyThread.Duplicate(RThread());
       
   364   	TInt threadHandle=dummyThread.Handle();
       
   365 	wrBuf.SetLength(KAtaSectorSize);
       
   366 	for (i=0;i<KAtaSectorSize;i++)
       
   367 		wrBuf[i]=(TUint8)i;
       
   368 	test(theAtaDrive.Write(10,KAtaSectorSize,&wrBuf,threadHandle,0)==KErrNone);
       
   369 	rdBuf.Fill(0,KAtaSectorSize);
       
   370  	test(theAtaDrive.Read(10,KAtaSectorSize,&rdBuf,threadHandle,0)==KErrNone);
       
   371   	test(rdBuf.Compare(wrBuf)==0);
       
   372 	dummyThread.Close();
       
   373 */
       
   374 	test.Next(_L("ATA drive: Format sectors (short)"));
       
   375 	TBuf8<KAtaSectorSize> savBuf1,savBuf2;
       
   376 	TInt fmtTestPos=(10<<KAtaSectorShift);
       
   377 	// Save sectors surrounding those which will be formatted
       
   378  	test(theAtaDrive.Read((fmtTestPos-KAtaSectorSize),KAtaSectorSize,savBuf1)==KErrNone);
       
   379  	test(theAtaDrive.Read((fmtTestPos+KShortFormatInBytes),KAtaSectorSize,savBuf2)==KErrNone);
       
   380 	test(theAtaDrive.Format(fmtTestPos,KShortFormatInBytes)==KErrNone);
       
   381  	test(theAtaDrive.Read(fmtTestPos,KShortFormatInBytes,rdBuf)==KErrNone);
       
   382 	wrBuf.Fill(0xFF,KShortFormatInBytes);
       
   383   	test(rdBuf.Compare(wrBuf)==0);
       
   384     // Check that surrounding sectors unaffected
       
   385  	test(theAtaDrive.Read((fmtTestPos-KAtaSectorSize),KAtaSectorSize,rdBuf)==KErrNone);
       
   386   	test(rdBuf.Compare(savBuf1)==0);
       
   387  	test(theAtaDrive.Read((fmtTestPos+KShortFormatInBytes),KAtaSectorSize,rdBuf)==KErrNone);
       
   388   	test(rdBuf.Compare(savBuf2)==0);
       
   389 
       
   390 	test.Next(_L("ATA drive: Format sectors (long)"));
       
   391 	fmtTestPos+=(4<<KAtaSectorShift);
       
   392 	// Save sectors surrounding those which will be formatted
       
   393  	test(theAtaDrive.Read((fmtTestPos-KAtaSectorSize),KAtaSectorSize,savBuf1)==KErrNone);
       
   394  	test(theAtaDrive.Read((fmtTestPos+KLongFormatInBytes),KAtaSectorSize,savBuf2)==KErrNone);
       
   395 	test(theAtaDrive.Format(fmtTestPos,KLongFormatInBytes)==KErrNone);
       
   396  	test(theAtaDrive.Read(fmtTestPos,KLongFormatInBytes,rdBuf)==KErrNone);
       
   397 	wrBuf.Fill(0xFF,KLongFormatInBytes);
       
   398   	test(rdBuf.Compare(wrBuf)==0);
       
   399     // Check that surrounding sectors unaffected
       
   400  	test(theAtaDrive.Read((fmtTestPos-KAtaSectorSize),KAtaSectorSize,rdBuf)==KErrNone);
       
   401   	test(rdBuf.Compare(savBuf1)==0);
       
   402  	test(theAtaDrive.Read((fmtTestPos+KLongFormatInBytes),KAtaSectorSize,rdBuf)==KErrNone);
       
   403   	test(rdBuf.Compare(savBuf2)==0);
       
   404 
       
   405 	test.Next(_L("ATA drive: Format entire disk"));
       
   406 	TFormatInfo fi;
       
   407 	test.Printf(_L("Formatting "));
       
   408 	TInt ret;
       
   409 	while((ret=theAtaDrive.Format(fi))!=KErrEof)
       
   410 		{
       
   411 		ProgressBar((fi.i512ByteSectorsFormatted<<9),diskSize,11);
       
   412 		test(ret==KErrNone);
       
   413 		}
       
   414 	test.Printf(_L("\r\nReading    "));
       
   415 	for (i=0;i<diskSize;i+=len)
       
   416 		{
       
   417 		ProgressBar(i,diskSize,11);
       
   418 		len=Min(KAtaSectorSize,(diskSize-i));
       
   419 		rdBuf.Fill(0x55,len);
       
   420  		test(theAtaDrive.Read(i,len,rdBuf)==KErrNone);
       
   421 		wrBuf.SetLength(len);
       
   422   		test(rdBuf.Compare(wrBuf)==0);
       
   423 		}
       
   424 
       
   425 	TTime endTime;
       
   426 	endTime.HomeTime();
       
   427 	TTimeIntervalMicroSeconds elapsed=endTime.MicroSecondsFrom(startTime);
       
   428 	test.Printf(_L("   (Elapsed time: %dmS)\r\n"),(elapsed.Int64()/1000));
       
   429 
       
   430 	if (!mediaChangeSupported)
       
   431 		{
       
   432 		// Remainder of tests involve media change so stop now
       
   433 		test.End();
       
   434 		return(0);
       
   435 		}
       
   436 	
       
   437 	test.Next(_L("ATA drive: Media change"));
       
   438 #if defined (__WINS__)
       
   439 	test.Printf( _L("<<<Hit F5 - then any other key>>>\r\n"));
       
   440 #else
       
   441 	test.Printf( _L("<<<Generate Media change - then hit a key>>>\r\n"));
       
   442 #endif
       
   443 	test.Getch();
       
   444 	User::After(300000);	// Allow 0.3s after power down for controller to detect door closed.
       
   445 	test(ChangeFlag);
       
   446 //	test(UserHal::SupplyInfo(supply2)==KErrNone);
       
   447 //	test(supply2().iCurrentConsumptionMilliAmps==supply1().iCurrentConsumptionMilliAmps);
       
   448 	__KHEAP_MARK;
       
   449 
       
   450 	test.Next(_L("ATA drive: Caps following media change"));
       
   451 	test(theAtaDrive.Caps(infoPckg)==KErrNone);
       
   452 	test(info.iType==EMediaHardDisk);
       
   453 //	test(UserHal::SupplyInfo(supply2)==KErrNone);
       
   454 //	test(supply2().iCurrentConsumptionMilliAmps==supply1().iCurrentConsumptionMilliAmps+KAtaIdleCurrentInMilliAmps);
       
   455 
       
   456 	test.Next(_L("ATA drive: Caps while OOM"));
       
   457 	TInt err=KErrNoMemory;
       
   458 	test.Printf(_L("Mount returns:"));
       
   459 	for (TInt j=1; err!=KErrNone && j<16; j++)
       
   460 		{
       
   461 		theAtaDrive.ForceMediaChange();	// Generate media change
       
   462 		User::After(300000);	// Allow 0.3s after power down for controller to detect door closed.
       
   463 //		__KHEAP_MARK;
       
   464 		__KHEAP_SETFAIL(RHeap::EDeterministic,j);
       
   465 		err=theAtaDrive.Caps(infoPckg);
       
   466 		test.Printf(_L("(%d)"),err);
       
   467 		test(err==KErrNoMemory || err==KErrNone);
       
   468 //		__KHEAP_MARKEND;		// fails because card functions only released by media change or power down
       
   469 		__KHEAP_RESET;
       
   470 		}
       
   471 	test(err==KErrNone);
       
   472 	test.Printf(_L("\r\n"));
       
   473 	theAtaDrive.ForceMediaChange();	// Generate media change
       
   474 	User::After(300000);	// Allow 0.3s after power down for controller to detect door closed.
       
   475 	__KHEAP_MARKEND;		// test memory released after media change
       
   476 
       
   477 //	__KHEAP_MARK;
       
   478 	test.Next(_L("ATA drive: Caps before power off"));
       
   479 	test(theAtaDrive.Caps(infoPckg)==KErrNone);
       
   480 	test(info.iType==EMediaHardDisk);
       
   481 
       
   482 	test.Next(_L("ATA drive: Machine power-off."));
       
   483 	ChangeFlag=EFalse;
       
   484 	RTimer timer;
       
   485 	test(timer.CreateLocal()==KErrNone);
       
   486 	TRequestStatus timerStat;
       
   487 	TTime tim;
       
   488 	tim.HomeTime();
       
   489 	tim+=TTimeIntervalSeconds(8);
       
   490 	timer.At(timerStat,tim);
       
   491 	UserHal::SwitchOff();
       
   492 	User::WaitForRequest(timerStat);
       
   493 	test(!ChangeFlag);		// ie machine power off hasn't updated it
       
   494 	timer.Close();
       
   495 //	__KHEAP_MARKEND;		// test memory released on power off
       
   496 
       
   497 	test.Next(_L("ATA drive: Caps following power off"));
       
   498 	test(theAtaDrive.Caps(infoPckg)==KErrNone);
       
   499 	test(info.iType==EMediaHardDisk);
       
   500 
       
   501 	test.Next(_L("Starting 2nd thread"));
       
   502 	SecThreadChangeFlag=EFalse;
       
   503 	RThread thread;
       
   504 	TRequestStatus stat;
       
   505 	test(thread.Create(_L("Thread"),dontDisconnectThread,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone);
       
   506 	thread.Logon(stat);
       
   507 	thread.Resume();
       
   508 	User::WaitForRequest(stat);
       
   509 	test(stat==KErrNone);
       
   510 	CLOSE_AND_WAIT(thread);
       
   511 
       
   512 	test.Next(_L("ATA drive: 2nd media change"));
       
   513 	theAtaDrive.ForceMediaChange();		// Generate media change
       
   514 	test(ChangeFlag);
       
   515 	test(!SecThreadChangeFlag);	// Closed 2nd thread so shouldn't have been updated
       
   516 
       
   517 	b.Format(_L("Disconnect from local drive (%c:)"),DriveNumber+'C');
       
   518 	test.Next(b);
       
   519 	theAtaDrive.Disconnect();
       
   520 
       
   521 	test.End();
       
   522 
       
   523 #if defined (__WINS__)
       
   524 	for (i=0;i<KMaxLocalDrives;i++)
       
   525 		Drive[i].Disconnect();
       
   526 #endif
       
   527 	return(0);
       
   528 	}
       
   529