os/kernelhwsrv/kerneltest/e32test/pccd/t_medch.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1997-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_medch.cpp
    15 // Continuously generate media changes followesd by a remount of the peripheral bus controller.
    16 // 
    17 //
    18 
    19 #define __E32TEST_EXTENSION__
    20 #include <e32test.h>
    21 #include <e32svr.h>
    22 #include <hal.h>
    23 #include "d_medch.h"
    24 
    25 //#define __SOAK_TEST__				// Define to run until a key is pressed (Automatic tests only)
    26 //#define __MANUAL_TEST__			// Define to allow manual control of the door/media
    27 //#define __DEVICE_HAS_NO_DOOR__	// Define for devices that have no door (Manual tests only)
    28 
    29 #if defined(__MANUAL_TEST__) && defined(__WINS__)
    30 #define __DEVICE_HAS_NO_DOOR__
    31 #endif
    32 
    33 #if !defined(__MANUAL_TEST__) && defined(__DEVICE_HAS_NO_DOOR__)
    34 #undef __DEVICE_HAS_NO_DOOR__
    35 #endif
    36 
    37 #if defined(__MANUAL_TEST__) && defined(__SOAK_TEST__)
    38 #undef __SOAK_TEST__
    39 #endif
    40 
    41 #ifndef __SOAK_TEST__
    42 #ifdef __WINS__
    43 const TInt KMaxTestTime	=  5000000;	// Run the test for 5 seconds on emulator
    44 #else
    45 const TInt KMaxTestTime	= 10000000;	// Run the test for 10 seconds on target
    46 #endif
    47 #endif
    48 
    49 #define MMC_PDD_NAME _L("MEDMMC")
    50 
    51 const TInt KPowerUpTimeOut = 5000000; // Give the card 5 seconds to power up
    52 
    53 LOCAL_D	RTest test(_L("Media change test"));
    54 
    55 LOCAL_D	TBusLocalDrive TheDrive;
    56 LOCAL_D	RMedCh TheMediaChange;
    57 LOCAL_D TRequestStatus TheMediaStatus;
    58 LOCAL_D TBool TheChangedFlag;
    59 
    60 
    61 LOCAL_C TBool SetupDrivesForPlatform(TInt& aDrive, TInt& aSocket)
    62 /**
    63  * Finds a suitable drive for the media change test
    64  *
    65  * @param aDrive  The number of the local drive to test
    66  * @param aSocket The number of the socket to test
    67  * @return TBool ETrue if a suitable drive is found, EFalse otherwise.
    68  */
    69 	{
    70 	
    71 	TDriveInfoV1Buf diBuf;
    72 	UserHal::DriveInfo(diBuf);
    73 	TDriveInfoV1 &di=diBuf();
    74 
    75 	aDrive  = -1;
    76 	aSocket = -1;
    77 	
    78 	for(aDrive=0; aDrive < di.iTotalSupportedDrives; aDrive++)
    79 		{
    80 		test.Printf(_L(" Drive %d - %S\r\n"), aDrive, &di.iDriveName[aDrive]);
    81 		if(di.iDriveName[aDrive].MatchF(_L("MultiMediaCard0")) == KErrNone)
    82 			break;
    83 		}
    84 
    85 	if(aDrive == di.iTotalSupportedDrives)
    86 		{
    87 		test.Printf(_L(" MMC Drive Not Found\r\n"));
    88 		return EFalse;
    89 		}
    90 		
    91 	
    92 	for(aSocket=0; aSocket < di.iTotalSockets; aSocket++)
    93 		{
    94 		test.Printf(_L("Socket %d - %S\r\n"), aSocket, &di.iSocketName[aSocket]);
    95 		if(di.iSocketName[aSocket].MatchF(_L("MultiMediaCard0")) == KErrNone)
    96 			break;
    97 		}
    98 
    99 	if(aSocket == di.iTotalSockets)
   100 		{
   101 		test.Printf(_L(" MMC Socket Not Found\r\n"));
   102 		return EFalse;
   103 		}
   104 
   105 	return ETrue;
   106 	}
   107 
   108 LOCAL_C void TestMediaAccess(TInt aExpectedError, TBool aExpectedChange)
   109 /**
   110  * Tests that the drive is accessable (or not) by issuing a request 
   111  * to power up the media.  Also verifies that the attributes are correct.
   112  * 
   113  * @param aExpectedError The expected result of powering up the drive
   114  * @param aExpectedChange ETrue if the changed flag is expected to be set
   115  *
   116  * @return ETrue if successful, EFalse otherwise
   117  */
   118 	{
   119 	
   120 	RTimer rto;
   121 	TInt r = rto.CreateLocal();
   122 	test(r == KErrNone);
   123 	
   124 	TRequestStatus rtoStat;
   125 	rto.After(rtoStat, KPowerUpTimeOut);
   126 	test(rtoStat == KRequestPending);
   127 	
   128 	if(aExpectedChange)
   129 		{
   130 		// TheChangedFlag is set when the door is opened if media was present.
   131 		// The asynch notifier is signalled when media is removed OR inserted.
   132 		User::WaitForRequest(TheMediaStatus, rtoStat);
   133 		test(TheMediaStatus != KRequestPending);
   134 		}
   135 
   136 	// ...aChangedFlag's purpose is to notify us of media removal.
   137 	test_Equal(aExpectedChange,TheChangedFlag);
   138 
   139 	TheDrive.NotifyChange(&TheMediaStatus);
   140 	TheChangedFlag = EFalse;
   141 
   142 	// Attempt to power up the drive
   143 	TLocalDriveCapsV2Buf info;
   144 	do
   145 		{
   146 		r = TheDrive.Caps(info);
   147 		}
   148 	while(r != aExpectedError && rtoStat == KRequestPending);
   149 
   150 	rto.Cancel();
   151 	rto.Close();
   152 
   153 	// ...was the error as expected?
   154 	test(r == aExpectedError);
   155 
   156 	// ...and are the caps still OK?
   157 	if(r == KErrNone)
   158 		test(info().iType == EMediaHardDisk);
   159 	else if(r == KErrNotReady)
   160 		test(info().iType == EMediaNotPresent);
   161 
   162 	if(aExpectedChange == EFalse)
   163 		test(TheMediaStatus == KRequestPending);
   164 	}
   165 
   166 LOCAL_C void NextTest(const TDesC& aTitle, TInt aCycles)
   167 /**
   168  * Simply displays a string on the console and the current iteration.
   169  * 
   170  * @param aTitle  The text to be displayed
   171  * @param aCycles The current iteration
   172  */
   173 	{
   174 	test.Console()->SetPos(20, 25);
   175 	test.Printf(_L("%S [%d cycles]"), &aTitle, aCycles);
   176 #ifdef __MANUAL_TEST__
   177 	test.Console()->SetPos(20, 27);
   178 	test.Printf(_L("<press a key>"));
   179 	test.Getch();
   180 #endif
   181 	}
   182 		
   183 GLDEF_C TInt E32Main()
   184 /**
   185  * Test Entry Point for T_MEDCH.
   186  * 
   187  * This test uses the associated driver (D_MEDCH) to simulate media removal and 
   188  * door opening/closing.  The media is powered up in each state and verified that 
   189  * the correct error code and changed count is returned.
   190  */
   191     {
   192 	TBuf<64> b;
   193 	test.Title();
   194 
   195 	/**
   196 	 * Load the associated media driver (MEDMMC by default).  This is required to ensure 
   197 	 * that the device can be powered up and the capabilities if the media accessed.
   198 	 */
   199 	test.Start(_L("Load Media Driver"));
   200 	TInt r;
   201 	r=User::LoadPhysicalDevice(MMC_PDD_NAME);
   202 	if(r==KErrNotFound)
   203 		{
   204 		test.Printf(_L("Test not supported on this platform \n"));
   205 		test.End();
   206 		return(0);
   207 		}
   208 	test(r==KErrNone || r==KErrAlreadyExists);
   209 
   210 	/**
   211 	 * Connect to the required local drive.
   212 	 * TheChangedFlag is used for detection of media removal.
   213 	 */
   214 	TInt drive;
   215 	TInt socket;
   216 	if(SetupDrivesForPlatform(drive, socket))
   217 		{
   218 		b.Format(_L("Connect to local drive %d"), drive);
   219 		test.Next(b);
   220 		TheDrive.Connect(drive, TheChangedFlag);
   221 	
   222 		/**
   223 		 * Read the drive capabilities to ensure that this test may be run.
   224 		 */
   225 		test.Next(_L("Get drive capabilities"));
   226 		TLocalDriveCapsV2Buf info;
   227 		r = TheDrive.Caps(info);
   228 		if(r == KErrNotReady || r == KErrNotSupported)
   229 			{
   230 			test.Next(_L("\r\nTest requires media to be present and the door closed - Disconnecting"));
   231 			TheDrive.Disconnect();		
   232 			test.End();
   233 			return KErrNone;
   234 			}	
   235 		test(r == KErrNone);
   236 	
   237 		test(TheDrive.Caps(info) == KErrNone);
   238 		test(info().iType == EMediaHardDisk);
   239 	
   240 		/**
   241 		 * Load the media simulation test driver
   242 		 */
   243 		test.Next(_L("Load media change logical device"));
   244 		r=User::LoadLogicalDevice(_L("D_MEDCH"));
   245 		test(r == KErrNone || r == KErrAlreadyExists);
   246 	
   247 		test.Next(_L("Open device"));
   248 		r=TheMediaChange.Open(socket, TheMediaChange.VersionRequired());
   249 		if(r == KErrNotSupported)
   250 			{
   251 			test.Next(_L("\r\nTest not supported on this drive - Disconnecting"));
   252 			r=User::FreeLogicalDevice(_L("MedCh"));
   253 			test(r == KErrNone);
   254 			TheDrive.Disconnect();
   255 			test.End();
   256 			return KErrNone;
   257 			}	
   258 		test(r == KErrNone);
   259 	
   260 		/**
   261 		 * Verify that the system supports simulation of media change events
   262 		 */
   263 		test.Next(_L("Test support for media change simulation"));
   264 		r = TheMediaChange.DoorNormal();
   265 		test(r == KErrNone || r == KErrNotSupported);
   266 	
   267 		/**
   268 		 * Now for the real testing...
   269 		 */
   270 		if(r == KErrNone)
   271 			{
   272 			/**
   273 	    	 * Test0 - Simulate 2 consecutive door open interrupts
   274 			 */
   275 			test.Next(_L("Test that the pbus can handle 2 consecutive door open interrupts"));
   276 			TheDrive.NotifyChange(&TheMediaStatus);
   277 			r = TheMediaChange.DoubleDoorOpen();
   278 			test(r == KErrNone || r == KErrNotSupported);
   279 			TestMediaAccess(KErrNone, ETrue);
   280 		
   281 
   282 			TInt cycles=0;
   283 #if defined(__SOAK_TEST__)
   284 			TRequestStatus endStat;
   285 			test.Console()->Read(endStat);
   286 			while(endStat == KRequestPending)
   287 #elif !defined(__MANUAL_TEST__)
   288 			RTimer t;
   289 			r=t.CreateLocal();
   290 			test(r == KErrNone);
   291 			TRequestStatus endStat;
   292 			t.After(endStat, KMaxTestTime);
   293 			test(endStat == KRequestPending);
   294 			while(endStat == KRequestPending)
   295 #endif
   296 				{
   297 				TheChangedFlag = EFalse;
   298 	
   299 				TheDrive.NotifyChange(&TheMediaStatus);
   300 	
   301 				/**
   302 	    		 * Test1 - Simulate door open
   303 				 *		 - Power up responds with KErrNotReady
   304 				 */
   305 				NextTest(_L("Open Door......"), cycles);
   306 #ifndef __MANUAL_TEST__
   307 				test(TheMediaChange.DoorOpen() == KErrNone);
   308 #endif
   309 				TestMediaAccess(KErrNotReady, ETrue);
   310 				TheDrive.NotifyChange(&TheMediaStatus);
   311 	
   312 				/**
   313 	    		 * Test2 - Simulate door closed (with media removed)
   314 				 *		 - Power up responds with KErrNotReady
   315 				 */
   316 #ifndef __DEVICE_HAS_NO_DOOR__
   317 	    		NextTest(_L("Remove Media..."), cycles);
   318 #ifndef __MANUAL_TEST__
   319 				test(TheMediaChange.DoorClose(EFalse) == KErrNone);		
   320 #endif
   321 				TestMediaAccess(KErrNotReady, EFalse);					
   322 				/**
   323 	    		 * Test3 - Simulate door open
   324 				 *		 - Power up responds with KErrNotReady
   325 				 */
   326 				NextTest(_L("Open Door......"), cycles);
   327 #ifndef __MANUAL_TEST__
   328 				test(TheMediaChange.DoorOpen() == KErrNone);			
   329 #endif
   330 				TestMediaAccess(KErrNotReady, EFalse);				// Power up responds with KErrNotReady
   331 #endif
   332 				/**
   333 	    		 * Test4 - Simulate door closed (with media present)
   334 				 *		 - Power up responds with KErrNone
   335 				 */
   336 	    		NextTest(_L("Insert Media..."), cycles);
   337 #ifndef __MANUAL_TEST__
   338 				test(TheMediaChange.DoorClose(ETrue) == KErrNone);
   339 #endif
   340 				TestMediaAccess(KErrNone, ETrue);
   341 				++cycles;
   342 				}
   343 	
   344 			test.Console()->SetPos(0, 27);
   345 #if !defined(__SOAK_TEST__) && !defined(__MANUAL_TEST__)
   346 			t.Close();
   347 #endif
   348 			}
   349 		else if(r == KErrNotSupported)
   350 			{
   351 			test.Printf(_L("Media change simulation not supported"));
   352 			}
   353 	
   354 		/**
   355 		 * Tidy up and exit
   356 		 */
   357 		test.Next(_L("\r\nClose device"));
   358 		TheMediaChange.Close();
   359 	
   360 		test.Next(_L("Free device"));
   361 		r=User::FreeLogicalDevice(_L("MedCh"));
   362 		test(r == KErrNone);
   363 	
   364 		b.Format(_L("\r\nDisconnect from local drive %d "), drive);
   365 		test.Next(b);
   366 		TheDrive.Disconnect();
   367 		}
   368 
   369 	test.End();
   370 	return(0);
   371 	}
   372