os/kernelhwsrv/kerneltest/e32test/pccd/t_atadrv.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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.iConnectionBusType==EConnectionBusInternal);
   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