1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/pccd/t_medch.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,372 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\pccd\t_medch.cpp
1.18 +// Continuously generate media changes followesd by a remount of the peripheral bus controller.
1.19 +//
1.20 +//
1.21 +
1.22 +#define __E32TEST_EXTENSION__
1.23 +#include <e32test.h>
1.24 +#include <e32svr.h>
1.25 +#include <hal.h>
1.26 +#include "d_medch.h"
1.27 +
1.28 +//#define __SOAK_TEST__ // Define to run until a key is pressed (Automatic tests only)
1.29 +//#define __MANUAL_TEST__ // Define to allow manual control of the door/media
1.30 +//#define __DEVICE_HAS_NO_DOOR__ // Define for devices that have no door (Manual tests only)
1.31 +
1.32 +#if defined(__MANUAL_TEST__) && defined(__WINS__)
1.33 +#define __DEVICE_HAS_NO_DOOR__
1.34 +#endif
1.35 +
1.36 +#if !defined(__MANUAL_TEST__) && defined(__DEVICE_HAS_NO_DOOR__)
1.37 +#undef __DEVICE_HAS_NO_DOOR__
1.38 +#endif
1.39 +
1.40 +#if defined(__MANUAL_TEST__) && defined(__SOAK_TEST__)
1.41 +#undef __SOAK_TEST__
1.42 +#endif
1.43 +
1.44 +#ifndef __SOAK_TEST__
1.45 +#ifdef __WINS__
1.46 +const TInt KMaxTestTime = 5000000; // Run the test for 5 seconds on emulator
1.47 +#else
1.48 +const TInt KMaxTestTime = 10000000; // Run the test for 10 seconds on target
1.49 +#endif
1.50 +#endif
1.51 +
1.52 +#define MMC_PDD_NAME _L("MEDMMC")
1.53 +
1.54 +const TInt KPowerUpTimeOut = 5000000; // Give the card 5 seconds to power up
1.55 +
1.56 +LOCAL_D RTest test(_L("Media change test"));
1.57 +
1.58 +LOCAL_D TBusLocalDrive TheDrive;
1.59 +LOCAL_D RMedCh TheMediaChange;
1.60 +LOCAL_D TRequestStatus TheMediaStatus;
1.61 +LOCAL_D TBool TheChangedFlag;
1.62 +
1.63 +
1.64 +LOCAL_C TBool SetupDrivesForPlatform(TInt& aDrive, TInt& aSocket)
1.65 +/**
1.66 + * Finds a suitable drive for the media change test
1.67 + *
1.68 + * @param aDrive The number of the local drive to test
1.69 + * @param aSocket The number of the socket to test
1.70 + * @return TBool ETrue if a suitable drive is found, EFalse otherwise.
1.71 + */
1.72 + {
1.73 +
1.74 + TDriveInfoV1Buf diBuf;
1.75 + UserHal::DriveInfo(diBuf);
1.76 + TDriveInfoV1 &di=diBuf();
1.77 +
1.78 + aDrive = -1;
1.79 + aSocket = -1;
1.80 +
1.81 + for(aDrive=0; aDrive < di.iTotalSupportedDrives; aDrive++)
1.82 + {
1.83 + test.Printf(_L(" Drive %d - %S\r\n"), aDrive, &di.iDriveName[aDrive]);
1.84 + if(di.iDriveName[aDrive].MatchF(_L("MultiMediaCard0")) == KErrNone)
1.85 + break;
1.86 + }
1.87 +
1.88 + if(aDrive == di.iTotalSupportedDrives)
1.89 + {
1.90 + test.Printf(_L(" MMC Drive Not Found\r\n"));
1.91 + return EFalse;
1.92 + }
1.93 +
1.94 +
1.95 + for(aSocket=0; aSocket < di.iTotalSockets; aSocket++)
1.96 + {
1.97 + test.Printf(_L("Socket %d - %S\r\n"), aSocket, &di.iSocketName[aSocket]);
1.98 + if(di.iSocketName[aSocket].MatchF(_L("MultiMediaCard0")) == KErrNone)
1.99 + break;
1.100 + }
1.101 +
1.102 + if(aSocket == di.iTotalSockets)
1.103 + {
1.104 + test.Printf(_L(" MMC Socket Not Found\r\n"));
1.105 + return EFalse;
1.106 + }
1.107 +
1.108 + return ETrue;
1.109 + }
1.110 +
1.111 +LOCAL_C void TestMediaAccess(TInt aExpectedError, TBool aExpectedChange)
1.112 +/**
1.113 + * Tests that the drive is accessable (or not) by issuing a request
1.114 + * to power up the media. Also verifies that the attributes are correct.
1.115 + *
1.116 + * @param aExpectedError The expected result of powering up the drive
1.117 + * @param aExpectedChange ETrue if the changed flag is expected to be set
1.118 + *
1.119 + * @return ETrue if successful, EFalse otherwise
1.120 + */
1.121 + {
1.122 +
1.123 + RTimer rto;
1.124 + TInt r = rto.CreateLocal();
1.125 + test(r == KErrNone);
1.126 +
1.127 + TRequestStatus rtoStat;
1.128 + rto.After(rtoStat, KPowerUpTimeOut);
1.129 + test(rtoStat == KRequestPending);
1.130 +
1.131 + if(aExpectedChange)
1.132 + {
1.133 + // TheChangedFlag is set when the door is opened if media was present.
1.134 + // The asynch notifier is signalled when media is removed OR inserted.
1.135 + User::WaitForRequest(TheMediaStatus, rtoStat);
1.136 + test(TheMediaStatus != KRequestPending);
1.137 + }
1.138 +
1.139 + // ...aChangedFlag's purpose is to notify us of media removal.
1.140 + test_Equal(aExpectedChange,TheChangedFlag);
1.141 +
1.142 + TheDrive.NotifyChange(&TheMediaStatus);
1.143 + TheChangedFlag = EFalse;
1.144 +
1.145 + // Attempt to power up the drive
1.146 + TLocalDriveCapsV2Buf info;
1.147 + do
1.148 + {
1.149 + r = TheDrive.Caps(info);
1.150 + }
1.151 + while(r != aExpectedError && rtoStat == KRequestPending);
1.152 +
1.153 + rto.Cancel();
1.154 + rto.Close();
1.155 +
1.156 + // ...was the error as expected?
1.157 + test(r == aExpectedError);
1.158 +
1.159 + // ...and are the caps still OK?
1.160 + if(r == KErrNone)
1.161 + test(info().iType == EMediaHardDisk);
1.162 + else if(r == KErrNotReady)
1.163 + test(info().iType == EMediaNotPresent);
1.164 +
1.165 + if(aExpectedChange == EFalse)
1.166 + test(TheMediaStatus == KRequestPending);
1.167 + }
1.168 +
1.169 +LOCAL_C void NextTest(const TDesC& aTitle, TInt aCycles)
1.170 +/**
1.171 + * Simply displays a string on the console and the current iteration.
1.172 + *
1.173 + * @param aTitle The text to be displayed
1.174 + * @param aCycles The current iteration
1.175 + */
1.176 + {
1.177 + test.Console()->SetPos(20, 25);
1.178 + test.Printf(_L("%S [%d cycles]"), &aTitle, aCycles);
1.179 +#ifdef __MANUAL_TEST__
1.180 + test.Console()->SetPos(20, 27);
1.181 + test.Printf(_L("<press a key>"));
1.182 + test.Getch();
1.183 +#endif
1.184 + }
1.185 +
1.186 +GLDEF_C TInt E32Main()
1.187 +/**
1.188 + * Test Entry Point for T_MEDCH.
1.189 + *
1.190 + * This test uses the associated driver (D_MEDCH) to simulate media removal and
1.191 + * door opening/closing. The media is powered up in each state and verified that
1.192 + * the correct error code and changed count is returned.
1.193 + */
1.194 + {
1.195 + TBuf<64> b;
1.196 + test.Title();
1.197 +
1.198 + /**
1.199 + * Load the associated media driver (MEDMMC by default). This is required to ensure
1.200 + * that the device can be powered up and the capabilities if the media accessed.
1.201 + */
1.202 + test.Start(_L("Load Media Driver"));
1.203 + TInt r;
1.204 + r=User::LoadPhysicalDevice(MMC_PDD_NAME);
1.205 + if(r==KErrNotFound)
1.206 + {
1.207 + test.Printf(_L("Test not supported on this platform \n"));
1.208 + test.End();
1.209 + return(0);
1.210 + }
1.211 + test(r==KErrNone || r==KErrAlreadyExists);
1.212 +
1.213 + /**
1.214 + * Connect to the required local drive.
1.215 + * TheChangedFlag is used for detection of media removal.
1.216 + */
1.217 + TInt drive;
1.218 + TInt socket;
1.219 + if(SetupDrivesForPlatform(drive, socket))
1.220 + {
1.221 + b.Format(_L("Connect to local drive %d"), drive);
1.222 + test.Next(b);
1.223 + TheDrive.Connect(drive, TheChangedFlag);
1.224 +
1.225 + /**
1.226 + * Read the drive capabilities to ensure that this test may be run.
1.227 + */
1.228 + test.Next(_L("Get drive capabilities"));
1.229 + TLocalDriveCapsV2Buf info;
1.230 + r = TheDrive.Caps(info);
1.231 + if(r == KErrNotReady || r == KErrNotSupported)
1.232 + {
1.233 + test.Next(_L("\r\nTest requires media to be present and the door closed - Disconnecting"));
1.234 + TheDrive.Disconnect();
1.235 + test.End();
1.236 + return KErrNone;
1.237 + }
1.238 + test(r == KErrNone);
1.239 +
1.240 + test(TheDrive.Caps(info) == KErrNone);
1.241 + test(info().iType == EMediaHardDisk);
1.242 +
1.243 + /**
1.244 + * Load the media simulation test driver
1.245 + */
1.246 + test.Next(_L("Load media change logical device"));
1.247 + r=User::LoadLogicalDevice(_L("D_MEDCH"));
1.248 + test(r == KErrNone || r == KErrAlreadyExists);
1.249 +
1.250 + test.Next(_L("Open device"));
1.251 + r=TheMediaChange.Open(socket, TheMediaChange.VersionRequired());
1.252 + if(r == KErrNotSupported)
1.253 + {
1.254 + test.Next(_L("\r\nTest not supported on this drive - Disconnecting"));
1.255 + r=User::FreeLogicalDevice(_L("MedCh"));
1.256 + test(r == KErrNone);
1.257 + TheDrive.Disconnect();
1.258 + test.End();
1.259 + return KErrNone;
1.260 + }
1.261 + test(r == KErrNone);
1.262 +
1.263 + /**
1.264 + * Verify that the system supports simulation of media change events
1.265 + */
1.266 + test.Next(_L("Test support for media change simulation"));
1.267 + r = TheMediaChange.DoorNormal();
1.268 + test(r == KErrNone || r == KErrNotSupported);
1.269 +
1.270 + /**
1.271 + * Now for the real testing...
1.272 + */
1.273 + if(r == KErrNone)
1.274 + {
1.275 + /**
1.276 + * Test0 - Simulate 2 consecutive door open interrupts
1.277 + */
1.278 + test.Next(_L("Test that the pbus can handle 2 consecutive door open interrupts"));
1.279 + TheDrive.NotifyChange(&TheMediaStatus);
1.280 + r = TheMediaChange.DoubleDoorOpen();
1.281 + test(r == KErrNone || r == KErrNotSupported);
1.282 + TestMediaAccess(KErrNone, ETrue);
1.283 +
1.284 +
1.285 + TInt cycles=0;
1.286 +#if defined(__SOAK_TEST__)
1.287 + TRequestStatus endStat;
1.288 + test.Console()->Read(endStat);
1.289 + while(endStat == KRequestPending)
1.290 +#elif !defined(__MANUAL_TEST__)
1.291 + RTimer t;
1.292 + r=t.CreateLocal();
1.293 + test(r == KErrNone);
1.294 + TRequestStatus endStat;
1.295 + t.After(endStat, KMaxTestTime);
1.296 + test(endStat == KRequestPending);
1.297 + while(endStat == KRequestPending)
1.298 +#endif
1.299 + {
1.300 + TheChangedFlag = EFalse;
1.301 +
1.302 + TheDrive.NotifyChange(&TheMediaStatus);
1.303 +
1.304 + /**
1.305 + * Test1 - Simulate door open
1.306 + * - Power up responds with KErrNotReady
1.307 + */
1.308 + NextTest(_L("Open Door......"), cycles);
1.309 +#ifndef __MANUAL_TEST__
1.310 + test(TheMediaChange.DoorOpen() == KErrNone);
1.311 +#endif
1.312 + TestMediaAccess(KErrNotReady, ETrue);
1.313 + TheDrive.NotifyChange(&TheMediaStatus);
1.314 +
1.315 + /**
1.316 + * Test2 - Simulate door closed (with media removed)
1.317 + * - Power up responds with KErrNotReady
1.318 + */
1.319 +#ifndef __DEVICE_HAS_NO_DOOR__
1.320 + NextTest(_L("Remove Media..."), cycles);
1.321 +#ifndef __MANUAL_TEST__
1.322 + test(TheMediaChange.DoorClose(EFalse) == KErrNone);
1.323 +#endif
1.324 + TestMediaAccess(KErrNotReady, EFalse);
1.325 + /**
1.326 + * Test3 - Simulate door open
1.327 + * - Power up responds with KErrNotReady
1.328 + */
1.329 + NextTest(_L("Open Door......"), cycles);
1.330 +#ifndef __MANUAL_TEST__
1.331 + test(TheMediaChange.DoorOpen() == KErrNone);
1.332 +#endif
1.333 + TestMediaAccess(KErrNotReady, EFalse); // Power up responds with KErrNotReady
1.334 +#endif
1.335 + /**
1.336 + * Test4 - Simulate door closed (with media present)
1.337 + * - Power up responds with KErrNone
1.338 + */
1.339 + NextTest(_L("Insert Media..."), cycles);
1.340 +#ifndef __MANUAL_TEST__
1.341 + test(TheMediaChange.DoorClose(ETrue) == KErrNone);
1.342 +#endif
1.343 + TestMediaAccess(KErrNone, ETrue);
1.344 + ++cycles;
1.345 + }
1.346 +
1.347 + test.Console()->SetPos(0, 27);
1.348 +#if !defined(__SOAK_TEST__) && !defined(__MANUAL_TEST__)
1.349 + t.Close();
1.350 +#endif
1.351 + }
1.352 + else if(r == KErrNotSupported)
1.353 + {
1.354 + test.Printf(_L("Media change simulation not supported"));
1.355 + }
1.356 +
1.357 + /**
1.358 + * Tidy up and exit
1.359 + */
1.360 + test.Next(_L("\r\nClose device"));
1.361 + TheMediaChange.Close();
1.362 +
1.363 + test.Next(_L("Free device"));
1.364 + r=User::FreeLogicalDevice(_L("MedCh"));
1.365 + test(r == KErrNone);
1.366 +
1.367 + b.Format(_L("\r\nDisconnect from local drive %d "), drive);
1.368 + test.Next(b);
1.369 + TheDrive.Disconnect();
1.370 + }
1.371 +
1.372 + test.End();
1.373 + return(0);
1.374 + }
1.375 +