Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

634 lines
28 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/INFTLDBG.C_V $
  3. *
  4. * Rev 1.0 Nov 16 2001 00:44:12 oris
  5. * Initial revision.
  6. *
  7. */
  8. /***********************************************************************************/
  9. /* M-Systems Confidential */
  10. /* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
  11. /* All Rights Reserved */
  12. /***********************************************************************************/
  13. /* NOTICE OF M-SYSTEMS OEM */
  14. /* SOFTWARE LICENSE AGREEMENT */
  15. /* */
  16. /* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
  17. /* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
  18. /* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
  19. /* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
  20. /* E-MAIL = [email protected] */
  21. /***********************************************************************************/
  22. /*************************************************/
  23. /* T r u e F F S 5.0 S o u r c e F i l e s */
  24. /* --------------------------------------------- */
  25. /*************************************************/
  26. /*****************************************************************************
  27. * File Header *
  28. * ----------- *
  29. * Name : inftldbg.c *
  30. * *
  31. * Description : Implementation of INFTL debug routine. *
  32. * *
  33. *****************************************************************************/
  34. /*********************************************************/
  35. /* The following routine are for debuging INFTL chains. */
  36. /* They should not be compiled as part of TrueFFS based */
  37. /* drivers and application. */
  38. /*********************************************************/
  39. /* function prototype */
  40. static FLStatus getUnitData(Bnand vol, ANANDUnitNo unitNo,
  41. ANANDUnitNo *virtualUnitNo, ANANDUnitNo *prevUnitNo,
  42. byte *ANAC, byte *NAC, byte *validFields);
  43. static byte getSectorFlags(Bnand vol, CardAddress sectorAddress);
  44. #ifdef CHECK_MOUNT
  45. extern FILE* tl_out;
  46. /* Macroes */
  47. #define TL_DEBUG_PRINT fprintf
  48. #define STATUS_DEBUG_PRINT printf
  49. #define SET_EXIT(x) vol.debugState |= x /* Add INFTL debug warnnings */
  50. #define DID_MOUNT_FAIL vol.debugState & INFTL_FAILED_MOUNT
  51. #endif /* CHECK_MOUNT */
  52. #ifdef CHAINS_DEBUG
  53. byte * fileNameBuf1 = "Chains00.txt";
  54. byte * fileNameBuf2 = "report.txt";
  55. /*------------------------------------------------------------------------*/
  56. /* g e t F i l e H a n d l e */
  57. /* */
  58. /* Get file handle for debug print output file. */
  59. /* */
  60. /* Parameters: */
  61. /* vol : Pointer identifying drive */
  62. /* type : File name identifier */
  63. /* */
  64. /* Returns: */
  65. /* File handle to ourput file. */
  66. /*------------------------------------------------------------------------*/
  67. #include <string.h>
  68. FILE* getFileHandle(Bnand vol,byte type)
  69. {
  70. char *fileName;
  71. char *logFileExt;
  72. switch (type)
  73. {
  74. case 0:
  75. fileName = fileNameBuf1;
  76. break;
  77. case 1:
  78. fileName = fileNameBuf2;
  79. break;
  80. default:
  81. return NULL;
  82. }
  83. logFileExt = strchr(fileName,'.');
  84. if (logFileExt == NULL)
  85. {
  86. return NULL;
  87. }
  88. else
  89. {
  90. (*(logFileExt-1))++;
  91. }
  92. if (DID_MOUNT_FAIL)
  93. {
  94. return (FILE *)FL_FOPEN(fileName,"a");
  95. }
  96. else
  97. {
  98. return NULL;
  99. }
  100. }
  101. /*------------------------------------------------------------------------*/
  102. /* g o A l o n g V i r t u a l U n i t */
  103. /* */
  104. /* Print the following info for a specified virtual chain: */
  105. /* */
  106. /* Virtual unit number : "Chain #XX :" */
  107. /* Physical unit number : "#XX " */
  108. /* Physical unit ANAC : "(%XX)" */
  109. /* Physical unit NAC : "[%XX]" */
  110. /* Previous unit : "==>:" or "endofchain" */
  111. /* */
  112. /* The virtual unit state can have several comments: */
  113. /* */
  114. /* "FREE" - Legal state where irtual unit has */
  115. /* no physical unit assigned */
  116. /* "Chain XX is too long" - The chains has 2 times the maxium */
  117. /* legal chains length */
  118. /* "Something wrong with chain #XX" - There is a problem with the chain: */
  119. /* a) "this unit should be the last in chain " */
  120. /* The ram convertin table does not have the first in chain mark */
  121. /* for this unit although we know it is the last of its chain. */
  122. /* b) "this unit points to the unit with the different vu no %XX" */
  123. /* The virtual unit field of the current physical unit does not */
  124. /* match the virtual unit number of the chain being inspected. The */
  125. /* new virtual unit is XX */
  126. /* */
  127. /* Parameters: */
  128. /* vol : Pointer identifying drive */
  129. /* virtualUnit : Number of the virtual unit to scan */
  130. /* physUnits : Physical unit table indicating the number of */
  131. /* virtual units each physical unit bellongs to. */
  132. /* out : File pointer for ouput */
  133. /* */
  134. /* Returns: */
  135. /* None */
  136. /*------------------------------------------------------------------------*/
  137. void goAlongVirtualUnit(Bnand vol,word virtualUnit,byte *physUnits,FILE* out)
  138. {
  139. int i;
  140. ANANDUnitNo virtualUnitNo, prevUnitNo,unitNo;
  141. byte ANAC,NAC,parityPerField;
  142. unitNo=vol.virtualUnits[virtualUnit];
  143. FL_FPRINTF(out,"Chain #%d :", virtualUnit);
  144. if(unitNo==ANAND_NO_UNIT)
  145. {
  146. FL_FPRINTF(out,"FREE\n");
  147. return;
  148. }
  149. for(i=0;i<2*MAX_UNIT_CHAIN;i++)
  150. {
  151. if (physUnits != NULL)
  152. physUnits[unitNo]++;
  153. getUnitData(&vol,unitNo,&virtualUnitNo, &prevUnitNo,&ANAC,&NAC,&parityPerField);
  154. FL_FPRINTF(out,"#%d (%d)[%d]==>:",unitNo,ANAC,NAC);
  155. if(vol.physicalUnits[unitNo]&FIRST_IN_CHAIN)
  156. {
  157. FL_FPRINTF(out,"endofchain\n");
  158. return;
  159. }
  160. unitNo=prevUnitNo;
  161. if((prevUnitNo==ANAND_NO_UNIT)||(virtualUnitNo!=virtualUnit))
  162. {
  163. FL_FPRINTF(out,"\nSomething wrong with chain #%d\n",virtualUnit);
  164. TL_DEBUG_PRINT(tl_out,"\nSomething wrong with chain #%d\n",virtualUnit);
  165. SET_EXIT(INFTL_FAILED_MOUNT);
  166. if(prevUnitNo==ANAND_NO_UNIT)
  167. {
  168. FL_FPRINTF(out,"this unit should be the last in chain\n");
  169. TL_DEBUG_PRINT(tl_out,"this unit should be the last in chain (length %d)\n",i);
  170. }
  171. else
  172. {
  173. FL_FPRINTF(out,"this unit points to the unit with the different vu no %d\n",virtualUnitNo);
  174. TL_DEBUG_PRINT(tl_out,"this unit points to the unit with the different vu no %d\n",virtualUnitNo);
  175. }
  176. return;
  177. }
  178. }
  179. FL_FPRINTF(out,"Chain %d is too long \n",virtualUnit);
  180. TL_DEBUG_PRINT(tl_out,"Chain %d is too long \n",virtualUnit);
  181. SET_EXIT(INFTL_FAILED_MOUNT);
  182. }
  183. /*------------------------------------------------------------------------*/
  184. /* c h e c k V i r t u a l C h a i n s */
  185. /* */
  186. /* Print the physical units in each virtual unit of the media */
  187. /* */
  188. /* Parameters: */
  189. /* vol : Pointer identifying drive */
  190. /* out : File pointer to print the result */
  191. /* */
  192. /* Returns: */
  193. /* None */
  194. /*------------------------------------------------------------------------*/
  195. void checkVirtualChains(Bnand vol, FILE* out)
  196. {
  197. word i;
  198. #ifdef FL_MALLOC
  199. byte* physUnits;
  200. #else
  201. byte physUnits[MAX_SUPPORTED_UNITS];
  202. #endif /* FL_MALLOC */
  203. if (vol.noOfVirtualUnits == 0) /* Not format */
  204. {
  205. FL_FPRINTF(out,"\nThis is a format routine since no virtual unit are reported\n");
  206. return;
  207. }
  208. #ifdef FL_MALLOC
  209. physUnits = (byte *)FL_MALLOC(vol.noOfUnits);
  210. if (physUnits == NULL)
  211. #else
  212. if (MAX_SUPPORTED_UNITS < vol.noOfUnits)
  213. #endif /* FL_MALLOC */
  214. {
  215. FL_FPRINTF(out,"\nCheck virtual chains will not check cross links due to lack of memory\n");
  216. TL_DEBUG_PRINT(tl_out,"\nCheck virtual chains will not check cross links due to lack of memory (no of units %d\n",vol.noOfUnits);
  217. SET_EXIT(INFTL_FAILED_MOUNT);
  218. return;
  219. }
  220. if (physUnits != NULL)
  221. tffsset(physUnits,0,vol.noOfUnits);
  222. /* Go along each of the virtual units */
  223. FL_FPRINTF(out,"Chains are :\n");
  224. for(i=0;i<vol.noOfVirtualUnits;i++)
  225. goAlongVirtualUnit(&vol,i,physUnits,out);
  226. FL_FPRINTF(out,"\nChecking if physicl units were used more then once\n");
  227. if (physUnits != NULL)
  228. {
  229. for(i=0;i<vol.noOfUnits;i++)
  230. if(physUnits[i]>1)
  231. {
  232. FL_FPRINTF(out,"Phys unit #%d were used more than once %d\n",i,physUnits[i]);
  233. TL_DEBUG_PRINT(tl_out,"Phys unit #%d were used more than once.\n",i);
  234. TL_DEBUG_PRINT(tl_out,"It was used %d times.\n",physUnits[i]);
  235. SET_EXIT(INFTL_FAILED_MOUNT);
  236. }
  237. }
  238. else
  239. {
  240. FL_FPRINTF(out,"\nCould not check due to lack of memory\n");
  241. }
  242. /* Free memory */
  243. #ifdef FL_MALLOC
  244. FL_FREE(physUnits);
  245. #endif /* FL_MALLOC */
  246. }
  247. /*------------------------------------------------------------------------*/
  248. /* c h e c k V o l u m e S t a t i s t i c s */
  249. /* */
  250. /* Print the volume statistics. */
  251. /* */
  252. /* Parameters: */
  253. /* vol : Pointer identifying drive */
  254. /* out : File pointer to print the result */
  255. /* */
  256. /* Returns: */
  257. /* None */
  258. /*------------------------------------------------------------------------*/
  259. void checkVolumeStatistics(Bnand vol , FILE* out)
  260. {
  261. FL_FPRINTF(out,"\nThe volume statistics are:\n");
  262. FL_FPRINTF(out,"Socket nomber ----------------------------------- %d\n",vol.socketNo);
  263. FL_FPRINTF(out,"The volume internal flags ----------------------- %d\n",vol.flags);
  264. FL_FPRINTF(out,"Number of free units ---------------------------- %d\n",vol.freeUnits);
  265. TL_DEBUG_PRINT(tl_out,"Number of free units ---------------------------- %d\n",vol.freeUnits);
  266. FL_FPRINTF(out,"Number of boot unit ----------------------------- %d\n",vol.bootUnits);
  267. FL_FPRINTF(out,"Number of media units --------------------------- %d\n",vol.noOfUnits);
  268. FL_FPRINTF(out,"Number of virtual units ------------------------- %d\n",vol.noOfVirtualUnits);
  269. FL_FPRINTF(out,"Number of virtual sector on the volume ---------- %ld\n",vol.virtualSectors);
  270. FL_FPRINTF(out,"The media rover unit ---------------------------- %d\n",vol.roverUnit);
  271. FL_FPRINTF(out,"Physical first unit number of the volume -------- %d\n",vol.firstUnit);
  272. #ifdef NFTL_CACHE
  273. FL_FPRINTF(out,"Physical first unit address --------------------- %d\n",vol.firstUnitAddress);
  274. #endif /* NFTL_CACHE */
  275. #ifdef QUICK_MOUNT_FEATURE
  276. FL_FPRINTF(out,"First quick mount unit -------------------------- %d\n",vol.firstQuickMountUnit);
  277. #endif /* QUICK_MOUNT_FEATURE */
  278. FL_FPRINTF(out,"Number of unit with a valid sector count -------- %d\n",vol.countsValid);
  279. FL_FPRINTF(out,"The currently mapped sector number -------------- %ld\n",vol.mappedSectorNo);
  280. FL_FPRINTF(out,"The currently mapped sector address ------------- %ld\n",vol.mappedSectorAddress);
  281. FL_FPRINTF(out,"Number of sectors per unit ---------------------- %d\n",vol.sectorsPerUnit);
  282. FL_FPRINTF(out,"Number of bits needed to shift from block to unit %d\n",vol.blockMultiplierBits);
  283. FL_FPRINTF(out,"Number of bits used to represent a flash block -- %d\n",vol.erasableBlockSizeBits);
  284. FL_FPRINTF(out,"Number of bits used to represent a media unit --- %d\n",vol.unitSizeBits);
  285. FL_FPRINTF(out,"Number of sectors read -------------------------- %ld\n",vol.sectorsRead);
  286. FL_FPRINTF(out,"Number of sectors written ----------------------- %ld\n",vol.sectorsWritten);
  287. FL_FPRINTF(out,"Number of sectors deleted ----------------------- %ld\n",vol.sectorsDeleted);
  288. FL_FPRINTF(out,"Number of parasite write ------------------------ %ld\n",vol.parasiteWrites);
  289. FL_FPRINTF(out,"Number of units folded -------------------------- %ld\n",vol.unitsFolded);
  290. FL_FPRINTF(out,"The total erase counter ------------------------- %ld\n",vol.eraseSum);
  291. FL_FPRINTF(out,"Wear leveling counter limit---------------------- %ld\n",vol.wearLevel.alarm);
  292. FL_FPRINTF(out,"Wear leveling current unit ---------------------- %d\n",vol.wearLevel.currUnit);
  293. FL_FCLOSE(out);
  294. }
  295. #endif /* CHAINS_DEBUG */
  296. #ifdef CHECK_MOUNT
  297. /*------------------------------------------------------------------------*/
  298. /* c h e c k M o u n t I N F T L */
  299. /* */
  300. /* Print Low level errors in INFTL format. */
  301. /* */
  302. /* Parameters: */
  303. /* vol : Pointer identifying drive */
  304. /* */
  305. /* Returns: */
  306. /* flOK on success */
  307. /*------------------------------------------------------------------------*/
  308. FLStatus checkMountINFTL(Bnand vol)
  309. {
  310. ANANDUnitNo erCount=0,freeUnits=0,iUnit;
  311. ANANDUnitNo virtualUnitNo,prevUnitNo;
  312. FLStatus status;
  313. byte pattern[SECTOR_SIZE],tempbuf[SECTOR_SIZE];
  314. byte sectorFlags,ANAC, NAC, prevANAC, parityPerField;
  315. word *erasePatt1;
  316. word *erasePatt2;
  317. word i,temp;
  318. dword sectorAddress;
  319. tffsset(pattern,0xff,SECTOR_SIZE);
  320. for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++)
  321. {
  322. STATUS_DEBUG_PRINT("Checking unit %d\r",iUnit);
  323. if (vol.physicalUnits[iUnit] != UNIT_BAD)
  324. {
  325. /*Read unit header*/
  326. status=getUnitData(&vol,iUnit,&virtualUnitNo, &prevUnitNo,&ANAC,&NAC,&parityPerField);
  327. if((status!=flOK)||(!isValidParityResult(parityPerField)))
  328. {
  329. TL_DEBUG_PRINT(tl_out,"Error going along INFTL chains - could not get unit data of %d.\n",iUnit);
  330. TL_DEBUG_PRINT(tl_out,"Status = %d and parityPerField is %d.\n",status,parityPerField);
  331. SET_EXIT(INFTL_FAILED_MOUNT);
  332. continue;
  333. }
  334. /* FREE unit test that it's all erased and it has erase mark */
  335. if((virtualUnitNo==ANAND_NO_UNIT)&&
  336. (prevUnitNo==ANAND_NO_UNIT) &&
  337. (ANAC==ANAND_UNIT_FREE) &&
  338. (NAC==ANAND_UNIT_FREE))
  339. {
  340. freeUnits++;
  341. for(i=0;i<(1<<(vol.unitSizeBits - SECTOR_SIZE_BITS));i++)
  342. {
  343. /* Extra area */
  344. if(i!=2) /* skip erase mark at - UNIT_TAILER_OFFSET */
  345. {
  346. checkStatus(vol.flash.read(&vol.flash,
  347. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,
  348. tempbuf,16,EXTRA));
  349. if(tffscmp(tempbuf,pattern,16)!=0)
  350. {
  351. TL_DEBUG_PRINT(tl_out,"Extra area of FREE unit is not FF's in %d unit %d sector, it is\n",iUnit,i);
  352. for(temp=0;temp<16;temp++)
  353. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  354. TL_DEBUG_PRINT(tl_out,"\n\n");
  355. SET_EXIT(INFTL_FAILED_MOUNT);
  356. }
  357. }
  358. else /* Erase mark sector offset */
  359. {
  360. checkStatus(vol.flash.read(&vol.flash,
  361. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,
  362. tempbuf,16,EXTRA));
  363. if(tffscmp(tempbuf,pattern,8)!=0)
  364. {
  365. TL_DEBUG_PRINT(tl_out,"Extra area of FREE unit is not FF's in %d unit %d sector, it is\n",iUnit,i);
  366. for(temp=0;temp<16;temp++)
  367. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  368. TL_DEBUG_PRINT(tl_out,"\n\n");
  369. SET_EXIT(INFTL_FAILED_MOUNT);
  370. }
  371. erasePatt1=(unsigned short*)(&(tempbuf[12]));
  372. erasePatt2=(unsigned short*)(&(tempbuf[14]));
  373. if(*erasePatt1!=ERASE_MARK)
  374. {
  375. TL_DEBUG_PRINT(tl_out,"First Erase mark of FREE unit is not written well in Unit %d it is %x\n",iUnit,*erasePatt1);
  376. }
  377. if(*erasePatt2!=ERASE_MARK)
  378. {
  379. TL_DEBUG_PRINT(tl_out,"Second Erase mark of FREE unit is not written well in Unit %d it is %x\n",iUnit,*erasePatt2);
  380. }
  381. if ((*erasePatt1!=ERASE_MARK)||(*erasePatt2!=ERASE_MARK))
  382. erCount++;
  383. }
  384. /* Data area */
  385. checkStatus(vol.flash.read(&vol.flash,
  386. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,
  387. tempbuf,SECTOR_SIZE,0));
  388. if(tffscmp(tempbuf,pattern,SECTOR_SIZE)!=0)
  389. {
  390. TL_DEBUG_PRINT(tl_out,"Data area of FREE unit is not FF's in %d unit %d sector it is.\n",iUnit,i);
  391. for(temp=0;temp<SECTOR_SIZE;temp++)
  392. {
  393. if (temp%0x10==0)
  394. TL_DEBUG_PRINT(tl_out,"\n");
  395. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  396. }
  397. TL_DEBUG_PRINT(tl_out,"\n\n");
  398. SET_EXIT(INFTL_FAILED_MOUNT);
  399. }
  400. }
  401. }
  402. else /* Not a FREE unit */
  403. {
  404. /* If it's not erased test each valid sector for ecc/edc error */
  405. for(i=0;i<(1<<(vol.unitSizeBits - SECTOR_SIZE_BITS));i++)
  406. {
  407. sectorFlags = getSectorFlags(&vol,unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE);
  408. if(sectorFlags==SECTOR_FREE)
  409. {
  410. /* Extra area */
  411. switch(i)
  412. {
  413. case 0: /* Do not check extra area */
  414. case 4:
  415. break;
  416. case 2: /* Check only erase mark */
  417. checkStatus(vol.flash.read(&vol.flash,
  418. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,
  419. tempbuf,16,EXTRA));
  420. if(tffscmp(tempbuf,pattern,8)!=0)
  421. {
  422. TL_DEBUG_PRINT(tl_out,"Extra area of USED unit is not FF's in %d unit %d sector, it is\n",iUnit,i);
  423. for(temp=0;temp<16;temp++)
  424. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  425. TL_DEBUG_PRINT(tl_out,"\n\n");
  426. SET_EXIT(INFTL_FAILED_MOUNT);
  427. }
  428. else
  429. {
  430. erasePatt1=(unsigned short*)(&(tempbuf[12]));
  431. erasePatt2=(unsigned short*)(&(tempbuf[14]));
  432. if(*erasePatt1!=ERASE_MARK)
  433. {
  434. TL_DEBUG_PRINT(tl_out,"USED unit First Erase mark is not written well in Unit %d it is %x\n",iUnit,*erasePatt1);
  435. }
  436. if(*erasePatt2!=ERASE_MARK)
  437. {
  438. TL_DEBUG_PRINT(tl_out,"USED unit Second Erase mark is not written well in Unit %d it is %x\n",iUnit,*erasePatt2);
  439. }
  440. if ((*erasePatt1!=ERASE_MARK)||(*erasePatt2!=ERASE_MARK))
  441. {
  442. SET_EXIT(INFTL_FAILED_MOUNT);
  443. erCount++;
  444. }
  445. }
  446. break;
  447. default: /* Make sure it is free (0xff) */
  448. checkStatus(vol.flash.read(&vol.flash,
  449. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,
  450. tempbuf,16,EXTRA));
  451. if(tffscmp(tempbuf,pattern,16)!=0)
  452. {
  453. TL_DEBUG_PRINT(tl_out,"Extra area of USED unit is not FF's in %d unit %d sector, it is\n",iUnit,i);
  454. for(temp=0;temp<16;temp++)
  455. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  456. TL_DEBUG_PRINT(tl_out,"\n\n");
  457. SET_EXIT(INFTL_FAILED_MOUNT);
  458. }
  459. } /* End sector number case */
  460. /* Data area */
  461. checkStatus(vol.flash.read(&vol.flash,
  462. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,
  463. tempbuf,SECTOR_SIZE,0));
  464. if(tffscmp(tempbuf,pattern,SECTOR_SIZE)!=0)
  465. {
  466. TL_DEBUG_PRINT(tl_out,"Data area of USED unit FREE sector is not FF's in %d unit %d sector it is\n",iUnit,i);
  467. for(temp=0;temp<SECTOR_SIZE;temp++)
  468. {
  469. if (temp%0x10==0)
  470. TL_DEBUG_PRINT(tl_out,"\n");
  471. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  472. }
  473. TL_DEBUG_PRINT(tl_out,"\n\n");
  474. SET_EXIT(INFTL_FAILED_MOUNT);
  475. }
  476. }
  477. else /* not a FREE sector - Used / Deleted / ignored */
  478. {
  479. /* Extra area */
  480. switch(i)
  481. {
  482. case 0: /* Do not check extra area */
  483. case 4:
  484. break;
  485. case 2: /* Check only erase mark */
  486. checkStatus(vol.flash.read(&vol.flash,
  487. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE+8,
  488. tempbuf,8,EXTRA));
  489. erasePatt1=(unsigned short*)(&(tempbuf[4]));
  490. erasePatt2=(unsigned short*)(&(tempbuf[6]));
  491. if(*erasePatt1!=ERASE_MARK)
  492. {
  493. TL_DEBUG_PRINT(tl_out,"USED unit not a free sector First Erase mark is not written well in Unit %d it is %x\n",iUnit,*erasePatt1);
  494. }
  495. if(*erasePatt2!=ERASE_MARK)
  496. {
  497. TL_DEBUG_PRINT(tl_out,"USED unit not a free sector Second Erase mark is not written well in Unit %d it is %x\n",iUnit,*erasePatt2);
  498. }
  499. if ((*erasePatt1!=ERASE_MARK)||(*erasePatt2!=ERASE_MARK))
  500. {
  501. SET_EXIT(INFTL_FAILED_MOUNT);
  502. erCount++;
  503. }
  504. break;
  505. default: /* Make sure it is free (0xff) */
  506. checkStatus(vol.flash.read(&vol.flash,
  507. unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE+8,
  508. tempbuf,8,EXTRA));
  509. if(tffscmp(tempbuf,pattern,8)!=0)
  510. {
  511. TL_DEBUG_PRINT(tl_out,"USED unit not a free sector is not FF's in %d unit %d sector, it is\n",iUnit,i);
  512. for(temp=0;temp<8;temp++)
  513. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  514. TL_DEBUG_PRINT(tl_out,"\n\n");
  515. SET_EXIT(INFTL_FAILED_MOUNT);
  516. }
  517. } /* End sector number case */
  518. /* Data area */
  519. status=vol.flash.read(&vol.flash,unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,tempbuf,SECTOR_SIZE,EDC);
  520. if((sectorFlags==SECTOR_DELETED)||
  521. (sectorFlags==SECTOR_USED))
  522. {
  523. if(status!=flOK)
  524. {
  525. if(sectorFlags==SECTOR_USED)
  526. {
  527. TL_DEBUG_PRINT(tl_out,"Used sector with ");
  528. }
  529. else
  530. {
  531. TL_DEBUG_PRINT(tl_out,"Deleted sector with ");
  532. }
  533. TL_DEBUG_PRINT(tl_out,"ECC/EDC error in %d unit %d sector, the data is\n",iUnit,i);
  534. for(temp=0;temp<SECTOR_SIZE;temp++)
  535. {
  536. if (temp%0x10==0)
  537. TL_DEBUG_PRINT(tl_out,"\n");
  538. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  539. }
  540. TL_DEBUG_PRINT(tl_out,"\n\n");
  541. SET_EXIT(INFTL_FAILED_MOUNT);
  542. }
  543. }
  544. else /* sectorFlags == SECTOR_IGNORED */
  545. {
  546. vol.flash.read(&vol.flash,unitBaseAddress(vol,iUnit)+i*SECTOR_SIZE,tempbuf,SECTOR_SIZE,0);
  547. TL_DEBUG_PRINT(tl_out,"There is an ignored sector in %d unit %d sector the data is\n",iUnit,i);
  548. for(temp=0;temp<SECTOR_SIZE;temp++)
  549. {
  550. if (temp%0x10==0)
  551. TL_DEBUG_PRINT(tl_out,"\n");
  552. TL_DEBUG_PRINT(tl_out,"%x ",tempbuf[temp]);
  553. }
  554. if (status == flOK)
  555. {
  556. TL_DEBUG_PRINT(tl_out,"\nThe EDC is fine, how about checking bit failures\n\n");
  557. }
  558. else
  559. {
  560. TL_DEBUG_PRINT(tl_out,"\nThe EDC is wrong\n\n");
  561. }
  562. }
  563. }
  564. } /* sector loop */
  565. } /* Used unit */
  566. } /* Good block */
  567. } /* unit loop */
  568. if (vol.debugState & INFTL_FAILED_MOUNT)
  569. {
  570. TL_DEBUG_PRINT(tl_out,"\nNote that all unit numbers are relative to first unit = %d\n",vol.firstUnit);
  571. }
  572. else
  573. {
  574. TL_DEBUG_PRINT(tl_out,"\n");
  575. }
  576. return flOK;
  577. }
  578. #endif /* CHECK_MOUNT */