|
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 |