|
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_mmcdrv.cpp |
|
15 // Test the MultiMediaCard (MMC) media driver |
|
16 // Spare Test case Numbers 0513-0519 |
|
17 // |
|
18 // |
|
19 |
|
20 #include "../mmu/d_sharedchunk.h" |
|
21 #include <e32test.h> |
|
22 #include <e32svr.h> |
|
23 #include <e32hal.h> |
|
24 #include <e32uid.h> |
|
25 #include <f32fsys.h> |
|
26 #include <e32def.h> |
|
27 #include <e32def_private.h> |
|
28 |
|
29 const TInt KDiskSectorSize=512; |
|
30 const TInt KDiskSectorShift=9; |
|
31 const TUint KDiskSectorMask=0xFFFFFE00; |
|
32 const TInt KSectBufSizeInSectors=8; |
|
33 const TInt KSectBufSizeInBytes=(KSectBufSizeInSectors<<KDiskSectorShift); |
|
34 const TInt KRdWrBufLen=(KSectBufSizeInBytes+KDiskSectorSize); // 4.5K - exceeds driver local buffer size |
|
35 |
|
36 const TInt KShortFormatInSectors=1; |
|
37 const TInt KShortFormatInBytes=(KShortFormatInSectors<<KDiskSectorShift); |
|
38 const TInt KLongFormatInSectors=KSectBufSizeInSectors+1; // 4.5K - exceeds driver local buffer size |
|
39 const TInt KLongFormatInBytes=(KLongFormatInSectors<<KDiskSectorShift); |
|
40 |
|
41 const TInt KVeryLongSectBufSizeInSectors=4096; // ..2M |
|
42 const TInt KVeryLongSectBufSizeInBytes=(KVeryLongSectBufSizeInSectors<<KDiskSectorShift); // |
|
43 const TInt KVeryLongRdWrBufLen=(KVeryLongSectBufSizeInBytes+KDiskSectorSize); // 2M + 0.5K |
|
44 |
|
45 const TInt KHeapSize=0x4000; |
|
46 |
|
47 const TInt64 KDefaultRandSeed = MAKE_TINT64(0x501a501a, 0x501a501a); |
|
48 |
|
49 #define TEST_DOOR_CLOSE 0 // see comment in E32Main() |
|
50 |
|
51 |
|
52 class TMMCDrive : public TBusLocalDrive |
|
53 { |
|
54 public: |
|
55 enum TTestMode |
|
56 { |
|
57 ETestPartition, |
|
58 ETestWholeMedia, |
|
59 ETestSharedMemory, |
|
60 ETestSharedMemoryCache, |
|
61 ETestSharedMemoryFrag, |
|
62 ETestSharedMemoryFragCache, |
|
63 EMaxTestModes |
|
64 }; |
|
65 public: |
|
66 TMMCDrive(); |
|
67 |
|
68 TInt Read(TInt64 aPos, TInt aLength, TDes8& aTrg); |
|
69 TInt Write(TInt64 aPos, const TDesC8& aSrc); |
|
70 |
|
71 TInt SetTestMode(TTestMode aTestMode); |
|
72 TTestMode TestMode(); |
|
73 |
|
74 void SetSize(TInt64 aDriveSize, TInt64 aMediaSize); |
|
75 TInt64 Size(); |
|
76 private: |
|
77 TTestMode iTestMode; |
|
78 |
|
79 TInt64 iDriveSize; |
|
80 TInt64 iMediaSize; |
|
81 }; |
|
82 |
|
83 // Serial numbers for 'special case' test cards (ie - those with known problems) |
|
84 class TKnownCardTypes |
|
85 { |
|
86 public: |
|
87 enum TCardType |
|
88 { |
|
89 EStandardCard = 0, |
|
90 EBuffalloMiniSD_32M_ERASE, |
|
91 EBuffalloMiniSD_64M_ERASE, |
|
92 EBuffalloMiniSD_128M_ERASE, |
|
93 EBuffalloMiniSD_256M_ERASE, |
|
94 EBuffalloMiniSD_512M_ERASE, |
|
95 EBuffalloMiniSD_512M, |
|
96 EIntegralHSSD_2G, |
|
97 ESanDiskMmcMobile_1GB |
|
98 }; |
|
99 |
|
100 TKnownCardTypes(TCardType aCardType, const TText8* aSerialNumber) |
|
101 : iCardType(aCardType), iSerialNumber(aSerialNumber) {}; |
|
102 |
|
103 TCardType iCardType; |
|
104 const TText8* iSerialNumber; |
|
105 }; |
|
106 |
|
107 LOCAL_D TKnownCardTypes KnownCardTypes[] = |
|
108 { |
|
109 //** The Following Buffalo Cards all have a known Mis-Implementation |
|
110 // When requesting Erase the area to be erase is specified in terms of a start (CMD32) and stop (CMD33) blocks |
|
111 // Specification states that CMD33 refers to the end block in terms of the first byte of that block |
|
112 // the Buffallo implementation requires that the last byte of the block is specified. |
|
113 |
|
114 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_32M_ERASE, _S8("936300c70e150d003630333046445004")), |
|
115 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_64M_ERASE, _S8("d96600456d120a003732343046445004")), |
|
116 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_128M_ERASE, _S8("f964000d13150c003630333046445004")), |
|
117 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_256M_ERASE, _S8("4d66004c68120a003732343046445004")), |
|
118 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M_ERASE, _S8("db6500824e0010013236333243454228")), |
|
119 |
|
120 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_32M_ERASE, _S8("df6400e60d150d003630333046445004")), |
|
121 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_64M_ERASE, _S8("296600386d120a003732343046445004")), |
|
122 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_128M_ERASE, _S8("b16400f512150c003630333046445004")), |
|
123 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_256M_ERASE, _S8("435600cc390000000000004453474b13")), |
|
124 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M_ERASE, _S8("ed6300de700000000000004453474b13")), |
|
125 //***********************************************************************************************// |
|
126 |
|
127 TKnownCardTypes(TKnownCardTypes::EBuffalloMiniSD_512M, _S8("0d56004e2d0000000000004453474b13")), |
|
128 TKnownCardTypes(TKnownCardTypes::EIntegralHSSD_2G, _S8("37570058073099114732304453000027")), |
|
129 TKnownCardTypes(TKnownCardTypes::ESanDiskMmcMobile_1GB,_S8("956a1c00001810303030303030000015")) |
|
130 }; |
|
131 |
|
132 |
|
133 LOCAL_D RTest test(_L("T_MMCDRV")); |
|
134 LOCAL_D RTest nTest(_L("This thread doesn't disconnect")); |
|
135 LOCAL_D TBool ChangeFlag; |
|
136 LOCAL_D TBool SecThreadChangeFlag; |
|
137 |
|
138 |
|
139 LOCAL_D TPtr8 wrBuf(NULL, KVeryLongRdWrBufLen); |
|
140 LOCAL_D TPtr8 rdBuf(NULL, KVeryLongRdWrBufLen); |
|
141 LOCAL_D HBufC8* wrBufH = NULL; |
|
142 LOCAL_D HBufC8* rdBufH = NULL; |
|
143 |
|
144 LOCAL_D TInt DriveNumber = -1; // Local Drive number |
|
145 LOCAL_D TInt RFsDNum = -1; // File Server Drive number |
|
146 LOCAL_D TMMCDrive TheMmcDrive; |
|
147 LOCAL_D TLocalDriveCapsV5Buf DriveCaps; |
|
148 LOCAL_D TKnownCardTypes::TCardType CardType; |
|
149 LOCAL_D TBool IsReadOnly; |
|
150 |
|
151 LOCAL_D RSharedChunkLdd Ldd; |
|
152 LOCAL_D RChunk TheChunk; |
|
153 LOCAL_D TInt PageSize; |
|
154 const TUint ChunkSize = 0x201000; //2MB+4096bytes > than largest transfer |
|
155 |
|
156 const TInt KSingSectorNo=1; |
|
157 const TInt64 KTwoGigbytes = 0x80000000; |
|
158 |
|
159 TBool mediaChangeSupported=EFalse; // ??? |
|
160 TBool ManualMode=EFalse; |
|
161 |
|
162 // Wrappers for the test asserts |
|
163 GLREF_C void TestIfError( TInt aValue, TInt aLine, const TText* aFile ); |
|
164 GLREF_C void TestIfErrorMsg( TInt aValue, TInt aLine, const TText* aFile, const TDesC& aMessageOnError ); |
|
165 GLREF_C void TestEqual( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile ); |
|
166 GLREF_C void TestEqualMsg( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile, const TDesC& aMessageOnError ); |
|
167 GLREF_C void TestEitherEqual( TInt aValue, TInt aExpected1, TInt aExpected2, TInt aLine, const TText* aFile ); |
|
168 GLREF_C void TestRange( TInt aValue, TInt aMin, TInt Max, TInt aLine, const TText* aFile ); |
|
169 |
|
170 #define TEST_FOR_ERROR2( r, l, f ) TestIfError( r, l, _S(f) ) |
|
171 #define TEST_FOR_ERROR_ERRMSG2( r, l, f, m ) TestIfErrorMsg( r, l, _S(f), m ) |
|
172 #define TEST_FOR_VALUE2( r, e, l, f ) TestEqual( r, e, l, _S(f) ) |
|
173 #define TEST_FOR_VALUE_ERRMSG2( r, e, l, f, m ) TestEqualMsg( r, e, l, _S(f), m ) |
|
174 #define TEST_FOR_EITHER_VALUE2( r, e1, e2, l, f ) TestEitherEqual( r, e1, e2, l, _S(f) ) |
|
175 #define TEST_FOR_RANGE2( r, min, max, l, f ) TestRange( r, min, max, l, _S(f) ) |
|
176 |
|
177 #define TEST_FOR_ERROR( r ) TEST_FOR_ERROR2( r, __LINE__, __FILE__ ) |
|
178 #define TEST_FOR_ERROR_ERRMSG( r, m ) TEST_FOR_ERRORMSG2( r, __LINE__, __FILE__, m ) |
|
179 #define TEST_FOR_VALUE( r, expected ) TEST_FOR_VALUE2( r, expected, __LINE__, __FILE__ ) |
|
180 #define TEST_FOR_VALUE_ERRMSG( r, expected, m ) TEST_FOR_VALUE_ERRMSG2( r, expected, __LINE__, __FILE__, m ) |
|
181 #define TEST_FOR_EITHER_VALUE( r, expected1, expected2 ) TEST_FOR_EITHER_VALUE2( r, expected1, expected2, __LINE__, __FILE__ ) |
|
182 #define TEST_FOR_RANGE( r, min, max ) TEST_FOR_RANGE2( r, min, max, __LINE__, __FILE__ ) |
|
183 |
|
184 GLDEF_C void TestIfError( TInt aValue, TInt aLine, const TText* aFile ) |
|
185 { |
|
186 if( aValue < 0 ) |
|
187 { |
|
188 _LIT( KErrorTestFailMsg, "ERROR %d\n\r" ); |
|
189 test.Printf( KErrorTestFailMsg, aValue ); |
|
190 test.operator()( EFalse, aLine, (const TText*)(aFile) ); |
|
191 } |
|
192 } |
|
193 |
|
194 GLDEF_C void TestIfErrorMsg( TInt aValue, TInt aLine, const TText* aFile, const TDesC& aMessageOnError ) |
|
195 { |
|
196 if( aValue < 0 ) |
|
197 { |
|
198 _LIT( KErrorTestFailMsg, "ERROR %d %S\n\r" ); |
|
199 test.Printf( KErrorTestFailMsg, aValue, &aMessageOnError ); |
|
200 test.operator()( EFalse, aLine, (const TText*)(aFile) ); |
|
201 } |
|
202 } |
|
203 |
|
204 |
|
205 GLDEF_C void TestEqual( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile ) |
|
206 { |
|
207 if( aExpected != aValue ) |
|
208 { |
|
209 _LIT( KEqualTestFailMsg, "ERROR %d expected %d\n\r" ); |
|
210 test.Printf( KEqualTestFailMsg, aValue, aExpected ); |
|
211 test.operator()( EFalse, aLine, (const TText*)(aFile) ); |
|
212 } |
|
213 } |
|
214 |
|
215 GLDEF_C void TestEqualMsg( TInt aValue, TInt aExpected, TInt aLine, const TText* aFile, const TDesC& aMessageOnError ) |
|
216 { |
|
217 if( aExpected != aValue ) |
|
218 { |
|
219 _LIT( KEqualTestFailMsg, "ERROR %d expected %d %S\n\r" ); |
|
220 test.Printf( KEqualTestFailMsg, aValue, aExpected, &aMessageOnError ); |
|
221 test.operator()( EFalse, aLine, (const TText*)(aFile) ); |
|
222 } |
|
223 } |
|
224 |
|
225 GLDEF_C void TestEitherEqual( TInt aValue, TInt aExpected1, TInt aExpected2, TInt aLine, const TText* aFile ) |
|
226 { |
|
227 if( (aExpected1 != aValue) && (aExpected2 != aValue) ) |
|
228 { |
|
229 _LIT( KEqualTestFailMsg, "ERROR %d expected %d or %d\n\r" ); |
|
230 test.Printf( KEqualTestFailMsg, aValue, aExpected1, aExpected2 ); |
|
231 test.operator()( EFalse, aLine, (const TText*)(aFile) ); |
|
232 } |
|
233 } |
|
234 |
|
235 GLDEF_C void TestRange( TInt aValue, TInt aMin, TInt aMax, TInt aLine, const TText* aFile ) |
|
236 { |
|
237 if( (aValue < aMin) || (aValue > aMax) ) |
|
238 { |
|
239 _LIT( KRangeTestFailMsg, "ERROR 0x%x expected 0x%x..0x%x\n\r" ); |
|
240 test.Printf( KRangeTestFailMsg, aValue, aMin, aMax ); |
|
241 test.operator()( EFalse, aLine, (const TText*)(aFile) ); |
|
242 } |
|
243 } |
|
244 |
|
245 //// |
|
246 |
|
247 TMMCDrive::TMMCDrive() |
|
248 : iTestMode(ETestPartition), |
|
249 iDriveSize(0), |
|
250 iMediaSize(0) |
|
251 { |
|
252 } |
|
253 |
|
254 TInt TMMCDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg) |
|
255 { |
|
256 if(iTestMode == ETestWholeMedia) |
|
257 { |
|
258 return TBusLocalDrive::Read(aPos, aLength, &aTrg, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia); |
|
259 } |
|
260 else if(iTestMode != ETestPartition && aLength <= (TInt)ChunkSize) |
|
261 { |
|
262 TPtr8 wholeBufPtr(TheChunk.Base(),aLength); |
|
263 |
|
264 TInt r = TBusLocalDrive::Read(aPos, aLength, wholeBufPtr); |
|
265 |
|
266 aTrg.Copy(wholeBufPtr); |
|
267 return r; |
|
268 } |
|
269 |
|
270 return TBusLocalDrive::Read(aPos, aLength, aTrg); |
|
271 } |
|
272 |
|
273 TInt TMMCDrive::Write(TInt64 aPos,const TDesC8& aSrc) |
|
274 { |
|
275 if(iTestMode == ETestWholeMedia) |
|
276 { |
|
277 return TBusLocalDrive::Write(aPos, aSrc.Length(), &aSrc, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia); |
|
278 } |
|
279 else if(iTestMode != ETestPartition && aSrc.Length() <= (TInt)ChunkSize) |
|
280 { |
|
281 TPtr8 wholeBufPtr(TheChunk.Base(),aSrc.Length()); |
|
282 wholeBufPtr.Copy(aSrc); |
|
283 |
|
284 TInt r = TBusLocalDrive::Write(aPos, wholeBufPtr); |
|
285 |
|
286 return r; |
|
287 } |
|
288 |
|
289 return TBusLocalDrive::Write(aPos, aSrc); |
|
290 } |
|
291 |
|
292 TInt TMMCDrive::SetTestMode(TTestMode aTestMode) |
|
293 { |
|
294 switch (aTestMode) |
|
295 { |
|
296 case ETestWholeMedia : test.Printf(_L("\nTesting Whole Media\n")); break; |
|
297 case ETestPartition : test.Printf(_L("\nTesting Partition\n")); break; |
|
298 case ETestSharedMemory : test.Printf(_L("\nTesting Shared Memory\n")); break; |
|
299 case ETestSharedMemoryCache : test.Printf(_L("\nTesting Shared Memory (Caching)\n")); break; |
|
300 case ETestSharedMemoryFrag : test.Printf(_L("\nTesting Shared Memory (Fragmented)\n")); break; |
|
301 default : test.Printf(_L("\nTesting Shared Memory (Fragmented/Caching)\n")); break; |
|
302 } |
|
303 |
|
304 if(aTestMode == ETestWholeMedia && iMediaSize == 0) |
|
305 { |
|
306 test.Printf(_L("...not supported")); |
|
307 return KErrNotSupported; |
|
308 } |
|
309 |
|
310 iTestMode = aTestMode; |
|
311 return KErrNone; |
|
312 } |
|
313 |
|
314 TMMCDrive::TTestMode TMMCDrive::TestMode() |
|
315 { |
|
316 return iTestMode; |
|
317 } |
|
318 |
|
319 void TMMCDrive::SetSize(TInt64 aDriveSize, TInt64 aMediaSize) |
|
320 { |
|
321 iDriveSize = aDriveSize; |
|
322 iMediaSize = aMediaSize; |
|
323 } |
|
324 |
|
325 TInt64 TMMCDrive::Size() |
|
326 { |
|
327 switch (iTestMode) |
|
328 { |
|
329 case ETestWholeMedia : return iMediaSize; |
|
330 default : return iDriveSize; |
|
331 } |
|
332 } |
|
333 |
|
334 ////// |
|
335 |
|
336 GLDEF_C void DumpBuffer( const TDesC8& aBuffer ) |
|
337 /** |
|
338 * Dump the content of aBuffer in hex |
|
339 */ |
|
340 { |
|
341 static const TText hextab[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
|
342 'A', 'B', 'C', 'D', 'E', 'F' }; |
|
343 const TInt KBytesPerLine = 32; |
|
344 const TInt KCharsPerLine = KBytesPerLine * 2; |
|
345 |
|
346 TInt remaining = aBuffer.Length(); |
|
347 TUint8* pSrc = const_cast<TUint8*>(aBuffer.Ptr()); |
|
348 |
|
349 TBuf<KCharsPerLine> line; |
|
350 line.SetLength( KCharsPerLine ); // don't need to print trailing space |
|
351 TInt bytesPerLine = KBytesPerLine; |
|
352 TInt lineOffs = 0; |
|
353 while( remaining ) |
|
354 { |
|
355 if( remaining < KBytesPerLine ) |
|
356 { |
|
357 bytesPerLine = remaining; |
|
358 line.SetLength( (bytesPerLine*2) ); |
|
359 } |
|
360 TUint16* pDest = const_cast<TUint16*>(line.Ptr()); |
|
361 remaining -= bytesPerLine; |
|
362 for( TInt i = bytesPerLine; i > 0; --i ) |
|
363 { |
|
364 TUint8 c = *pSrc++; |
|
365 *pDest++ = hextab[c >> 4]; |
|
366 *pDest++ = hextab[c & 0xF]; |
|
367 } |
|
368 _LIT( KFmt, "%06x: %S\n\r" ); |
|
369 test.Printf( KFmt, lineOffs, &line ); |
|
370 lineOffs += bytesPerLine; |
|
371 } |
|
372 } |
|
373 |
|
374 |
|
375 GLDEF_C TBool CompareBuffers( const TDesC8& aBuf1, const TDesC8& aBuf2 ) |
|
376 { |
|
377 TInt count = 32; |
|
378 if (aBuf1.Length() < count) |
|
379 count = aBuf1.Length(); |
|
380 |
|
381 |
|
382 for (TInt i = 0; i < (aBuf1.Length()-count); i+= count) |
|
383 { |
|
384 if( aBuf1.Mid(i,count).Compare(aBuf2.Mid(i,count)) != 0) |
|
385 { |
|
386 // now need to find where mismatch ends |
|
387 TInt j =i; |
|
388 for (; j <= (aBuf1.Length()-count); j+= count) |
|
389 { |
|
390 if( aBuf1.Mid(j,count).Compare(aBuf2.Mid(j,count)) == 0) break; |
|
391 } |
|
392 test.Printf(_L("buf1 len: %d, buf2 len: %d\n"),aBuf1.Length(),aBuf2.Length()); |
|
393 test.Printf( _L("Buffer mismatch @%d to %d (%d Bytes)\n\r"),i,j, (j-i) ); |
|
394 test.Printf( _L("buffer 1 ------------------\n\r") ); |
|
395 DumpBuffer( aBuf1.Mid(i,(j-i)) ); |
|
396 test.Printf( _L("buffer 2 ------------------\n\r") ); |
|
397 DumpBuffer( aBuf2.Mid(i,(j-i)) ); |
|
398 test.Printf(_L("buf1 len: %d, buf2 len: %d\n"),aBuf1.Length(),aBuf2.Length()); |
|
399 test.Printf( _L("Buffer mismatch @%d to %d (%d Bytes)\n\r"),i,j, (j-i) ); |
|
400 return EFalse; |
|
401 } |
|
402 } |
|
403 return ETrue; |
|
404 } |
|
405 |
|
406 |
|
407 void singleSectorRdWrTest(TInt aSectorOffset,TInt aLen) |
|
408 // |
|
409 // Perform a write / read test on a single sector (KSingSectorNo). Verify that the |
|
410 // write / read back is successful and that the rest of the sector is unchanged. |
|
411 // |
|
412 { |
|
413 |
|
414 TBuf8<KDiskSectorSize> saveBuf; |
|
415 test.Start(_L("Single sector write/read test")); |
|
416 test(aSectorOffset+aLen<=KDiskSectorSize); |
|
417 |
|
418 // Now save state of sector before we write to it |
|
419 TInt secStart=(KSingSectorNo<<KDiskSectorShift); |
|
420 test(TheMmcDrive.Read(secStart,KDiskSectorSize,saveBuf)==KErrNone); |
|
421 |
|
422 // Write zero's to another sector altogether (to ensure drivers |
|
423 // local buffer hasn't already got test pattern we expect). |
|
424 wrBuf.Fill(0,KDiskSectorSize); |
|
425 test(TheMmcDrive.Write((KSingSectorNo+4)<<KDiskSectorShift,wrBuf)==KErrNone); |
|
426 |
|
427 // Write / read back sector in question |
|
428 wrBuf.SetLength(aLen); |
|
429 for (TInt i=0;i<aLen;i++) |
|
430 wrBuf[i]=(TUint8)(0xFF-i); |
|
431 test(TheMmcDrive.Write((secStart+aSectorOffset),wrBuf)==KErrNone); |
|
432 rdBuf.Fill(0,aLen); |
|
433 test(TheMmcDrive.Read((secStart+aSectorOffset),aLen,rdBuf)==KErrNone); |
|
434 test(CompareBuffers(rdBuf, wrBuf)); |
|
435 //test(rdBuf.Compare(wrBuf)==0); |
|
436 |
|
437 // Now check the rest of the sector is unchanged |
|
438 rdBuf.Fill(0,KDiskSectorSize); |
|
439 test(TheMmcDrive.Read(secStart,KDiskSectorSize,rdBuf)==KErrNone); |
|
440 saveBuf.Replace(aSectorOffset,aLen,wrBuf); |
|
441 test(CompareBuffers(rdBuf, saveBuf)); |
|
442 test.End(); |
|
443 } |
|
444 |
|
445 const TInt KMultSectorNo=2; |
|
446 |
|
447 void MultipleSectorRdWrTestMB(TInt aFirstSectorOffset, TInt aLen, TBool aWrMB, TBool aRdMB) |
|
448 // |
|
449 // Perform a write / read test over multiple sectors (starting within sector KMultSectorNo). |
|
450 // Verify that the write / read back is successful and that the remainder of the first and |
|
451 // last sectors are not affected. |
|
452 // |
|
453 { |
|
454 |
|
455 TBuf8<KDiskSectorSize> saveBuf1; |
|
456 TBuf8<KDiskSectorSize> saveBuf2; |
|
457 |
|
458 test.Printf(_L(" MBW[%d] : MBR[%d]\n\r"), aWrMB, aRdMB); |
|
459 |
|
460 test(aFirstSectorOffset<KDiskSectorSize&&aLen<=KVeryLongRdWrBufLen); |
|
461 |
|
462 // If not starting on sector boundary then save 1st sector to check rest of 1st sector is unchanged |
|
463 TInt startSecPos=(KMultSectorNo<<KDiskSectorShift); |
|
464 if (aFirstSectorOffset!=0) |
|
465 test(TheMmcDrive.Read(startSecPos,KDiskSectorSize,saveBuf1)==KErrNone); |
|
466 |
|
467 // If not ending on sector boundary then save last sector to check rest of last sector is unchanged |
|
468 TInt endOffset=(aFirstSectorOffset+aLen)&(~KDiskSectorMask); |
|
469 TInt endSecPos=((startSecPos+aFirstSectorOffset+aLen)&KDiskSectorMask); |
|
470 if (endOffset) |
|
471 { |
|
472 test(TheMmcDrive.Read(endSecPos,KDiskSectorSize,saveBuf2)==KErrNone); |
|
473 } |
|
474 |
|
475 // Write zero's to another sector altogether (to ensure drivers |
|
476 // local buffer hasn't already got test pattern we expect). |
|
477 wrBuf.Fill(0,KSectBufSizeInBytes); |
|
478 test(TheMmcDrive.Write((endSecPos+(2*KDiskSectorSize)),wrBuf)==KErrNone); |
|
479 |
|
480 TInt i; |
|
481 |
|
482 wrBuf.SetLength(aLen); |
|
483 for (i=0;i<aLen;i++) |
|
484 { |
|
485 wrBuf[i]=(TUint8)(0xFF-i); |
|
486 } |
|
487 |
|
488 if(aWrMB) |
|
489 { |
|
490 test(TheMmcDrive.Write((startSecPos+aFirstSectorOffset),wrBuf)==KErrNone); |
|
491 } |
|
492 else |
|
493 { |
|
494 for (i=0;i<aLen;i+=512) |
|
495 { |
|
496 TInt thisLen = (aLen-i) < 512 ? (aLen-i) : 512; |
|
497 TPtrC8 sectorWr(wrBuf.Mid(i, thisLen).Ptr(), thisLen); |
|
498 test(TheMmcDrive.Write((startSecPos+aFirstSectorOffset+i), sectorWr)==KErrNone); |
|
499 } |
|
500 } |
|
501 |
|
502 rdBuf.Fill(0,aLen); |
|
503 rdBuf.SetLength(aLen); |
|
504 |
|
505 if(aRdMB) |
|
506 { |
|
507 test(TheMmcDrive.Read((startSecPos+aFirstSectorOffset),aLen,rdBuf) == KErrNone); |
|
508 } |
|
509 else |
|
510 { |
|
511 for (i=0;i<aLen;i+=512) |
|
512 { |
|
513 TInt thisLen = (aLen-i) < 512 ? (aLen-i) : 512; |
|
514 TPtr8 sectorRd(((TUint8*)(rdBuf.Ptr()))+i, thisLen, thisLen); |
|
515 test(TheMmcDrive.Read((startSecPos+aFirstSectorOffset+i), thisLen, sectorRd) == KErrNone); |
|
516 } |
|
517 } |
|
518 |
|
519 test(CompareBuffers(rdBuf, wrBuf)); |
|
520 |
|
521 // Check rest of first sector involved is unchanged (if offset specified) |
|
522 if (aFirstSectorOffset!=0) |
|
523 { |
|
524 rdBuf.Fill(0,KDiskSectorSize); |
|
525 test(TheMmcDrive.Read(startSecPos,KDiskSectorSize,rdBuf)==KErrNone); |
|
526 wrBuf.SetLength(KDiskSectorSize-aFirstSectorOffset); |
|
527 saveBuf1.Replace(aFirstSectorOffset,(KDiskSectorSize-aFirstSectorOffset),wrBuf); |
|
528 test(rdBuf.Compare(saveBuf1)==0); |
|
529 } |
|
530 |
|
531 // Check rest of last sector involved is unchanged (if not ending on sector boundary) |
|
532 if (endOffset) |
|
533 { |
|
534 rdBuf.Fill(0,KDiskSectorSize); |
|
535 test(TheMmcDrive.Read(endSecPos,KDiskSectorSize,rdBuf)==KErrNone); |
|
536 wrBuf.SetLength(aLen); |
|
537 wrBuf.Delete(0,aLen-endOffset); |
|
538 saveBuf2.Replace(0,endOffset,wrBuf); |
|
539 test(CompareBuffers(rdBuf, saveBuf2)); |
|
540 } |
|
541 } |
|
542 |
|
543 void MultipleSectorRdWrTest(TInt aFirstSectorOffset,TInt aLen, TBool aMBOnly = EFalse) |
|
544 // |
|
545 // Perform a write / read test over multiple sectors (starting within sector KMultSectorNo). |
|
546 // Verify that the write / read back is successful and that the remainder of the first and |
|
547 // last sectors are not affected. |
|
548 // |
|
549 { |
|
550 test.Start(_L("Multiple sector write/read test")); |
|
551 |
|
552 if(!aMBOnly) |
|
553 { |
|
554 MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, EFalse, EFalse); |
|
555 MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, EFalse, ETrue); |
|
556 MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, ETrue, EFalse); |
|
557 } |
|
558 |
|
559 MultipleSectorRdWrTestMB(aFirstSectorOffset, aLen, ETrue, ETrue); |
|
560 |
|
561 test.End(); |
|
562 } |
|
563 |
|
564 LOCAL_C TInt dontDisconnectThread(TAny*) |
|
565 { |
|
566 |
|
567 TBusLocalDrive anotherMmcDrive; |
|
568 nTest.Title(); |
|
569 |
|
570 nTest.Start(_L("Connect to internal drive")); |
|
571 anotherMmcDrive.Connect(DriveNumber,SecThreadChangeFlag); |
|
572 |
|
573 nTest.Next(_L("Capabilities")); |
|
574 TLocalDriveCapsV2 info; |
|
575 TPckg<TLocalDriveCapsV2> infoPckg(info); |
|
576 nTest(anotherMmcDrive.Caps(infoPckg)==KErrNone); |
|
577 nTest(info.iType==EMediaHardDisk); |
|
578 |
|
579 nTest.End(); |
|
580 return(KErrNone); |
|
581 } |
|
582 |
|
583 LOCAL_C void ProgressBar(TInt64 aPos,TInt64 anEndPos,TInt anXPos) |
|
584 // |
|
585 // Display progress of local drive operation on screen (1-16 dots) |
|
586 // |
|
587 { |
|
588 static TInt64 prev; |
|
589 TInt64 curr; |
|
590 if ((curr=(aPos-1)/(anEndPos>>4))>prev) |
|
591 { // Update progress bar |
|
592 test.Console()->SetPos(anXPos); |
|
593 for (TInt64 i=curr;i>=0;i--) |
|
594 test.Printf(_L(".")); |
|
595 } |
|
596 prev=curr; |
|
597 } |
|
598 |
|
599 |
|
600 /** |
|
601 @SYMTestCaseID PBASE-T_MMCDRV-0510 |
|
602 @SYMTestCaseDesc Test Write/Read during media Change |
|
603 @SYMTestPriority High |
|
604 |
|
605 @SYMTestActions |
|
606 a.) Test Read during a Media Change |
|
607 b.) Test Write during a Media Change |
|
608 |
|
609 @SYMTestExpectedResults All tests must pass |
|
610 */ |
|
611 LOCAL_C void TestHugeReadWrite(TBool aIsRead, TInt aLen) |
|
612 // |
|
613 // Writes aLen bytes to the MMC drive. Gives user enough time to flip the media |
|
614 // change switch. Request should abort with KErrNotReady on write command, but nothing |
|
615 // on read command. |
|
616 // Each read or write is started from sector KMultSectNo (2). |
|
617 // The media change operation only works when the switch is moved from the closed position |
|
618 // to the open position. |
|
619 // |
|
620 { |
|
621 test.Start(_L("TestHugeReadWrite: media change during I/O test.")); |
|
622 test.Printf(_L("aIsRead = %x, aLen = %x.\n"), aIsRead, aLen); |
|
623 |
|
624 HBufC8 *buf = HBufC8::New(aLen); |
|
625 test(buf != NULL); |
|
626 |
|
627 TInt startSectPos = KMultSectorNo << KDiskSectorShift; |
|
628 if (aIsRead) |
|
629 { |
|
630 test.Printf(_L("Launching %08x byte read at %08x.\n"), aLen, startSectPos); |
|
631 test.Printf(_L("Move media change from closed to open position before finished.\n")); |
|
632 TPtr8 ptr(buf->Des()); |
|
633 TInt r = TheMmcDrive.Read(startSectPos, aLen, ptr); |
|
634 test.Printf(_L("r = %d.\n"), r); |
|
635 test(r == KErrNone); |
|
636 } |
|
637 else |
|
638 { |
|
639 buf->Des().Fill(0xff, aLen); |
|
640 test.Printf(_L("Launching %08x byte write at %08x.\n"), aLen, startSectPos); |
|
641 test.Printf(_L("Move media change from closed to open position before finished.\n")); |
|
642 TInt r = TheMmcDrive.Write(startSectPos, *buf); |
|
643 test.Printf(_L("r = %d.\n"), r); |
|
644 test(r == KErrNotReady); |
|
645 } |
|
646 |
|
647 test.Printf(_L("Pausing for 5 seconds to move media change switch back to closed.\n")); |
|
648 User::After(5 * 1000 * 1000); |
|
649 delete buf; |
|
650 test.End(); |
|
651 } |
|
652 |
|
653 |
|
654 LOCAL_C void FillBufferWithPattern(TDes8 &aBuf) |
|
655 // |
|
656 // Fills aBuf with cycling hex digits up to aBuf.Length(). |
|
657 // |
|
658 { |
|
659 TInt len = aBuf.Length() & ~3; |
|
660 for (TInt i = 0; i < len; i+=4) |
|
661 { |
|
662 *((TUint32*) &aBuf[i]) = i; |
|
663 } |
|
664 } |
|
665 |
|
666 |
|
667 LOCAL_C void WriteAndReadBack(TInt64 aStartPos, const TDesC8 &aWrBuf) |
|
668 // |
|
669 // This function tests the multiple block reads when aWrBuf is sufficiently large. |
|
670 // |
|
671 { |
|
672 test.Start(_L("WriteAndReadBack")); |
|
673 |
|
674 TInt r; // general error values |
|
675 |
|
676 // Allocate a same size buffer to read back into and compare with. |
|
677 HBufC8 *rdBuf = aWrBuf.Alloc(); |
|
678 test(rdBuf != NULL); |
|
679 TPtr8 rdPtr(rdBuf->Des()); |
|
680 |
|
681 test.Next(_L("wrb: writing")); |
|
682 r = TheMmcDrive.Write(aStartPos, aWrBuf); |
|
683 test.Printf(_L("\nwrb:r=%d"), r); |
|
684 test(r == KErrNone); |
|
685 |
|
686 test.Printf(_L("\n")); |
|
687 test.Next(_L("wrb: reading")); |
|
688 r = TheMmcDrive.Read(aStartPos, rdPtr.Length(), rdPtr); |
|
689 test.Printf(_L("rb:r=%d"), r); |
|
690 test(r == KErrNone); |
|
691 |
|
692 // Compare the pattern that has just been read back with the original. |
|
693 test.Printf(_L("\n")); |
|
694 test.Next(_L("wrb: comparing")); |
|
695 test.Printf( |
|
696 _L("rdPtr.Length() = %04x, aWrBuf.Length() = %04x"), |
|
697 rdPtr.Length(), aWrBuf.Length()); |
|
698 test(rdPtr == aWrBuf); |
|
699 |
|
700 #if 0 // extra debug when buffers not compare. |
|
701 for (TInt j = 0; j < rdPtr.Length(); j++) |
|
702 { |
|
703 test.Printf(_L("%d: w%02x r%02x"), j, aWrBuf[j], rdBuf[j]); |
|
704 |
|
705 if (rdPtr[j] != aWrBuf[j]) |
|
706 { |
|
707 test.Printf(_L("buffer mismatch at %04x: %02x v %02x"), j, rdPtr[j], aWrBuf[j]); |
|
708 test(EFalse); |
|
709 } |
|
710 } |
|
711 #endif |
|
712 |
|
713 test.Printf(_L("\n")); |
|
714 delete rdBuf; |
|
715 test.End(); |
|
716 } |
|
717 |
|
718 /** |
|
719 @SYMTestCaseID PBASE-T_MMCDRV-0169 |
|
720 @SYMTestCaseDesc Test Multiple Block Reads |
|
721 @SYMTestPriority High |
|
722 |
|
723 @SYMTestActions |
|
724 a.) Test Multiple Block Reads at the internal buffer size |
|
725 b.) Test Multiple Block Reads greater than the internal buffer size |
|
726 |
|
727 @SYMTestExpectedResults All tests must pass |
|
728 |
|
729 @TODO: increase Buffer size to match current reference platform (128KB) |
|
730 */ |
|
731 LOCAL_C void TestMultipleBlockReads() |
|
732 { |
|
733 // Test multiple block reads. |
|
734 static TBuf8<256 * 1024> rw_wrBuf; |
|
735 |
|
736 rw_wrBuf.SetLength(rw_wrBuf.MaxLength()); |
|
737 FillBufferWithPattern(rw_wrBuf); |
|
738 |
|
739 test.Next(_L("Testing multiple block reads at internal buffer size")); |
|
740 rw_wrBuf.SetLength(8 * KDiskSectorSize); |
|
741 WriteAndReadBack(KMultSectorNo << KDiskSectorShift, rw_wrBuf); |
|
742 |
|
743 test.Next(_L("Testing multiple block reads at gt internal buffer size")); |
|
744 rw_wrBuf.SetLength(10 * KDiskSectorSize); |
|
745 WriteAndReadBack(KMultSectorNo << KDiskSectorShift, rw_wrBuf); |
|
746 |
|
747 test.Next(_L("Testing unaligned large block read ")); |
|
748 rw_wrBuf.SetLength(rw_wrBuf.MaxLength()); |
|
749 WriteAndReadBack((KMultSectorNo << KDiskSectorShift) + 128, rw_wrBuf); |
|
750 } |
|
751 |
|
752 |
|
753 /** |
|
754 @SYMTestCaseID PBASE-T_MMCDRV-0558 |
|
755 @SYMTestCaseDesc Test Long Read/Write Boundaries |
|
756 @SYMTestPriority High |
|
757 |
|
758 @SYMTestActions |
|
759 |
|
760 Perform and Write/Read/Verify for the given length (L) of data across the following boundaries. |
|
761 Depending on the length provided, this will also perform a partial write/read at the end sector. |
|
762 |
|
763 ------------------- |
|
764 | Start | End | |
|
765 |-------------------| |
|
766 | 0 | L | |
|
767 | 507 | L-507 | |
|
768 | 10 | L | |
|
769 | 0 | L-3 | |
|
770 | 27 | L-512 | |
|
771 | 0 | L-509 | |
|
772 | 3 | L-3 | |
|
773 ------------------- |
|
774 |
|
775 For each combination, the write/read/verify operations are performed in the following sequence: |
|
776 |
|
777 a: Write and Read in single 512-byte blocks. |
|
778 b: Write in a single operation (multiple blocks), Read in 512-Byte blocks. |
|
779 c: Write in 512-Byte blocks, Read in a single operation (multiple-blocks). |
|
780 d: Write and Read in a single operation (multiple-blocks). |
|
781 |
|
782 In the cases where a partial read/write operation occurs (ie - the start and/or end position don't lie within |
|
783 a sector boundary), the original contents of the start and/or end sectors are read and stored at the start of |
|
784 the test, and compared with the contents of the sectors at the end of the test to ensure that unwritten data within |
|
785 the sectors remain unaffected. |
|
786 |
|
787 @SYMTestExpectedResults All tests must pass |
|
788 |
|
789 @SYMPREQ1389 REQ6951 Double Buffering and SD Switch |
|
790 */ |
|
791 |
|
792 LOCAL_C void TestLongReadWriteBoundaries(TUint aLen, TBool aMBOnly = EFalse) |
|
793 { |
|
794 TBuf<64> b; |
|
795 |
|
796 b.Format(_L("MMC drive: Very long RdWr(1) (%dbytes at %d)"),aLen,0); |
|
797 test.Next(b); |
|
798 MultipleSectorRdWrTest(0, aLen, aMBOnly); // Exceeds driver's buffer, starts/ends on sector boundary |
|
799 |
|
800 b.Format(_L("MMC drive: Very long RdWr(2) (%dbytes at %d)"),(aLen-KDiskSectorSize+5),507); |
|
801 test.Next(b); |
|
802 MultipleSectorRdWrTest(507, (aLen-KDiskSectorSize+5), aMBOnly); // Exceeds driver's buffer, ends on sector boundary |
|
803 |
|
804 b.Format(_L("MMC drive: Very long RdWr(3) (%dbytes at %d)"),aLen,10); |
|
805 test.Next(b); |
|
806 MultipleSectorRdWrTest(10, aLen, aMBOnly); // Exceeds driver's buffer, starts/ends off sector boundary |
|
807 |
|
808 b.Format(_L("MMC drive: Very long RdWr(4) (%dbytes at %d)"),(aLen-3),0); |
|
809 test.Next(b); |
|
810 MultipleSectorRdWrTest(0, aLen-3, aMBOnly); // Exceeds driver's buffer, starts on sector boundary |
|
811 |
|
812 b.Format(_L("MMC drive: Very long RdWr(5) (%dbytes at %d)"),(aLen-KDiskSectorSize),27); |
|
813 test.Next(b); |
|
814 MultipleSectorRdWrTest(27, (aLen-KDiskSectorSize), aMBOnly); // Exceeds driver's buffer (due to start offset), starts/ends off sector boundary |
|
815 |
|
816 b.Format(_L("MMC drive: Very long RdWr(6) (%dbytes at %d)"),(aLen-KDiskSectorSize-3),0); |
|
817 test.Next(b); |
|
818 MultipleSectorRdWrTest(0, aLen-KDiskSectorSize-3, aMBOnly); // Equals driver's buffer, starts on sector boundary |
|
819 |
|
820 b.Format(_L("MMC drive: Very long RdWr(7) (%dbytes at %d)"),(aLen-3),3); |
|
821 test.Next(b); |
|
822 MultipleSectorRdWrTest(3, aLen-3, aMBOnly); // Equals driver's buffer, ends on sector boundary |
|
823 } |
|
824 |
|
825 |
|
826 /** |
|
827 @SYMTestCaseID PBASE-T_MMCDRV-0509 |
|
828 @SYMTestCaseDesc Test Sector Read/Writing |
|
829 @SYMTestPriority High |
|
830 |
|
831 @SYMTestActions |
|
832 a.) Test Writing blocks on sector boundaries |
|
833 b.) Test Reading blocks on sector boundaries |
|
834 c.) Test single sector Write/Read at: |
|
835 i.) Sector Start |
|
836 ii.) Mid Sector |
|
837 iii.) Sector End |
|
838 d.) Test Multiple Sector Write/Read: |
|
839 i.) Start on Sector Boundary |
|
840 ii.) Start/End on Sector Boundary |
|
841 iii.) End on Sector Boundary |
|
842 e.) Test Write/Read over sector boundary |
|
843 |
|
844 @SYMTestExpectedResults All tests must pass |
|
845 */ |
|
846 LOCAL_C void TestSectorReadWrite() |
|
847 { |
|
848 TBuf<64> b; |
|
849 b.Format(_L("MMC drive: Sector RdWr(%d)"), KDiskSectorSize); |
|
850 |
|
851 test.Next(b); |
|
852 |
|
853 TInt len; |
|
854 |
|
855 // Fill wrBuf with a pattern of ascending numbers. |
|
856 wrBuf.SetLength(KDiskSectorSize); |
|
857 TUint32 *p = REINTERPRET_CAST(TUint32 *, &wrBuf[0]); |
|
858 TInt secPos; |
|
859 for (secPos = 0; secPos < KDiskSectorSize; secPos++) |
|
860 { |
|
861 wrBuf[secPos] = TUint8(secPos % 0x0100); |
|
862 } |
|
863 |
|
864 // Write 512 byte blocks to the card, writing the sector number to the first |
|
865 // word in each buffer. |
|
866 |
|
867 test.Printf(_L("Writing ")); |
|
868 TInt64 i; |
|
869 // for (i=0;i<DriveSize;i+=len) // B - Sector wr/rd on sector boundary |
|
870 for (i=0;i<(0x200<<3);i+=len) // B - Sector wr/rd on sector boundary |
|
871 { |
|
872 ProgressBar(i, TheMmcDrive.Size(), 11); |
|
873 len = KDiskSectorSize < TheMmcDrive.Size() - i ? KDiskSectorSize : I64LOW(TheMmcDrive.Size() - i); |
|
874 (*p) = I64LOW(i) / KDiskSectorSize; |
|
875 wrBuf.SetLength(len); |
|
876 TInt r = TheMmcDrive.Write(i, wrBuf); |
|
877 if (r != KErrNone) |
|
878 { |
|
879 test.Printf(_L("wt:i = %d, len = %d, r %d"), i, len, r); |
|
880 test(EFalse); |
|
881 } |
|
882 } |
|
883 |
|
884 // Read each of the 512 byte blocks back from the card. |
|
885 test.Printf(_L("\r\nReading ")); |
|
886 // for (i=0;i<TheMmcDrive.Size();i+=len) |
|
887 for (i=0;i<(0x200<<3);i+=len) // B - Sector wr/rd on sector boundary |
|
888 { |
|
889 ProgressBar(i, TheMmcDrive.Size(), 11); |
|
890 len = KDiskSectorSize < TheMmcDrive.Size() - i ? KDiskSectorSize : I64LOW(TheMmcDrive.Size() - i); |
|
891 rdBuf.Fill(0,len); |
|
892 TInt r = TheMmcDrive.Read(i, len, rdBuf); |
|
893 if (r != KErrNone) |
|
894 { |
|
895 test.Printf(_L("rd:i = %d, len = %d, r %d"), i, len, r); |
|
896 test(EFalse); |
|
897 } |
|
898 (*p) = (I64LOW(i)/KDiskSectorSize); |
|
899 wrBuf.SetLength(len); |
|
900 |
|
901 if ((r = rdBuf.Compare(wrBuf)) != 0) |
|
902 { |
|
903 test.Printf(_L("wc:i = %d, len = %d, r %d"), i, len, r); |
|
904 test.Printf(_L("wc: wrBuf.Length() = %d, rdBuf.Length() = %d"), wrBuf.Length(), rdBuf.Length()); |
|
905 TInt j; |
|
906 for (j = 0; j < wrBuf.Length() && wrBuf[j] == rdBuf[j]; j++) |
|
907 { |
|
908 // empty. |
|
909 } |
|
910 test.Printf(_L("wc: wrBuf[%d] = %d, rdBuf[%d] = %d"), j, wrBuf[j], j, rdBuf[j]); |
|
911 |
|
912 test(EFalse); |
|
913 } |
|
914 } |
|
915 test.Printf(_L("\r\n")); |
|
916 |
|
917 b.Format(_L("MMC drive: Short RdWr(1) (%dbytes at %d)"),25,0); |
|
918 test.Next(b); |
|
919 singleSectorRdWrTest(0,25); // A - Sub-sector wr/rd at sector start |
|
920 |
|
921 b.Format(_L("MMC drive: Short RdWr(2) (%dbytes at %d)"),16,277); |
|
922 test.Next(b); |
|
923 singleSectorRdWrTest(277,16); // E - Sub-sector wr/rd in mid sector |
|
924 |
|
925 b.Format(_L("MMC drive: Short RdWr(3) (%dbytes at %d)"),100,412); |
|
926 test.Next(b); |
|
927 singleSectorRdWrTest(412,100); // F - Sub-sector wr/rd at sector end |
|
928 |
|
929 b.Format(_L("MMC drive: Long RdWr(1) (%dbytes at %d)"),KDiskSectorSize+15,0); |
|
930 test.Next(b); |
|
931 MultipleSectorRdWrTest(0,KDiskSectorSize+15); // C - Long wr/rd starting on sector boundary |
|
932 |
|
933 b.Format(_L("MMC drive: Long RdWr(2) (%dbytes at %d)"),(KDiskSectorSize<<1),0); |
|
934 test.Next(b); |
|
935 MultipleSectorRdWrTest(0,(KDiskSectorSize<<1)); // D - Long wr/rd starting/ending on sector boundary |
|
936 |
|
937 b.Format(_L("MMC drive: Long RdWr(3) (%dbytes at %d)"),KDiskSectorSize+3,509); |
|
938 test.Next(b); |
|
939 MultipleSectorRdWrTest(509,KDiskSectorSize+3); // H - - Long wr/rd ending on sector boundary |
|
940 |
|
941 b.Format(_L("MMC drive: Long RdWr(4) (%dbytes at %d)"),(KDiskSectorSize<<1),508); |
|
942 test.Next(b); |
|
943 MultipleSectorRdWrTest(508,(KDiskSectorSize<<1)); |
|
944 |
|
945 b.Format(_L("MMC drive: Sector RdWr across sector boundary(%dbytes at %d)"),KDiskSectorSize,508); |
|
946 test.Next(b); |
|
947 MultipleSectorRdWrTest(508,KDiskSectorSize); // G - Sector wr/rd over sector boundary |
|
948 |
|
949 TestLongReadWriteBoundaries(KRdWrBufLen); // Short length - As per original test |
|
950 |
|
951 if (ManualMode) |
|
952 { |
|
953 for(TInt bufLen = KRdWrBufLen; bufLen <= 256*1024; bufLen += KRdWrBufLen) |
|
954 { |
|
955 TestLongReadWriteBoundaries(bufLen, ETrue); // Very long length - to test Double-Buffering |
|
956 } |
|
957 |
|
958 TestLongReadWriteBoundaries(KVeryLongRdWrBufLen, ETrue); // Very long length - to test Double-Buffering |
|
959 } |
|
960 } |
|
961 |
|
962 |
|
963 /** |
|
964 @SYMTestCaseID PBASE-T_MMCDRV-0168 |
|
965 @SYMTestCaseDesc Test Sector Formatting |
|
966 @SYMTestPriority High |
|
967 |
|
968 @SYMTestActions |
|
969 a.) Test Format/Read/Verify Single Sector |
|
970 b.) Test Format/Read/Verify Multiple Sectors |
|
971 c.) Test Format/Read/Verify Whole Media |
|
972 |
|
973 @SYMTestExpectedResults All tests must pass |
|
974 */ |
|
975 LOCAL_C void TestFormat() |
|
976 { |
|
977 if(TheMmcDrive.TestMode() != TMMCDrive::ETestPartition) |
|
978 { |
|
979 test.Printf(_L("Skipping format tests - only supported on Partition Test Mode")); |
|
980 return; |
|
981 } |
|
982 |
|
983 if(CardType == TKnownCardTypes::EBuffalloMiniSD_32M_ERASE || |
|
984 CardType == TKnownCardTypes::EBuffalloMiniSD_64M_ERASE || |
|
985 CardType == TKnownCardTypes::EBuffalloMiniSD_128M_ERASE || |
|
986 CardType == TKnownCardTypes::EBuffalloMiniSD_256M_ERASE || |
|
987 CardType == TKnownCardTypes::EBuffalloMiniSD_512M_ERASE |
|
988 ) |
|
989 { |
|
990 //These cards implement the erase command incorrectly |
|
991 test.Printf( _L(" -- Skipping Format Tests - Known card detected --\n") ); |
|
992 return; |
|
993 } |
|
994 |
|
995 test.Next(_L("MMC drive: Format sectors (short)")); |
|
996 TBuf8<KDiskSectorSize> savBuf1,savBuf2; |
|
997 TInt fmtTestPos=(10<<KDiskSectorShift); |
|
998 // Save sectors surrounding those which will be formatted |
|
999 test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,savBuf1)==KErrNone); |
|
1000 test(TheMmcDrive.Read((fmtTestPos+KShortFormatInBytes),KDiskSectorSize,savBuf2)==KErrNone); |
|
1001 |
|
1002 // Fill buffer with 0xCC |
|
1003 // (i.e. a value which is not going to be written by formatting the device) |
|
1004 // & then write to area which is to be formatted |
|
1005 wrBuf.SetLength(KShortFormatInBytes); |
|
1006 wrBuf.Fill(0xCC); |
|
1007 test(TheMmcDrive.Write(fmtTestPos, wrBuf)==KErrNone); |
|
1008 |
|
1009 |
|
1010 test(TheMmcDrive.Format(fmtTestPos,KShortFormatInBytes)==KErrNone); |
|
1011 test(TheMmcDrive.Read(fmtTestPos,KShortFormatInBytes,rdBuf)==KErrNone); |
|
1012 |
|
1013 TUint8 defEraseVal = rdBuf[0]; |
|
1014 test(defEraseVal == 0x00 || defEraseVal == 0xFF); // The card should erase with 0x00 or 0xFF |
|
1015 wrBuf.Fill(defEraseVal ,KShortFormatInBytes); |
|
1016 test(rdBuf.Compare(wrBuf)==0); |
|
1017 |
|
1018 // Check that surrounding sectors unaffected |
|
1019 test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,rdBuf)==KErrNone); |
|
1020 test(rdBuf.Compare(savBuf1)==0); |
|
1021 test(TheMmcDrive.Read((fmtTestPos+KShortFormatInBytes),KDiskSectorSize,rdBuf)==KErrNone); |
|
1022 test(rdBuf.Compare(savBuf2)==0); |
|
1023 |
|
1024 test.Next(_L("MMC drive: Format sectors (long)")); |
|
1025 fmtTestPos+=(4<<KDiskSectorShift); |
|
1026 // Save sectors surrounding those which will be formatted |
|
1027 test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,savBuf1)==KErrNone); |
|
1028 test(TheMmcDrive.Read((fmtTestPos+KLongFormatInBytes),KDiskSectorSize,savBuf2)==KErrNone); |
|
1029 |
|
1030 // Fill buffer with 0xCC |
|
1031 // (i.e. a value which is not going to be written by formatting the device) |
|
1032 // & then write to area which is to be formatted |
|
1033 wrBuf.SetLength(KLongFormatInBytes); |
|
1034 wrBuf.Fill(0xCC); |
|
1035 test(TheMmcDrive.Write(fmtTestPos, wrBuf)==KErrNone); |
|
1036 |
|
1037 test(TheMmcDrive.Format(fmtTestPos,KLongFormatInBytes)==KErrNone); |
|
1038 test(TheMmcDrive.Read(fmtTestPos,KLongFormatInBytes,rdBuf)==KErrNone); |
|
1039 |
|
1040 defEraseVal = rdBuf[0]; |
|
1041 test(defEraseVal == 0x00 || defEraseVal == 0xFF); // The card should erase with 0x00 or 0xFF |
|
1042 wrBuf.Fill(defEraseVal,KLongFormatInBytes); |
|
1043 TInt cmpRes = rdBuf.Compare(wrBuf); |
|
1044 if(cmpRes != 0) |
|
1045 { |
|
1046 test.Printf(_L("\n\rExpected 0x%02x\n\r")); |
|
1047 for(TInt x=0; x<KLongFormatInBytes; x+=8) |
|
1048 { |
|
1049 test.Printf(_L("%08x : %02x %02x %02x %02x %02x %02x %02x %02x\n\r"), x, rdBuf[x],rdBuf[x+1],rdBuf[x+2],rdBuf[x+3],rdBuf[x+4],rdBuf[x+5],rdBuf[x+6],rdBuf[x+7]); |
|
1050 } |
|
1051 } |
|
1052 test(cmpRes==0); |
|
1053 |
|
1054 // Check that surrounding sectors unaffected |
|
1055 test(TheMmcDrive.Read((fmtTestPos-KDiskSectorSize),KDiskSectorSize,rdBuf)==KErrNone); |
|
1056 test(rdBuf.Compare(savBuf1)==0); |
|
1057 test(TheMmcDrive.Read((fmtTestPos+KLongFormatInBytes),KDiskSectorSize,rdBuf)==KErrNone); |
|
1058 test(rdBuf.Compare(savBuf2)==0); |
|
1059 |
|
1060 if (ManualMode) |
|
1061 { |
|
1062 test.Next(_L("Fill the drive with garbage")); |
|
1063 TInt64 driveSize = TheMmcDrive.Size(); |
|
1064 TInt wtLen = wrBuf.MaxLength(); |
|
1065 TInt64 i; |
|
1066 for (i=0; i<driveSize; i+=wtLen) |
|
1067 { |
|
1068 ProgressBar(i,driveSize,11); |
|
1069 wtLen = wtLen < driveSize - i ? wtLen : I64LOW(driveSize - i); |
|
1070 wrBuf.Fill(0xCC,wtLen); |
|
1071 |
|
1072 wrBuf.SetLength(wtLen); |
|
1073 |
|
1074 test.Printf(_L("writing pos %08lX len %08X\n"), i, wrBuf.Length()); |
|
1075 test(TheMmcDrive.Write(i, wrBuf) == KErrNone); |
|
1076 } |
|
1077 |
|
1078 test.Next(_L("MMC drive: Format entire disk")); |
|
1079 TFormatInfo fi; |
|
1080 test.Printf(_L("Formatting ")); |
|
1081 TInt ret; |
|
1082 TInt stage = 0; |
|
1083 while((ret=TheMmcDrive.Format(fi))!=KErrEof) |
|
1084 { |
|
1085 stage++; |
|
1086 ProgressBar((fi.i512ByteSectorsFormatted<<9),TheMmcDrive.Size(),11); |
|
1087 test(ret==KErrNone); |
|
1088 } |
|
1089 |
|
1090 test.Printf(_L("\r\nReading ")); |
|
1091 |
|
1092 TInt len = KVeryLongSectBufSizeInBytes; |
|
1093 |
|
1094 for (i=0; i<TheMmcDrive.Size(); i+=len) |
|
1095 { |
|
1096 ProgressBar(i,TheMmcDrive.Size(),11); |
|
1097 len = len < TheMmcDrive.Size() - i ? len : I64LOW(TheMmcDrive.Size() - i); |
|
1098 rdBuf.Fill(0x55,len); |
|
1099 test(TheMmcDrive.Read(i,len,rdBuf) == KErrNone); |
|
1100 |
|
1101 const TInt wholeSectors = len / KDiskSectorSize; |
|
1102 const TInt rem = len - (wholeSectors * KDiskSectorSize); |
|
1103 |
|
1104 TInt sec; |
|
1105 for(sec=1;sec<wholeSectors; sec++) // Start at Base+1 - Card may have written an MBR at sector 0 |
|
1106 { |
|
1107 wrBuf.SetLength(KDiskSectorSize); |
|
1108 defEraseVal = rdBuf[sec * KDiskSectorSize]; |
|
1109 test(defEraseVal == 0x00 || defEraseVal == 0xFF); // The card should erase with 0x00 or 0xFF |
|
1110 wrBuf.Fill(defEraseVal, KDiskSectorSize); |
|
1111 test( CompareBuffers( wrBuf, rdBuf.Mid( sec * KDiskSectorSize, KDiskSectorSize ) ) ); |
|
1112 } |
|
1113 |
|
1114 if(rem > 0) |
|
1115 { |
|
1116 wrBuf.SetLength(rem); |
|
1117 defEraseVal = rdBuf[sec * KDiskSectorSize]; |
|
1118 test(defEraseVal == 0x00 || defEraseVal == 0xFF); // The card should erase with 0x00 or 0xFF |
|
1119 wrBuf.Fill(defEraseVal, rem); |
|
1120 test( CompareBuffers( wrBuf, rdBuf.Mid( sec * KDiskSectorSize, rem ) ) ); |
|
1121 } |
|
1122 } |
|
1123 } |
|
1124 } |
|
1125 |
|
1126 |
|
1127 class TRandGen |
|
1128 { |
|
1129 public: |
|
1130 TRandGen(); |
|
1131 void Seed(); |
|
1132 void Seed( const TInt64& aSeed ); |
|
1133 TUint Next(); |
|
1134 |
|
1135 private: |
|
1136 TInt64 iValue; |
|
1137 }; |
|
1138 |
|
1139 |
|
1140 TRandGen::TRandGen() |
|
1141 : iValue(KDefaultRandSeed) |
|
1142 { |
|
1143 } |
|
1144 |
|
1145 |
|
1146 void TRandGen::Seed( const TInt64& aSeed ) |
|
1147 { |
|
1148 iValue = aSeed; |
|
1149 } |
|
1150 |
|
1151 void TRandGen::Seed() |
|
1152 { |
|
1153 iValue = KDefaultRandSeed; |
|
1154 } |
|
1155 |
|
1156 TUint TRandGen::Next() |
|
1157 { |
|
1158 iValue *= 214013; |
|
1159 iValue += 2531011; |
|
1160 return static_cast<TUint>( I64LOW(iValue) ); |
|
1161 } |
|
1162 |
|
1163 |
|
1164 GLDEF_C void FillRandomBuffer( TDes8& aBuf, TRandGen& aRand ) |
|
1165 /** |
|
1166 * Fill buffer aBuf with data generated by aRand |
|
1167 */ |
|
1168 { |
|
1169 TUint l = aBuf.MaxLength(); |
|
1170 aBuf.SetLength( l ); |
|
1171 TUint* p = (TUint*)aBuf.Ptr(); |
|
1172 |
|
1173 // Do any unaligned bytes at the start |
|
1174 TInt preAlign = (TUint)p & 3; |
|
1175 if( preAlign ) |
|
1176 { |
|
1177 preAlign = 4 - preAlign; |
|
1178 TUint8* p8 = (TUint8*)p; |
|
1179 TUint rand = aRand.Next(); |
|
1180 while( preAlign && l ) |
|
1181 { |
|
1182 *p8 = (TUint8)(rand & 0xFF); |
|
1183 rand >>= 8; |
|
1184 ++p8; |
|
1185 --preAlign; |
|
1186 --l; |
|
1187 } |
|
1188 p = (TUint*)p8; |
|
1189 } |
|
1190 |
|
1191 for( ; l > 3; l-=4 ) |
|
1192 { |
|
1193 *p++ = aRand.Next(); |
|
1194 } |
|
1195 // Fill in any trailing bytes |
|
1196 if( l > 0 ) |
|
1197 { |
|
1198 TUint8* q = (TUint8*)p; |
|
1199 TUint r = aRand.Next(); |
|
1200 if( l > 1 ) |
|
1201 { |
|
1202 *((TUint16*)q) = (TUint16)(r & 0xFFFF); |
|
1203 q += 2; |
|
1204 l -= 2; |
|
1205 r >>= 16; |
|
1206 } |
|
1207 if( l > 0 ) |
|
1208 { |
|
1209 *q = (TUint8)(r & 0xFF); |
|
1210 } |
|
1211 } |
|
1212 } |
|
1213 |
|
1214 GLDEF_C void FillRandomBuffer( HBufC8* aBuf, TRandGen& aRand ) |
|
1215 /** |
|
1216 * Fill buffer aBuf with data generated by aRand |
|
1217 * For convenience this version takes a HBufC8* |
|
1218 */ |
|
1219 { |
|
1220 TPtr8 ptr = aBuf->Des(); |
|
1221 FillRandomBuffer( ptr, aRand ); |
|
1222 } |
|
1223 |
|
1224 |
|
1225 /** |
|
1226 @SYMTestCaseID PBASE-T_MMCDRV-0164 |
|
1227 @SYMTestCaseDesc Test MMC Drive Capabilities |
|
1228 @SYMTestPriority High |
|
1229 |
|
1230 @SYMTestActions |
|
1231 a. Obtain MMC Drive Capabilities |
|
1232 b. If the card size is greater than 2GBytes, test that the driver reports FAT32 file system supported. |
|
1233 c. Test that the type of media is reported as EMediaHardDisk |
|
1234 d. Test that the drive attributes report KDriveAttLocal and KDriveAttRemovable |
|
1235 e. Test that the drive attributes do not report KDriveAttRemote |
|
1236 f. If the drive is not write protected or a ROM card, test that the media attributes report that the drive is formattable |
|
1237 g. If the drive is write protected or a ROM card, test that the media attributes do not report that the drive is formattable |
|
1238 h. Test that the media attributes do not report variable sized media. |
|
1239 |
|
1240 @SYMTestExpectedResults All tests must pass |
|
1241 |
|
1242 @SYMPREQ1389 CR0795 Support for >2G SD Cards |
|
1243 */ |
|
1244 TBool TestDriveInfo() |
|
1245 { |
|
1246 test.Next( _L("Test drive info") ); |
|
1247 |
|
1248 TEST_FOR_ERROR( TheMmcDrive.Caps( DriveCaps ) ); |
|
1249 |
|
1250 test.Printf( _L("Caps V1:\n\tiSize=0x%lx\n\tiType=%d\n\tiBattery=%d\n\tiDriveAtt=0x%x\n\tiMediaAtt=0x%x\n\tiBaseAddress=0x%x\n\tiFileSystemId=0x%x\n\tiPartitionType=0x%x\n"), |
|
1251 DriveCaps().iSize, |
|
1252 DriveCaps().iType, |
|
1253 DriveCaps().iBattery, |
|
1254 DriveCaps().iDriveAtt, |
|
1255 DriveCaps().iMediaAtt, |
|
1256 DriveCaps().iBaseAddress, |
|
1257 DriveCaps().iFileSystemId, |
|
1258 DriveCaps().iPartitionType ); |
|
1259 |
|
1260 test.Printf( _L("Caps V2:\n\tiHiddenSectors=0x%x\n\tiEraseBlockSize=0x%x\nCaps V3:\n\tiExtraInfo=%x\n\tiMaxBytesPerFormat=0x%x\n"), |
|
1261 DriveCaps().iHiddenSectors, |
|
1262 DriveCaps().iEraseBlockSize, |
|
1263 DriveCaps().iExtraInfo, |
|
1264 DriveCaps().iMaxBytesPerFormat ); |
|
1265 |
|
1266 test.Printf( _L("Format info:\n\tiCapacity=0x%lx\n\tiSectorsPerCluster=0x%x\n\tiSectorsPerTrack=0x%x\n\tiNumberOfSides=0x%x\n\tiFatBits=%d\n"), |
|
1267 DriveCaps().iFormatInfo.iCapacity, |
|
1268 DriveCaps().iFormatInfo.iSectorsPerCluster, |
|
1269 DriveCaps().iFormatInfo.iSectorsPerTrack, |
|
1270 DriveCaps().iFormatInfo.iNumberOfSides, |
|
1271 DriveCaps().iFormatInfo.iFATBits ); |
|
1272 |
|
1273 if(DriveCaps().iSerialNumLength > 0) |
|
1274 { |
|
1275 test.Printf( _L("Serial Number : ") ); |
|
1276 TBuf8<2*KMaxSerialNumLength> snBuf; |
|
1277 TUint i; |
|
1278 for (i=0; i<DriveCaps().iSerialNumLength; i++) |
|
1279 { |
|
1280 snBuf.AppendNumFixedWidth( DriveCaps().iSerialNum[i], EHex, 2 ); |
|
1281 test.Printf( _L("%02x"), DriveCaps().iSerialNum[i]); |
|
1282 } |
|
1283 test.Printf( _L("\n") ); |
|
1284 |
|
1285 CardType = TKnownCardTypes::EStandardCard; |
|
1286 for(i=0; i < sizeof(KnownCardTypes) / sizeof(TKnownCardTypes); i++) |
|
1287 { |
|
1288 TPtrC8 serial(KnownCardTypes[i].iSerialNumber); |
|
1289 if(snBuf.Compare(serial) == 0) |
|
1290 { |
|
1291 CardType = KnownCardTypes[i].iCardType; |
|
1292 break; |
|
1293 } |
|
1294 } |
|
1295 } |
|
1296 else |
|
1297 { |
|
1298 test.Printf( _L("Serial Number : Not Supported") ); |
|
1299 } |
|
1300 |
|
1301 // DriveSize - The size of the partition to which the test is connected. |
|
1302 // MediaSize - The entire size of the media containing the partition. |
|
1303 |
|
1304 TInt64 mediaSize = DriveCaps().MediaSizeInBytes(); |
|
1305 TheMmcDrive.SetSize(DriveCaps().iSize, mediaSize); |
|
1306 if(mediaSize == 0) |
|
1307 { |
|
1308 test.Printf(_L("Check entire media size: Not Supported\r\n")); |
|
1309 } |
|
1310 |
|
1311 test.Printf(_L("Entire media size: %ld\r\n"),mediaSize); |
|
1312 test.Printf(_L("Partition size: %ld\r\n"),DriveCaps().iSize); |
|
1313 test.Printf(_L("Hidden sectors: %d\r\n"),DriveCaps().iHiddenSectors); |
|
1314 |
|
1315 |
|
1316 TEST_FOR_VALUE( DriveCaps().iFileSystemId, KDriveFileSysFAT ); |
|
1317 |
|
1318 // Test that a drive >2GB is marked as requesting FAT32 |
|
1319 if( DriveCaps().iSize > KTwoGigbytes && DriveCaps().iExtraInfo) |
|
1320 { |
|
1321 TEST_FOR_VALUE( DriveCaps().iFormatInfo.iFATBits, TLDFormatInfo::EFB32 ); |
|
1322 } |
|
1323 |
|
1324 TEST_FOR_VALUE( DriveCaps().iType, EMediaHardDisk ); |
|
1325 |
|
1326 const TUint KExpectedDriveAtt = KDriveAttLocal | KDriveAttRemovable; |
|
1327 const TUint KNotExpectedDriveAtt = KDriveAttRemote; |
|
1328 TEST_FOR_VALUE( DriveCaps().iDriveAtt & KExpectedDriveAtt, KExpectedDriveAtt ); |
|
1329 TEST_FOR_VALUE( DriveCaps().iDriveAtt & KNotExpectedDriveAtt, 0 ); |
|
1330 |
|
1331 TUint expectedMediaAtt = KMediaAttFormattable; |
|
1332 TUint notExpectedMediaAtt = KMediaAttVariableSize; |
|
1333 |
|
1334 TBool isReadOnly = DriveCaps().iMediaAtt & KMediaAttWriteProtected; |
|
1335 if(isReadOnly) |
|
1336 { |
|
1337 expectedMediaAtt &= ~KMediaAttFormattable; |
|
1338 |
|
1339 test.Printf( _L("\n ---------------------------\n") ); |
|
1340 test.Printf( _L(" Media is Write Protected\n") ); |
|
1341 if((DriveCaps().iMediaAtt & KMediaAttFormattable) != KMediaAttFormattable) |
|
1342 { |
|
1343 test.Printf( _L(" Media is a ROM card\n") ); |
|
1344 } |
|
1345 test.Printf( _L(" Some tests will be skipped\n") ); |
|
1346 test.Printf( _L(" ---------------------------\n") ); |
|
1347 } |
|
1348 |
|
1349 TEST_FOR_VALUE( DriveCaps().iMediaAtt & expectedMediaAtt, expectedMediaAtt ); |
|
1350 TEST_FOR_VALUE( DriveCaps().iMediaAtt & notExpectedMediaAtt, 0 ); |
|
1351 |
|
1352 return(isReadOnly); |
|
1353 } |
|
1354 |
|
1355 |
|
1356 /** |
|
1357 @SYMTestCaseID PBASE-T_MMCDRV-0165 |
|
1358 @SYMTestCaseDesc Test MMC Card Reads |
|
1359 @SYMTestPriority High |
|
1360 |
|
1361 @SYMTestActions |
|
1362 a. Read 64K in one operation from the start of the media and store the contents. |
|
1363 b. Read 512 byte blocks from the start of the media at various offsets and compare with initial read. |
|
1364 b. Read 64K in 512 byte blocks from the start of the media and compare with the initial read. |
|
1365 c. read 64K from the end of the drive |
|
1366 |
|
1367 @SYMTestExpectedResults All tests must pass |
|
1368 |
|
1369 @SYMPREQ1389 CR0795 Support for >2G SD Cards |
|
1370 */ |
|
1371 void TestRead() |
|
1372 { |
|
1373 // This just tests that we can read *something* from the drive |
|
1374 // We check elsewhere that we can read what we've written |
|
1375 test.Next( _L("Test reading" ) ); |
|
1376 |
|
1377 HBufC8* bigBuf = HBufC8::New( 65536 ); |
|
1378 HBufC8* smallBuf = HBufC8::New( 512 ); |
|
1379 |
|
1380 test( bigBuf != NULL ); |
|
1381 test( smallBuf != NULL ); |
|
1382 TPtr8 bigPtr( bigBuf->Des() ); |
|
1383 TPtr8 smallPtr( smallBuf->Des() ); |
|
1384 |
|
1385 test.Printf( _L("Read block from start of media\n") ); |
|
1386 TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(0), 65536, bigPtr) ); |
|
1387 |
|
1388 test.Printf( _L("Read smaller blocks which should match the data in big block\n\r" ) ); |
|
1389 TInt i; |
|
1390 for( i = 0; i <= 512; ++i ) |
|
1391 { |
|
1392 test.Printf( _L("\toffset: %d\r"), i ); |
|
1393 TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(i), 512, smallPtr ) ); |
|
1394 test( CompareBuffers( smallBuf->Des(), bigBuf->Mid( i, 512 ) ) ); |
|
1395 } |
|
1396 |
|
1397 for( i = 512; i <= 65536-512; i += 512 ) |
|
1398 { |
|
1399 test.Printf( _L("\toffset: %d\r"), i ); |
|
1400 TEST_FOR_ERROR( TheMmcDrive.Read( TInt64(i), 512, smallPtr ) ); |
|
1401 test( CompareBuffers( smallBuf->Des(), bigBuf->Mid( i, 512 ) ) ); |
|
1402 } |
|
1403 |
|
1404 test.Printf( _L("\nTest read from end of drive\n") ); |
|
1405 |
|
1406 if(CardType == TKnownCardTypes::EBuffalloMiniSD_512M || |
|
1407 CardType == TKnownCardTypes::EIntegralHSSD_2G) |
|
1408 { |
|
1409 // These cards have issues with reading at the end of the drive... |
|
1410 test.Printf( _L(" -- Skipping Test - Known card detected --\n") ); |
|
1411 } |
|
1412 else |
|
1413 { |
|
1414 TEST_FOR_ERROR( TheMmcDrive.Read( TheMmcDrive.Size() - 65536, 65536, bigPtr) ); |
|
1415 } |
|
1416 |
|
1417 delete smallBuf; |
|
1418 delete bigBuf; |
|
1419 } |
|
1420 |
|
1421 |
|
1422 /** |
|
1423 @SYMTestCaseID PBASE-T_MMCDRV-0511 |
|
1424 @SYMTestCaseDesc Test Moving Read/Write |
|
1425 @SYMTestPriority High |
|
1426 |
|
1427 @SYMTestActions |
|
1428 a.) Test Read/Verify Whole Sectors |
|
1429 b.) Test Read/Verify Sliding sector sized window |
|
1430 c.) Test Read/Verify Sliding byte sized window |
|
1431 d.) Test Read/Verify Increasing sized window |
|
1432 e.) Test Write/Read/Verify Whole Sectors |
|
1433 f.) Test Write/Read/Verify Sliding sector sized window |
|
1434 g.) Test Write/Read/Verify Increasing sized window |
|
1435 |
|
1436 @SYMTestExpectedResults All tests must pass |
|
1437 */ |
|
1438 void DoReadWriteTest( TInt64 aPos, TInt aWindowSize, TBool aQuick ) |
|
1439 { |
|
1440 // Do various read/write tests within a aWindowSize window starting at aPos |
|
1441 HBufC8* wholeBuf = HBufC8::New( aWindowSize ); |
|
1442 test( wholeBuf != NULL ); |
|
1443 |
|
1444 HBufC8* readBuf = HBufC8::New( aWindowSize ); |
|
1445 test( readBuf != NULL ); |
|
1446 |
|
1447 TBuf8<512> sectorBuf; |
|
1448 TRandGen rand; |
|
1449 |
|
1450 test.Printf( _L("Walking sector read\n\r") ); |
|
1451 FillRandomBuffer( wholeBuf, rand ); |
|
1452 TPtr8 wholeBufPtr( wholeBuf->Des() ); |
|
1453 TEST_FOR_ERROR( TheMmcDrive.Write( aPos, *wholeBuf ) ); |
|
1454 |
|
1455 // Read each sector back and check that it's correct |
|
1456 TInt64 pos( aPos ); |
|
1457 TInt i; |
|
1458 for( i = 0; i < aWindowSize - 512; i += 512 ) |
|
1459 { |
|
1460 pos = aPos + i; |
|
1461 test.Printf(_L("\tRead @0x%lx\r"), pos); |
|
1462 TEST_FOR_ERROR( TheMmcDrive.Read( pos, 512, sectorBuf ) ); |
|
1463 test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 512 ) ) ); |
|
1464 } |
|
1465 |
|
1466 test.Printf( _L("\nSliding sector read\n\r") ); |
|
1467 // Slide a sector-sized window over the data |
|
1468 TInt maxl = Min( aWindowSize - 512, 512 * 3 ); |
|
1469 for( i = 0; i < maxl; i++ ) |
|
1470 { |
|
1471 pos = aPos + i; |
|
1472 test.Printf(_L("\tRead @0x%lx\r"), pos); |
|
1473 TEST_FOR_ERROR( TheMmcDrive.Read( pos, 512, sectorBuf ) ); |
|
1474 test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 512 ) ) ); |
|
1475 } |
|
1476 |
|
1477 if( !aQuick ) |
|
1478 { |
|
1479 test.Printf( _L("\nSliding byte read\n\r") ); |
|
1480 // Slide a byte-sized window over the data |
|
1481 for( i = 0; i < maxl; i++ ) |
|
1482 { |
|
1483 pos = aPos + i; |
|
1484 test.Printf(_L("\tRead @0x%lx\r"), pos); |
|
1485 TEST_FOR_ERROR( TheMmcDrive.Read( pos, 1, sectorBuf ) ); |
|
1486 test( CompareBuffers( sectorBuf, wholeBuf->Mid( i, 1 ) ) ); |
|
1487 } |
|
1488 |
|
1489 test.Printf( _L("\nGrowing read\n\r") ); |
|
1490 // Read from an increasing-sized window |
|
1491 for( i = 1; i < 512; i++ ) |
|
1492 { |
|
1493 test.Printf(_L("\tRead length: %d\r"), i); |
|
1494 TEST_FOR_ERROR( TheMmcDrive.Read( aPos, i, sectorBuf ) ); |
|
1495 test( CompareBuffers( sectorBuf, wholeBuf->Left( i ) ) ); |
|
1496 } |
|
1497 |
|
1498 test.Printf( _L("\nDownward-expanding read\n\r") ); |
|
1499 // Read from a window that grows downward from the end of the test region |
|
1500 for( i = 1; i <= 512; i++ ) |
|
1501 { |
|
1502 pos = aPos + aWindowSize - i; |
|
1503 test.Printf(_L("\t[pos:len] %lx:%d\r"), pos, i); |
|
1504 TEST_FOR_ERROR( TheMmcDrive.Read( pos, i, sectorBuf ) ); |
|
1505 test( CompareBuffers( sectorBuf, wholeBuf->Mid( aWindowSize - i, i ) ) ); |
|
1506 } |
|
1507 } |
|
1508 |
|
1509 test.Printf( _L("\nWalking sector write\n\r") ); |
|
1510 // Overwrite each sector and check the whole region is correct |
|
1511 for( i = 0; i < aWindowSize - 512; i += 512 ) |
|
1512 { |
|
1513 FillRandomBuffer( sectorBuf, rand ); |
|
1514 pos = aPos + i; |
|
1515 test.Printf(_L("\tWrite @0x%lx\r"), pos); |
|
1516 TEST_FOR_ERROR( TheMmcDrive.Write( pos, sectorBuf ) ); |
|
1517 wholeBufPtr.MidTPtr( i, 512 ) = sectorBuf; // update our match data |
|
1518 |
|
1519 TPtr8 ptr( readBuf->Des() ); |
|
1520 TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) ); |
|
1521 test( CompareBuffers( *readBuf, *wholeBuf ) ); |
|
1522 } |
|
1523 |
|
1524 if( !aQuick ) |
|
1525 { |
|
1526 test.Printf( _L("\nSliding sector overwrite\n\r") ); |
|
1527 // Overwrite a sector-sized region that slides across the test region |
|
1528 for( i = 0; i < maxl; i += 1 ) |
|
1529 { |
|
1530 FillRandomBuffer( sectorBuf, rand ); |
|
1531 pos = aPos + i; |
|
1532 test.Printf(_L("\tWrite @0x%lx\r"), pos); |
|
1533 TEST_FOR_ERROR( TheMmcDrive.Write( pos, sectorBuf ) ); |
|
1534 wholeBufPtr.MidTPtr( i, 512 ) = sectorBuf; // update our match data |
|
1535 |
|
1536 TPtr8 ptr( readBuf->Des() ); |
|
1537 TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) ); |
|
1538 test( CompareBuffers( *readBuf, *wholeBuf ) ); |
|
1539 } |
|
1540 |
|
1541 test.Printf( _L("\nGrowing sector overwrite\n\r") ); |
|
1542 // Overwrite an expanding region starting at aPos |
|
1543 for( i = 1; i < 512; i += 1 ) |
|
1544 { |
|
1545 FillRandomBuffer( sectorBuf, rand ); |
|
1546 test.Printf(_L("\tWrite length: %d\r"), i); |
|
1547 sectorBuf.SetLength( i ); |
|
1548 TEST_FOR_ERROR( TheMmcDrive.Write( aPos, sectorBuf ) ); |
|
1549 wholeBufPtr.LeftTPtr( i ) = sectorBuf; // update our match data |
|
1550 |
|
1551 TPtr8 ptr( readBuf->Des() ); |
|
1552 TEST_FOR_ERROR( TheMmcDrive.Read( aPos, aWindowSize, ptr ) ); |
|
1553 test( CompareBuffers( *readBuf, *wholeBuf ) ); |
|
1554 } |
|
1555 } |
|
1556 |
|
1557 test.Printf( _L("\nTest zero-length read\n") ); |
|
1558 FillRandomBuffer( sectorBuf, rand ); |
|
1559 TEST_FOR_ERROR( TheMmcDrive.Read( aPos, 0, sectorBuf ) ); |
|
1560 TEST_FOR_VALUE( sectorBuf.Length(), 0 ); |
|
1561 |
|
1562 delete wholeBuf; |
|
1563 delete readBuf; |
|
1564 } |
|
1565 |
|
1566 |
|
1567 // This tests for a bug observed in certain ESanDiskMmcMobile_1GB cards which never exit the busy state |
|
1568 // when writing a buffer which is one sector bigger than the PSL buffer size (resulting in a single write |
|
1569 // request split into 2 fragments, the last of which is one sector only). The "fix" for this is to make the |
|
1570 // PSL reject CMD23 (SET_BLOCK_COUNT) for these particular cards, forcing the PIL to issue a CMD12 (STOP_TRANSMISSION) |
|
1571 void TestFragmentedWrite(TInt aLength) |
|
1572 { |
|
1573 test.Next( _L("Test a large write just bigger than PSL buffer size") ); |
|
1574 |
|
1575 HBufC8* bigBuf = HBufC8::New( aLength); |
|
1576 test( bigBuf != NULL ); |
|
1577 TPtr8 bigPtr( bigBuf->Des() ); |
|
1578 |
|
1579 TInt64 startPos = 0; |
|
1580 |
|
1581 // for a dual-slot enabled H4, buffer size is 132K - (512 * 2) = 131K |
|
1582 |
|
1583 |
|
1584 test.Printf( _L("Initializing buffer contents...\n")); |
|
1585 bigPtr.SetLength(aLength); |
|
1586 TInt n; |
|
1587 for (n=0; n<aLength; n++) |
|
1588 { |
|
1589 bigPtr[n] = (TUint8) n; |
|
1590 } |
|
1591 |
|
1592 bigPtr.SetLength(aLength); |
|
1593 test.Printf( _L("Write %d sectors\n"), bigPtr.Length() / 512); |
|
1594 TEST_FOR_ERROR( TheMmcDrive.Write( startPos, bigPtr) ); |
|
1595 |
|
1596 |
|
1597 bigPtr.SetLength(aLength); |
|
1598 bigPtr.FillZ(); |
|
1599 |
|
1600 test.Printf( _L("Read %d sectors\n"), bigPtr.Length() / 512); |
|
1601 TEST_FOR_ERROR( TheMmcDrive.Read( startPos, bigPtr.Length(), bigPtr) ); |
|
1602 |
|
1603 test.Printf( _L("Read #1 len %d \n"), bigPtr.Length()); |
|
1604 |
|
1605 for (n=0; n< 0 + aLength; n++) |
|
1606 { |
|
1607 if (bigPtr[n] != (TUint8) n) |
|
1608 { |
|
1609 test.Printf(_L("mismatch at %lx [0x%02x] != [0x%02x]"), n, bigPtr[n], (TUint8) n); |
|
1610 test(0); |
|
1611 } |
|
1612 } |
|
1613 |
|
1614 delete bigBuf; |
|
1615 } |
|
1616 |
|
1617 void TestWrite() |
|
1618 { |
|
1619 // for a dual-slot enabled H4, buffer size is 132K - (512 * 2) = 131K |
|
1620 TestFragmentedWrite(131*1024 + 512); |
|
1621 // for a single-slot enabled H4, buffer size is 132K - (512 * 1) = 131K + 512 |
|
1622 TestFragmentedWrite(131*1024 + 1024); |
|
1623 |
|
1624 |
|
1625 test.Next( _L("Test writing to drive") ); |
|
1626 DoReadWriteTest( 0, 65536, EFalse ); |
|
1627 } |
|
1628 |
|
1629 |
|
1630 /** |
|
1631 @SYMTestCaseID PBASE-T_MMCDRV-0166 |
|
1632 @SYMTestCaseDesc Test MMC Card accesses at the end of the media |
|
1633 @SYMTestPriority High |
|
1634 |
|
1635 @SYMTestActions |
|
1636 a. If the card is not read-only, perform read/write tests at the last 64K of the media. |
|
1637 b. Test that all accesses beyond the end of the media produce an error. |
|
1638 |
|
1639 @SYMTestExpectedResults All tests must pass |
|
1640 |
|
1641 @SYMPREQ1389 CR0795 Support for >2G SD Cards |
|
1642 */ |
|
1643 void TestCapacity() |
|
1644 { |
|
1645 if(!IsReadOnly) |
|
1646 { |
|
1647 test.Next( _L("Test access at end of media") ); |
|
1648 DoReadWriteTest( TheMmcDrive.Size() - 65536, 65536, ETrue ); |
|
1649 } |
|
1650 |
|
1651 test.Printf( _L("Test accesses past end of media produce an error\n") ); |
|
1652 |
|
1653 TBuf8<1024> buf; |
|
1654 |
|
1655 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 1, buf ) ); |
|
1656 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 2, buf ) ); |
|
1657 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size(), 512, buf ) ); |
|
1658 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() + 1, 512, buf ) ); |
|
1659 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() + 512, 512, buf ) ); |
|
1660 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 1, 2, buf ) ); |
|
1661 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 511, 512, buf ) ); |
|
1662 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 512, 513, buf ) ); |
|
1663 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 65536, 65537, buf ) ); |
|
1664 test( KErrNone != TheMmcDrive.Read( TheMmcDrive.Size() - 512, 1024, buf ) ); |
|
1665 } |
|
1666 |
|
1667 |
|
1668 void WriteAcrossBoundaries(TInt64 aBoundary) |
|
1669 { |
|
1670 test.Printf( _L("Test for aliasing around boundary\n") ); |
|
1671 TBuf8<512> bufLo; |
|
1672 TBuf8<512> bufHi; |
|
1673 TBuf8<8192> bufRead; |
|
1674 |
|
1675 bufLo.Fill( 0xE4, 512 ); |
|
1676 bufHi.Fill( 0x19, 512 ); |
|
1677 |
|
1678 TEST_FOR_ERROR( TheMmcDrive.Write( 0, bufLo ) ); |
|
1679 TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) ); |
|
1680 TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) ); |
|
1681 test( bufRead == bufLo ); |
|
1682 TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) ); |
|
1683 test( bufRead == bufHi ); |
|
1684 |
|
1685 bufHi.Fill( 0xBB, 1 ); |
|
1686 TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) ); |
|
1687 TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) ); |
|
1688 test( bufRead == bufLo ); |
|
1689 |
|
1690 bufHi.Fill( 0xCC, 1 ); |
|
1691 TEST_FOR_ERROR( TheMmcDrive.Write( (aBoundary+1), bufHi ) ); |
|
1692 TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) ); |
|
1693 test( bufRead == bufLo ); |
|
1694 |
|
1695 test.Printf( _L("Test write which ends at boundary\n") ); |
|
1696 bufHi.Fill( 0x33, 512 ); |
|
1697 TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary, bufHi ) ); |
|
1698 TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) ); |
|
1699 test( bufRead == bufHi ); |
|
1700 |
|
1701 bufHi.Fill( 0x44, 512 ); |
|
1702 TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512, bufHi ) ); |
|
1703 TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary - 512, 512, bufRead ) ); |
|
1704 test( bufRead == bufHi ); |
|
1705 |
|
1706 TEST_FOR_ERROR( TheMmcDrive.Read( 0, 512, bufRead ) ); |
|
1707 test( bufRead == bufLo ); |
|
1708 |
|
1709 bufHi.Fill( 0x33, 512 ); |
|
1710 TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary, 512, bufRead ) ); |
|
1711 test( bufRead == bufHi ); |
|
1712 |
|
1713 test.Printf( _L("Test read-modify-write across boundary\n") ); |
|
1714 TBuf8<512> rmw; |
|
1715 TBuf8<8192> data; |
|
1716 rmw.Fill( 0x66, 512 ); |
|
1717 data.Fill( 0x11, 8192 ); |
|
1718 |
|
1719 for( TInt i = 1; i < 511; ++i ) |
|
1720 { |
|
1721 ProgressBar(i, 511, 11); |
|
1722 |
|
1723 // Create initial data block |
|
1724 TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512, data ) ); |
|
1725 |
|
1726 // Read-modify-write some data |
|
1727 TEST_FOR_ERROR( TheMmcDrive.Write( aBoundary - 512 + i, rmw ) ); |
|
1728 |
|
1729 // Modify buffer to what we expect |
|
1730 data.MidTPtr( i, 512 ) = rmw; |
|
1731 |
|
1732 // Read it back and check it matches |
|
1733 TEST_FOR_ERROR( TheMmcDrive.Read( aBoundary - 512, 8192, bufRead ) ); |
|
1734 test( CompareBuffers( bufRead, data ) ); |
|
1735 } |
|
1736 test.Printf(_L("\n")); |
|
1737 } |
|
1738 |
|
1739 |
|
1740 /** |
|
1741 @SYMTestCaseID PBASE-T_MMCDRV-0167 |
|
1742 @SYMTestCaseDesc Test that the boundary >2GB doesn't produce aliases or errors |
|
1743 @SYMTestPriority High |
|
1744 |
|
1745 @SYMTestActions |
|
1746 a. Test that writing at the 2G boundary does not produce aliases. |
|
1747 b. Test writes that end at the 2G boundary. |
|
1748 c. Test read/modify/write across the 2G boundary. |
|
1749 |
|
1750 @SYMTestExpectedResults All tests must pass |
|
1751 |
|
1752 @SYMPREQ1389 CR0795 Support for >2G SD Cards |
|
1753 */ |
|
1754 void TestBoundaries() |
|
1755 { |
|
1756 |
|
1757 if( TheMmcDrive.Size() < 0x80008000 ) |
|
1758 { |
|
1759 test.Printf( _L("Drive not large enough for 2GB boundary test... skipped\n") ); |
|
1760 return; |
|
1761 } |
|
1762 |
|
1763 // Test that the boundary 2GB doesn't produce aliases or errors |
|
1764 // >2Gb cards change addressing scheme from byte to block base |
|
1765 test.Next( _L("Test 2GB boundary") ); |
|
1766 WriteAcrossBoundaries(0x80000000); |
|
1767 |
|
1768 // N.B. Commented Out for now due to compiler warnings |
|
1769 // if( TheMmcDrive.Size() < 0x100008000ll ) |
|
1770 // { |
|
1771 // test.Printf( _L("Drive not large enough for 4GB boundary test... skipped\n") ); |
|
1772 // return; |
|
1773 // } |
|
1774 // // Test that the boundary 4GB doesn't produce aliases or errors |
|
1775 // // >4GB cards change addressing scheme from 32bit to 64bit addresses |
|
1776 // test.Next( _L("Test 4GB boundary") ); |
|
1777 // WriteAcrossBoundaries(0x100000000ll); |
|
1778 } |
|
1779 |
|
1780 |
|
1781 /** |
|
1782 @SYMTestCaseID PBASE-T_MMCDRV-0512 |
|
1783 @SYMTestCaseDesc Test Media Change/Capabilities Reporting |
|
1784 @SYMTestPriority High |
|
1785 |
|
1786 @SYMTestActions |
|
1787 a.) Test Media Change flag after Media Change |
|
1788 b.) Test Capabilities reporting for Out Of Memory Conditions |
|
1789 c.) Test Media Change flag after Machine power-off |
|
1790 d.) Test Capabilities reporting after Machine power-off |
|
1791 e.) Test Multiple Media Change flags after Media Change |
|
1792 |
|
1793 @SYMTestExpectedResults All tests must pass |
|
1794 */ |
|
1795 void TestMediaChange() |
|
1796 { |
|
1797 test.Next(_L("MMC drive: Media change")); |
|
1798 #if defined (__WINS__) |
|
1799 test.Printf( _L("<<<Hit F5 - then any other key>>>\r\n")); |
|
1800 #else |
|
1801 test.Printf( _L("<<<Generate Media change - then hit a key>>>\r\n")); |
|
1802 #endif |
|
1803 test.Getch(); |
|
1804 User::After(300000); // Allow 0.3s after power down for controller to detect door closed. |
|
1805 test(ChangeFlag!=EFalse); |
|
1806 |
|
1807 test.Next(_L("MMC drive: Caps following media change")); |
|
1808 |
|
1809 TLocalDriveCapsV4 info; |
|
1810 TPckg<TLocalDriveCapsV4> infoPckg(info); |
|
1811 |
|
1812 test(TheMmcDrive.Caps(infoPckg)==KErrNone); |
|
1813 test(info.iType==EMediaHardDisk); |
|
1814 |
|
1815 test.Next(_L("MMC drive: Caps while OOM")); |
|
1816 TInt err; |
|
1817 test.Printf(_L("Mount returns:")); |
|
1818 for (TInt j=1;j<16;j++) |
|
1819 { |
|
1820 __KHEAP_SETFAIL(RHeap::EDeterministic,j); |
|
1821 err=TheMmcDrive.Caps(infoPckg); |
|
1822 test.Printf(_L("(%d)"),err); |
|
1823 __KHEAP_RESET; |
|
1824 } |
|
1825 test.Printf(_L("\r\n")); |
|
1826 |
|
1827 test.Next(_L("MMC drive: Machine power-off.")); |
|
1828 ChangeFlag=EFalse; |
|
1829 RTimer timer; |
|
1830 TRequestStatus trs; |
|
1831 test(timer.CreateLocal()==KErrNone); |
|
1832 TTime tim; |
|
1833 tim.HomeTime(); |
|
1834 tim+=TTimeIntervalSeconds(8); |
|
1835 timer.At(trs,tim); |
|
1836 UserHal::SwitchOff(); |
|
1837 User::WaitForRequest(trs); |
|
1838 test(trs.Int()==KErrNone); |
|
1839 test(ChangeFlag==EFalse); // ie machine power off hasn't updated it |
|
1840 |
|
1841 test.Next(_L("MMC drive: Caps following power off")); |
|
1842 TInt r=TheMmcDrive.Caps(infoPckg); |
|
1843 test(r==KErrNone); |
|
1844 test(info.iType==EMediaHardDisk); |
|
1845 |
|
1846 test.Next(_L("Starting 2nd thread")); |
|
1847 SecThreadChangeFlag=EFalse; |
|
1848 RThread thread; |
|
1849 TRequestStatus stat; |
|
1850 test(thread.Create(_L("Thread"),dontDisconnectThread,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone); |
|
1851 thread.Logon(stat); |
|
1852 thread.Resume(); |
|
1853 User::WaitForRequest(stat); |
|
1854 test(stat==KErrNone); |
|
1855 thread.Close(); |
|
1856 |
|
1857 test.Next(_L("MMC drive: 2nd media change")); |
|
1858 // UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change |
|
1859 test(ChangeFlag!=EFalse); |
|
1860 test(SecThreadChangeFlag==EFalse); // Closed 2nd thread so shouldn't have been updated |
|
1861 } |
|
1862 |
|
1863 |
|
1864 //// End of Test |
|
1865 void Format() |
|
1866 // |
|
1867 // Format current drive |
|
1868 // |
|
1869 { |
|
1870 RFs TheFs; |
|
1871 test(TheFs.Connect() == KErrNone); |
|
1872 |
|
1873 test.Next(_L("Format")); |
|
1874 TBuf<4> driveBuf=_L("?:\\"); |
|
1875 driveBuf[0]=(TText)(RFsDNum+'A'); |
|
1876 |
|
1877 RFormat format; |
|
1878 TInt count; |
|
1879 TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count); |
|
1880 test(r==KErrNone); |
|
1881 while(count) |
|
1882 { |
|
1883 TInt r=format.Next(count); |
|
1884 test(r==KErrNone); |
|
1885 } |
|
1886 format.Close(); |
|
1887 } |
|
1888 |
|
1889 void AllocateBuffers() |
|
1890 { |
|
1891 test.Next(_L("Allocate Buffers")); |
|
1892 |
|
1893 //HBufC8* wrBufH = NULL; |
|
1894 //HBufC8* rdBufH = NULL; |
|
1895 |
|
1896 wrBufH = HBufC8::New(KVeryLongRdWrBufLen); |
|
1897 test(wrBufH != NULL); |
|
1898 |
|
1899 rdBufH = HBufC8::New(KVeryLongRdWrBufLen); |
|
1900 if(rdBufH == NULL) delete wrBufH; |
|
1901 test(rdBufH != NULL); |
|
1902 |
|
1903 wrBuf.Set(wrBufH->Des()); |
|
1904 rdBuf.Set(rdBufH->Des()); |
|
1905 } |
|
1906 |
|
1907 void AllocateSharedBuffers(TBool Fragmented, TBool Caching) |
|
1908 { |
|
1909 // Setup SharedMemory Buffers |
|
1910 test.Next(_L("Allocate Shared Memory\n")); |
|
1911 |
|
1912 RLoader l; |
|
1913 test(l.Connect()==KErrNone); |
|
1914 test(l.CancelLazyDllUnload()==KErrNone); |
|
1915 l.Close(); |
|
1916 |
|
1917 test.Printf(_L("Initialise\n")); |
|
1918 TInt r = UserHal::PageSizeInBytes(PageSize); |
|
1919 test(r==KErrNone); |
|
1920 |
|
1921 test.Printf(_L("Loading test driver\n")); |
|
1922 r = User::LoadLogicalDevice(KSharedChunkLddName); |
|
1923 test(r==KErrNone || r==KErrAlreadyExists); |
|
1924 |
|
1925 test.Printf(_L("Opening channel\n")); |
|
1926 r = Ldd.Open(); |
|
1927 test(r==KErrNone); |
|
1928 |
|
1929 test.Printf(_L("Create chunk\n")); |
|
1930 |
|
1931 TUint aCreateFlags = EMultiple|EOwnsMemory; |
|
1932 |
|
1933 if (Caching) |
|
1934 { |
|
1935 test.Printf(_L("Chunk Type:Caching\n")); |
|
1936 aCreateFlags |= ECached; |
|
1937 } |
|
1938 else |
|
1939 test.Printf(_L("Chunk Type:Fully Blocking\n")); |
|
1940 |
|
1941 TCommitType aCommitType = EContiguous; |
|
1942 |
|
1943 TUint TotalChunkSize = ChunkSize; // rounded to nearest Page Size |
|
1944 |
|
1945 TUint ChunkAttribs = TotalChunkSize|aCreateFlags; |
|
1946 r = Ldd.CreateChunk(ChunkAttribs); |
|
1947 test(r==KErrNone); |
|
1948 |
|
1949 if(Fragmented) |
|
1950 { |
|
1951 test.Printf(_L("Commit Fragmented Memory\n")); |
|
1952 |
|
1953 // Allocate Pages in reverse order to maximise memory fragmentation |
|
1954 TUint i = ChunkSize; |
|
1955 do |
|
1956 { |
|
1957 i-=PageSize; |
|
1958 test.Printf(_L("Commit %d\n"), i); |
|
1959 r = Ldd.CommitMemory(aCommitType|i,PageSize); |
|
1960 test(r==KErrNone); |
|
1961 }while (i>0); |
|
1962 } |
|
1963 else |
|
1964 { |
|
1965 test.Printf(_L("Commit Contigouos Memory\n")); |
|
1966 r = Ldd.CommitMemory(aCommitType,TotalChunkSize); |
|
1967 test(r==KErrNone); |
|
1968 } |
|
1969 |
|
1970 test.Printf(_L("Open user handle\n")); |
|
1971 r = Ldd.GetChunkHandle(TheChunk); |
|
1972 test(r==KErrNone); |
|
1973 |
|
1974 } |
|
1975 |
|
1976 |
|
1977 void DeAllocateBuffers() |
|
1978 { |
|
1979 delete rdBufH; |
|
1980 delete wrBufH; |
|
1981 } |
|
1982 |
|
1983 void DeAllocareSharedMemory() |
|
1984 { |
|
1985 // destory chunk |
|
1986 test.Printf(_L("Shared Memory\n")); |
|
1987 test.Printf(_L("Close user chunk handle\n")); |
|
1988 TheChunk.Close(); |
|
1989 |
|
1990 test.Printf(_L("Close kernel chunk handle\n")); |
|
1991 TInt r = Ldd.CloseChunk(); // 1==DObject::EObjectDeleted |
|
1992 test(r==1); |
|
1993 |
|
1994 test.Printf(_L("Check chunk is destroyed\n")); |
|
1995 r = Ldd.IsDestroyed(); |
|
1996 test(r==1); |
|
1997 |
|
1998 test.Printf(_L("Close test driver\n")); |
|
1999 Ldd.Close(); |
|
2000 } |
|
2001 |
|
2002 |
|
2003 TBool SetupDrivesForPlatform(TInt& aDrive, TInt &aRFsDriveNum) |
|
2004 /** |
|
2005 * Finds a MMC/SD suitable drive for testing |
|
2006 * |
|
2007 * @param aDrive The number of the local drive to test |
|
2008 * @return TBool ETrue if a suitable drive is found, EFalse otherwise. |
|
2009 */ |
|
2010 { |
|
2011 |
|
2012 TDriveInfoV1Buf diBuf; |
|
2013 UserHal::DriveInfo(diBuf); |
|
2014 TDriveInfoV1 &di=diBuf(); |
|
2015 |
|
2016 test.Printf(_L(" iRegisteredDriveBitmask 0x%08X"), di.iRegisteredDriveBitmask); |
|
2017 |
|
2018 aDrive = -1; |
|
2019 |
|
2020 TLocalDriveCapsV5Buf capsBuf; |
|
2021 TBusLocalDrive TBLD; |
|
2022 TLocalDriveCapsV5& caps = capsBuf(); |
|
2023 TPtrC8 localSerialNum; |
|
2024 TInt registeredDriveNum = 0; |
|
2025 for(aDrive=0; aDrive < KMaxLocalDrives; aDrive++) |
|
2026 { |
|
2027 TInt driveNumberMask = 1 << aDrive; |
|
2028 if ((di.iRegisteredDriveBitmask & driveNumberMask) == 0) |
|
2029 continue; |
|
2030 |
|
2031 test.Printf(_L(" Drive %d - %S\r\n"), aDrive, &di.iDriveName[registeredDriveNum]); |
|
2032 |
|
2033 // check that the card is readable (so we can ignore for empty card slots) |
|
2034 if ((di.iDriveName[registeredDriveNum].MatchF(_L("MultiMediaCard0")) == KErrNone) || |
|
2035 (di.iDriveName[registeredDriveNum].MatchF(_L("SDIOCard0")) == KErrNone)) |
|
2036 { |
|
2037 |
|
2038 TBool TBLDChangedFlag; |
|
2039 TInt r = TBLD.Connect(aDrive, TBLDChangedFlag); |
|
2040 //test.Printf(_L(" Connect returned %d\n"), r); |
|
2041 if (r == KErrNone) |
|
2042 { |
|
2043 r = TBLD.Caps(capsBuf); |
|
2044 localSerialNum.Set(caps.iSerialNum, caps.iSerialNumLength); |
|
2045 const TInt KSectSize = 512; |
|
2046 TBuf8<KSectSize> sect; |
|
2047 r = TBLD.Read(0, KSectSize, sect); |
|
2048 //test.Printf(_L(" Read returned %d\n"), r); |
|
2049 |
|
2050 TBLD.Disconnect(); |
|
2051 if (r == KErrNone) |
|
2052 break; |
|
2053 } |
|
2054 } |
|
2055 registeredDriveNum++; |
|
2056 } |
|
2057 |
|
2058 if(aDrive == KMaxLocalDrives) |
|
2059 { |
|
2060 test.Printf(_L(" MMC Drive Not Found\r\n")); |
|
2061 return EFalse; |
|
2062 } |
|
2063 |
|
2064 // Work out the file server drive number (which isn't necessarily the same |
|
2065 // as the TBusLocalDrive drive number) |
|
2066 RFs theFs; |
|
2067 test(theFs.Connect() == KErrNone); |
|
2068 |
|
2069 TInt i; |
|
2070 for (i = EDriveA; i < EDriveZ; i++) |
|
2071 { |
|
2072 TMediaSerialNumber serialNum; |
|
2073 TInt r = theFs.GetMediaSerialNumber(serialNum, i); |
|
2074 TInt len = serialNum.Length(); |
|
2075 TInt n; |
|
2076 for (n=0; n<len; n+=16) |
|
2077 { |
|
2078 TBuf16<16*3 +1> buf; |
|
2079 for (TInt m=n; m<n+16; m++) |
|
2080 { |
|
2081 TBuf16<3> hexBuf; |
|
2082 hexBuf.Format(_L("%02X "),serialNum[m]); |
|
2083 buf.Append(hexBuf); |
|
2084 } |
|
2085 buf.Append(_L("\n")); |
|
2086 test.Printf(buf); |
|
2087 } |
|
2088 if (serialNum.Compare(localSerialNum) == 0) |
|
2089 { |
|
2090 TVolumeInfo vi; |
|
2091 r = theFs.Volume(vi, i); |
|
2092 TBool sizeMatch = (vi.iSize < caps.iSize); |
|
2093 if (sizeMatch) |
|
2094 { |
|
2095 aRFsDriveNum = i; |
|
2096 break; |
|
2097 } |
|
2098 } |
|
2099 |
|
2100 } |
|
2101 if (i == EDriveZ) |
|
2102 { |
|
2103 test.Printf(_L(" RFs MMC Drive Not Found\r\n")); |
|
2104 return EFalse; |
|
2105 } |
|
2106 |
|
2107 theFs.Close(); |
|
2108 |
|
2109 return ETrue; |
|
2110 } |
|
2111 |
|
2112 |
|
2113 LOCAL_D TBool ParseCommandLineArgs() |
|
2114 { |
|
2115 |
|
2116 TBuf<0x100> cmd; |
|
2117 User::CommandLine(cmd); |
|
2118 TLex lex(cmd); |
|
2119 |
|
2120 for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken())) |
|
2121 { |
|
2122 if (token.CompareF(_L("-m"))== 0) |
|
2123 { |
|
2124 ManualMode = ETrue; |
|
2125 continue; |
|
2126 } |
|
2127 } |
|
2128 |
|
2129 if (ManualMode) |
|
2130 { |
|
2131 // Get the list of drives |
|
2132 TDriveInfoV1Buf diBuf; |
|
2133 UserHal::DriveInfo(diBuf); |
|
2134 TDriveInfoV1 &di=diBuf(); |
|
2135 TInt driveCount = di.iTotalSupportedDrives; |
|
2136 |
|
2137 //Print the list of usable drives |
|
2138 test.Printf(_L("\nDRIVES USED AT PRESENT :\r\n")); |
|
2139 |
|
2140 for (TInt i=0; i < driveCount; i++) |
|
2141 { |
|
2142 TBool flag=EFalse; |
|
2143 RLocalDrive d; |
|
2144 TInt r=d.Connect(i,flag); |
|
2145 //Not all the drives are used at present |
|
2146 if (r == KErrNotSupported) |
|
2147 continue; |
|
2148 |
|
2149 test.Printf(_L("%d : DRIVE NAME :%- 16S\r\n"), i, &di.iDriveName[i]); |
|
2150 } |
|
2151 |
|
2152 test.Printf(_L("\r\nWarning - all data on removable drive will be lost.\r\n")); |
|
2153 test.Printf(_L("<<<Hit mmc drive number to continue>>>\r\n")); |
|
2154 |
|
2155 TChar driveToTest; |
|
2156 driveToTest=(TUint)test.Getch(); |
|
2157 DriveNumber=((TUint)driveToTest) - '0'; |
|
2158 test(DriveNumber >= 1 && DriveNumber < di.iTotalSupportedDrives); |
|
2159 |
|
2160 return ETrue; |
|
2161 } |
|
2162 else |
|
2163 { |
|
2164 //Auto Mode |
|
2165 //Lets find an MMC Drive to Test with.... |
|
2166 return SetupDrivesForPlatform(DriveNumber, RFsDNum); |
|
2167 } |
|
2168 } |
|
2169 |
|
2170 |
|
2171 GLDEF_C TInt E32Main() |
|
2172 { |
|
2173 test.Title(); |
|
2174 test.Start(_L("Test the MultiMediaCard (MMC) media driver")); |
|
2175 |
|
2176 if (!ParseCommandLineArgs()) |
|
2177 { |
|
2178 test.Printf(_L("MMC Drive Not Found - Skipping test\r\n")); |
|
2179 test.End(); |
|
2180 return(0); |
|
2181 } |
|
2182 |
|
2183 AllocateBuffers(); |
|
2184 |
|
2185 test.Printf(_L("Connect to local drive (%d)\n"),DriveNumber); |
|
2186 |
|
2187 ChangeFlag=EFalse; |
|
2188 test(TheMmcDrive.Connect(DriveNumber,ChangeFlag)==KErrNone); |
|
2189 |
|
2190 TTime startTime; |
|
2191 startTime.HomeTime(); |
|
2192 |
|
2193 IsReadOnly = TestDriveInfo(); |
|
2194 |
|
2195 // The following line causes t_mmcdrv to jump to the tests that check if the |
|
2196 // mmc driver will carry on reading when the door is opened, but abort with |
|
2197 // KErrGeneral when it is not. Enabling the goto here is useful because it |
|
2198 // allows the tester to skip the long read and write tests, which can take several |
|
2199 // minutes on a 16Mb card, and longer if tracing is enabled. It also stops the test |
|
2200 // from returning when !mediaChangeSupported and not getting to the door opening tests. |
|
2201 |
|
2202 #if TEST_DOOR_CLOSE |
|
2203 goto doorTest; |
|
2204 #endif |
|
2205 |
|
2206 for(TInt pass = 0; pass < TMMCDrive::EMaxTestModes; pass++) |
|
2207 { |
|
2208 TInt r = KErrNone; |
|
2209 switch (pass) |
|
2210 { |
|
2211 case 0 : r = TheMmcDrive.SetTestMode(TMMCDrive::ETestPartition); break; |
|
2212 case 1 : |
|
2213 // don't trash partition table in automated mode because... |
|
2214 // cards in test rigs have often got deliberately small partition sizes to testing (!) |
|
2215 if (!ManualMode) |
|
2216 continue; |
|
2217 r = TheMmcDrive.SetTestMode(TMMCDrive::ETestWholeMedia); |
|
2218 break; |
|
2219 case 2 : { |
|
2220 r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemory); |
|
2221 AllocateSharedBuffers(EFalse,EFalse); |
|
2222 break; |
|
2223 } |
|
2224 case 3 : { |
|
2225 r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryCache); |
|
2226 AllocateSharedBuffers(EFalse, ETrue); |
|
2227 break; |
|
2228 } |
|
2229 case 4 : { |
|
2230 r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryFrag); |
|
2231 AllocateSharedBuffers(ETrue, EFalse); |
|
2232 break; |
|
2233 } |
|
2234 default: { |
|
2235 r = TheMmcDrive.SetTestMode(TMMCDrive::ETestSharedMemoryFragCache); |
|
2236 AllocateSharedBuffers(ETrue, ETrue); |
|
2237 break; |
|
2238 } |
|
2239 } |
|
2240 |
|
2241 |
|
2242 if(r == KErrNone) |
|
2243 { |
|
2244 TestRead(); |
|
2245 TestCapacity(); |
|
2246 |
|
2247 if(IsReadOnly == EFalse) |
|
2248 { |
|
2249 TestMultipleBlockReads(); |
|
2250 TestSectorReadWrite(); |
|
2251 TestWrite(); |
|
2252 TestBoundaries(); |
|
2253 TestFormat(); |
|
2254 } |
|
2255 } |
|
2256 |
|
2257 if (pass > 1) |
|
2258 { |
|
2259 // Shared memory Test Mode in use |
|
2260 DeAllocareSharedMemory(); |
|
2261 } |
|
2262 } |
|
2263 |
|
2264 if (mediaChangeSupported) |
|
2265 { |
|
2266 // Remainder of tests involve media change |
|
2267 TestMediaChange(); |
|
2268 |
|
2269 #if TEST_DOOR_CLOSE |
|
2270 doorTest: |
|
2271 #endif |
|
2272 test.Next(_L("Launching 1.0Mb Read to interrupt with media change.\n")); |
|
2273 TestHugeReadWrite(ETrue, 512 * 1024); |
|
2274 |
|
2275 test.Next(_L("Launching 1.0Mb Write to interrupt with media change.\n")); |
|
2276 TestHugeReadWrite(EFalse, 512 * 1024); |
|
2277 } |
|
2278 |
|
2279 TTime endTime; |
|
2280 endTime.HomeTime(); |
|
2281 TTimeIntervalMicroSeconds elapsed=endTime.MicroSecondsFrom(startTime); |
|
2282 test.Printf(_L("\n\r (Elapsed time: %dmS)\r\n"),(elapsed.Int64()/1000)); |
|
2283 |
|
2284 test.Printf(_L("Disconnect from local drive (%d)"),DriveNumber); |
|
2285 TheMmcDrive.Disconnect(); |
|
2286 |
|
2287 DeAllocateBuffers(); |
|
2288 |
|
2289 // Format card with a File System i.e. FAT |
|
2290 // Such that it is re-usable by next test |
|
2291 Format(); |
|
2292 |
|
2293 test.End(); |
|
2294 |
|
2295 return(0); |
|
2296 } |
|
2297 |