Leaked source code of windows server 2003
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.

542 lines
22 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/FLTL.C_V $
  3. *
  4. * Rev 1.19 Jan 23 2002 23:33:08 oris
  5. * Bug fix - converting NFTL format to INFTL, with bad EDC in BBT.
  6. * Changed DFORMAT_PRINT syntax.
  7. *
  8. * Rev 1.18 Jan 20 2002 20:28:32 oris
  9. * Removed quick mount flag check for NFTL (no longer relevant).
  10. * Removed warnings (DFORMAT_PRINT).
  11. *
  12. * Rev 1.17 Jan 17 2002 23:02:44 oris
  13. * Added check for NULL pointers for readBBT and socket record.
  14. * Added checkVolume and defragment routine initialization.
  15. * Placed readBBT under NO_READ_BBT_CODE compilation flag.
  16. * Added include for docbdk.h
  17. * Added flash record as a parameter to flMount / flFormat / flPremount routine.
  18. * Removed check of TL_SINGLE_FLOOR_FORMATTING flag in the flFormat routine.
  19. * Added check for 0xFFFF FFFF binary signature.
  20. *
  21. * Rev 1.16 Nov 20 2001 20:25:24 oris
  22. * Changed debug print to dformat debug print.
  23. *
  24. * Rev 1.15 Nov 16 2001 00:22:06 oris
  25. * Fix check43to50 routine.
  26. *
  27. * Rev 1.14 Nov 08 2001 10:49:38 oris
  28. * Added format converter from NFTL to INFTL for ALON controllers (mobile DiskOnChip) NO_NFTL_2_INFTL compilation flag
  29. * Bug fix - support for DiskOnChip with different number of blocks in the last floor.
  30. * Added erase operation of bad blocks in write BBT routine (helps plant bad blocks).
  31. *
  32. * Rev 1.13 Sep 15 2001 23:46:40 oris
  33. * Removed some debug printing.
  34. *
  35. * Rev 1.12 Jul 15 2001 20:45:04 oris
  36. * Changed DFORMAT_PRINT syntax to be similar to DEBUG_PRINT.
  37. *
  38. * Rev 1.11 Jul 13 2001 01:06:54 oris
  39. * Rewritten writeBBT portion of the preMount routine - several bugs were found.
  40. * Millennium Plus does not support write BBT routine.
  41. *
  42. * Rev 1.10 Jun 17 2001 08:18:26 oris
  43. * Place write bbt under FORMAT_VOLUME compilation flag.
  44. *
  45. * Rev 1.9 May 16 2001 21:35:04 oris
  46. * Bug fix - write BBT did not cover the entire media.
  47. *
  48. * Rev 1.8 May 02 2001 06:39:46 oris
  49. * Removed the lastUsableBlock variable.
  50. *
  51. * Rev 1.7 Apr 24 2001 17:08:38 oris
  52. * Rebuilt writeBBT routine.
  53. * Added check for uninitialized socket in the premount routine (releveant to windows OS).
  54. *
  55. * Rev 1.6 Apr 16 2001 13:47:44 oris
  56. * Removed warrnings.
  57. *
  58. * Rev 1.5 Apr 09 2001 15:09:56 oris
  59. * End with an empty line.
  60. *
  61. * Rev 1.4 Apr 01 2001 07:57:34 oris
  62. * copywrite notice.
  63. * Removed debug massage when calling a premount routine from a TL that does not support it.
  64. *
  65. * Rev 1.3 Feb 18 2001 12:07:58 oris
  66. * Bug fix in writeBBT irLength argument is accepted if it is diffrent then 0 and not equal.
  67. * Bug fix in format sanity check must be sure a BDTLPartitionInfo exits before checking it for protection.
  68. *
  69. * Rev 1.2 Feb 14 2001 01:55:12 oris
  70. * CountVolumes returns no of volumes in irFlags instead of irLength.
  71. * Added boundry argument to writeBBT.
  72. * Moved format varification from blockdev.c.
  73. *
  74. * Rev 1.1 Feb 12 2001 11:57:42 oris
  75. * WriteBBT was moved from blockdev.c.
  76. *
  77. * Rev 1.0 Feb 04 2001 12:07:30 oris
  78. * Initial revision.
  79. *
  80. */
  81. /***********************************************************************************/
  82. /* M-Systems Confidential */
  83. /* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
  84. /* All Rights Reserved */
  85. /***********************************************************************************/
  86. /* NOTICE OF M-SYSTEMS OEM */
  87. /* SOFTWARE LICENSE AGREEMENT */
  88. /* */
  89. /* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
  90. /* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
  91. /* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
  92. /* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
  93. /* E-MAIL = [email protected] */
  94. /***********************************************************************************/
  95. /* #include "flflash.h" */
  96. #include "fltl.h"
  97. #include "docbdk.h" /* Only for bdk signature size */
  98. int noOfTLs; /* No. of translation layers actually registered */
  99. TLentry tlTable[TLS];
  100. /*----------------------------------------------------------------------*/
  101. /* m a r k U n i t B a d */
  102. /* */
  103. /* Erase a unit and mark it as bad */
  104. /* */
  105. /* Parameters: */
  106. /* flash : Pointer to MTD record */
  107. /* badUnit : Bad unit number to mark as bad */
  108. /* */
  109. /* Returns: */
  110. /* FLStatus : flOK */
  111. /*----------------------------------------------------------------------*/
  112. FLStatus markUnitBad(FLFlash * flash, CardAddress badUnit)
  113. {
  114. static byte zeroes[2] = {0,0};
  115. dword offset;
  116. /* Mark the first page with 00. If the write operation
  117. fails try marking the following pages of the block */
  118. for (offset = 0 ; (offset < flash->erasableBlockSize) &&
  119. (flash->write(flash,(badUnit << flash->erasableBlockSizeBits)+offset,
  120. zeroes,sizeof(zeroes),0) != flOK);
  121. offset += flash->pageSize);
  122. /* Entire block can not be written to */
  123. if (offset == flash->erasableBlockSize)
  124. #ifndef NT5PORT
  125. DEBUG_PRINT(("Debug: Error failed marking unit as bad (address %ld).\n",badUnit));
  126. #else /*NT5PORT*/
  127. DEBUG_PRINT(("Debug: Error failed marking unit as bad (address).\n"));
  128. #endif /*NT5PORT*/
  129. return flOK;
  130. }
  131. #ifndef NO_NFTL_2_INFTL
  132. /*----------------------------------------------------------------------*/
  133. /* c h e c k 4 3 F o r m a t */
  134. /* */
  135. /* Checks DiskOnChip 2000 tsop was formated using TrueFFS 4.3. If so it */
  136. /* unformats the media. */
  137. /* */
  138. /* Note - The routine will not help DiskOnChip larger then DiskOnChip */
  139. /* 2000 tsop formated with TrueFFS 4.3. */
  140. /* */
  141. /* Note - How about erasing the media header last. */
  142. /* */
  143. /* Parameters: */
  144. /* flash : Pointer to MTD record */
  145. /* */
  146. /* Returns: */
  147. /* FLStatus : flOK */
  148. /* flDataError - DiskOnChip ALON was formated with 4.3 */
  149. /* but is not DiskOnChip 2000 tsop. */
  150. /*----------------------------------------------------------------------*/
  151. FLStatus check43Format(FLFlash *flash)
  152. {
  153. FLStatus status;
  154. byte FAR1* buf;
  155. /* If this is an alon */
  156. if (flash->mediaType != DOC2000TSOP_TYPE)
  157. return flOK;
  158. buf = (flBufferOf(flSocketNoOf(flash->socket))->flData);
  159. if(flash->readBBT == NULL)
  160. {
  161. DFORMAT_PRINT(("ERROR : MTD read BBT routine was not initialized\r\n"));
  162. return flFeatureNotSupported;
  163. }
  164. status = flash->readBBT(flash,0,1,0,buf,FALSE);
  165. if (status == flBadBBT)
  166. {
  167. dword mediaSize = ((dword)flash->noOfChips*flash->chipSize);
  168. dword blockSize = 1<<flash->erasableBlockSizeBits;
  169. dword addr = 0;
  170. dword offset;
  171. word mediaHeaderBlock; /* ANAND unit number */
  172. byte blocksPerUnit; /* Blocks per virtual unit */
  173. byte blockShift; /* Bits to shift from block to unit */
  174. CHECK_UNIT_WITH_ANAND:
  175. /* Either virgin or formated wih TrueFFS 4.3 */
  176. for( ; addr < mediaSize ; addr += blockSize)
  177. {
  178. checkStatus(flash->read(flash,addr,buf,5,0));
  179. if(tffscmp(buf,"ANAND",5) == 0)
  180. break;
  181. }
  182. if (addr == mediaSize) /* virgin card */
  183. return flOK;
  184. DFORMAT_PRINT(("This DiskOnChip was formated with an NFTL format.\r\n"));
  185. /* Calculate block multiplier bits */
  186. for (offset = addr + SECTOR_SIZE , status = flOK;
  187. (offset < addr + blockSize) && (status == flOK) ;
  188. offset += SECTOR_SIZE)
  189. {
  190. status = flash->read(flash,addr+offset,buf,512,EDC);
  191. }
  192. if(offset == addr + (SECTOR_SIZE<<1)) /* Bad EDC for NFTL unit header */
  193. {
  194. DFORMAT_PRINT(("ERROR - Unit with ANAND was found, but the BBT has bad EDC.\r\n"));
  195. goto CHECK_UNIT_WITH_ANAND; /* Keep searching */
  196. }
  197. offset = (offset - addr - (SECTOR_SIZE<<1)) << flash->erasableBlockSizeBits;
  198. for(blockShift = 0 ; offset < mediaSize ; blockShift++)
  199. {
  200. offset <<= 1;
  201. }
  202. blocksPerUnit = 1 << blockShift;
  203. mediaHeaderBlock = (word)(addr >> (flash->erasableBlockSizeBits + blockShift));
  204. DFORMAT_PRINT(("Please wait while unformating is in progress...\r\n"));
  205. /* Read and write 512 blocks of the BBT (start from the end) */
  206. for (offset = 0;
  207. offset < mediaSize>>(flash->erasableBlockSizeBits + blockShift);
  208. offset += SECTOR_SIZE)
  209. {
  210. word i;
  211. checkStatus(flash->read(flash,addr+offset+SECTOR_SIZE,buf,SECTOR_SIZE,EDC));
  212. for(i=0;i<SECTOR_SIZE;i++)
  213. {
  214. if (i+offset == mediaHeaderBlock)
  215. continue;
  216. if (buf[i]==BBT_BAD_UNIT) /* A bad block */
  217. {
  218. markUnitBad(flash , i+offset);
  219. }
  220. else /* A good block */
  221. {
  222. status = flash->erase(flash,(word)(i+offset),blocksPerUnit);
  223. if (status != flOK)
  224. markUnitBad(flash , i+offset);
  225. }
  226. }
  227. }
  228. status = flash->erase(flash,mediaHeaderBlock,blocksPerUnit);
  229. if (status != flOK)
  230. markUnitBad(flash , mediaHeaderBlock);
  231. DFORMAT_PRINT(("Unformating of DiskOnChip 2000 tsop complete.\r\n"));
  232. }
  233. return flOK;
  234. }
  235. #endif /* NO_NFTL_2_INFTL */
  236. /*----------------------------------------------------------------------*/
  237. /* f l P r e M o u n t */
  238. /* */
  239. /* Perform TL operation before the TL is mounted */
  240. /* */
  241. /* Notes for FL_COUNT_VOLUMES routine */
  242. /* ---------------------------------- */
  243. /* Note : The number of partitions returned is not neccarily the number */
  244. /* That can be accesses. protected partitions will need a key. */
  245. /* Note : TL that do not support several partitions will return 1 */
  246. /* unless the socket can not be mounted in which case 0 will be */
  247. /* returned. */
  248. /* */
  249. /* Parameters: */
  250. /* callType : The type of the operation (see blockdev.h) */
  251. /* ioreq : Input Output packet */
  252. /* ioreq.irHandle : handle discribing the socket and the partition */
  253. /* flash : Location where the flash media record can be */
  254. /* stored. Note that it is not yet initialized */
  255. /* */
  256. /* Returns: */
  257. /* FLStatus : 0 on success, failed otherwise */
  258. /*----------------------------------------------------------------------*/
  259. FLStatus flPreMount(FLFunctionNo callType, IOreq FAR2* ioreq , FLFlash * flash)
  260. {
  261. FLStatus layerStatus = flUnknownMedia;
  262. FLStatus callStatus;
  263. FLSocket *socket = flSocketOf(FL_GET_SOCKET_FROM_HANDLE(ioreq));
  264. int iTL;
  265. #ifdef NT5PORT
  266. if(socket->window.base == NULL){
  267. ioreq->irFlags = 1;
  268. return flOK;
  269. }
  270. #endif /*NT5PORT*/
  271. /* Patch for OS drivers that call flInit before socket is initialized */
  272. if (callType == FL_COUNT_VOLUMES)
  273. {
  274. if((socket == NULL) || (socket->window.base==NULL))
  275. {
  276. ioreq->irFlags = 1;
  277. return flOK;
  278. }
  279. }
  280. /* Identify flash medium and initlize flash record */
  281. callStatus = flIdentifyFlash(socket,flash);
  282. if (callStatus != flOK && callStatus != flUnknownMedia)
  283. return callStatus;
  284. /* Try sending call to the diffrent TLs */
  285. for (iTL = 0; (iTL < noOfTLs) && (layerStatus != flOK); iTL++)
  286. if (tlTable[iTL].preMountRoutine != NULL)
  287. layerStatus = tlTable[iTL].preMountRoutine(callType,ioreq, flash,&callStatus);
  288. if (layerStatus != flOK)
  289. {
  290. switch (callType)
  291. {
  292. case FL_COUNT_VOLUMES:
  293. ioreq->irFlags = 1;
  294. return flOK;
  295. #ifdef FORMAT_VOLUME
  296. case FL_WRITE_BBT:
  297. {
  298. CardAddress endUnit = ((dword)(flash->chipSize * flash->noOfChips) >> flash->erasableBlockSizeBits); /* Media size */
  299. CardAddress unitsPerFloor = endUnit/flash->noOfFloors;
  300. CardAddress iUnit;
  301. CardAddress bUnit = *((unsigned long FAR1 *) ioreq->irData)
  302. >> flash->erasableBlockSizeBits;
  303. word badBlockNo;
  304. /* In case the user has given a specific length use it
  305. instead of the entire media */
  306. if ((ioreq->irLength != 0) && ( endUnit >
  307. ((dword)ioreq->irLength >> flash->erasableBlockSizeBits)))
  308. {
  309. endUnit = ioreq->irLength >> flash->erasableBlockSizeBits;
  310. }
  311. /* Millennium Plus DiskOnChip Family do not need a write bbt call */
  312. if ((flash->mediaType == MDOCP_TYPE ) ||
  313. (flash->mediaType == MDOCP_16_TYPE) )
  314. {
  315. DEBUG_PRINT(("DiskOnChip Millennium Plus has a H/W protected BBT.\r\n"));
  316. DEBUG_PRINT(("No need to erase the DiskOnChip. Simply reformat.\r\n"));
  317. return flFeatureNotSupported;
  318. }
  319. /* Erase entire media */
  320. for (iUnit = flash->firstUsableBlock ,badBlockNo = 0;
  321. iUnit < endUnit ;iUnit += ((iUnit+1) / unitsPerFloor) ?
  322. 1 : flash->firstUsableBlock + 1)
  323. {
  324. #ifndef NT5PORT
  325. DFORMAT_PRINT(("Erasing unit number %ld\r",iUnit));
  326. #endif /*NT5PORT*/
  327. if (ioreq->irFlags > badBlockNo) /* There are additional bad blocks */
  328. {
  329. if (bUnit == iUnit)
  330. {
  331. badBlockNo++;
  332. bUnit = (*((CardAddress FAR1 *)flAddLongToFarPointer
  333. (ioreq->irData,badBlockNo*sizeof(CardAddress))))
  334. >> flash->erasableBlockSizeBits;
  335. flash->erase(flash,(word)iUnit,1);
  336. markUnitBad(flash,iUnit);
  337. continue;
  338. }
  339. }
  340. callStatus = flash->erase(flash,(word)iUnit,1);
  341. if (callStatus != flOK) /* Additional bad block was found */
  342. {
  343. #ifndef NT5PORT
  344. DFORMAT_PRINT(("Failed erasing unit in write BBT (unit no %lu).\r\n",iUnit));
  345. #endif/*NT5PORT*/
  346. markUnitBad(flash,iUnit);
  347. }
  348. }
  349. DEBUG_PRINT(("\nUnformat Complete \r\n"));
  350. return flOK;
  351. }
  352. #endif /* FORMAT_VOLUME */
  353. default : /* Protection routines */
  354. return flFeatureNotSupported;
  355. }
  356. }
  357. return callStatus;
  358. }
  359. /*----------------------------------------------------------------------*/
  360. /* f l M o u n t */
  361. /* */
  362. /* Mount a translation layer */
  363. /* */
  364. /* Parameters: */
  365. /* volNo : Volume no. */
  366. /* socketNo : The socket no */
  367. /* tl : Where to store translation layer methods */
  368. /* useFilters : Whether to use filter translation-layers */
  369. /* flash : Location where the flash media record can be */
  370. /* stored. Note that it is not yet initialized */
  371. /* */
  372. /* Returns: */
  373. /* FLStatus : 0 on success, failed otherwise */
  374. /*----------------------------------------------------------------------*/
  375. FLStatus flMount(unsigned volNo, unsigned socketNo,TL *tl,
  376. FLBoolean useFilters , FLFlash * flash)
  377. {
  378. FLFlash *volForCallback = NULL;
  379. FLSocket *socket = flSocketOf(socketNo);
  380. FLStatus status = flUnknownMedia;
  381. int iTL;
  382. FLStatus flashStatus = flIdentifyFlash(socket,flash);
  383. if (flashStatus != flOK && flashStatus != flUnknownMedia)
  384. return flashStatus;
  385. tl->recommendedClusterInfo = NULL;
  386. tl->writeMultiSector = NULL;
  387. tl->readSectors = NULL;
  388. #ifndef NO_READ_BBT_CODE
  389. tl->readBBT = NULL;
  390. #endif
  391. #if (defined(VERIFY_VOLUME) || defined(VERIFY_WRITE))
  392. tl->checkVolume = NULL;
  393. #endif /* VERIFY_VOLUME || VERIFY_WRITE */
  394. #ifdef DEFRAGMENT_VOLUME
  395. tl->defragment = NULL;
  396. #endif /* DEFRAGMENT */
  397. for (iTL = 0; (iTL < noOfTLs) && (status != flOK) && (status != flHWProtection); iTL++)
  398. if (tlTable[iTL].formatRoutine != NULL) /* not a block-device filter */
  399. status = tlTable[iTL].mountRoutine(volNo,tl,flashStatus == flOK ? flash : NULL,&volForCallback);
  400. if (status == flOK) {
  401. if (volForCallback)
  402. volForCallback->setPowerOnCallback(volForCallback);
  403. if (useFilters)
  404. for (iTL = 0; iTL < noOfTLs; iTL++)
  405. if (tlTable[iTL].formatRoutine == NULL) /* block-device filter */
  406. if (tlTable[iTL].mountRoutine(volNo,tl,NULL,NULL) == flOK)
  407. break;
  408. }
  409. return status;
  410. }
  411. #ifdef FORMAT_VOLUME
  412. /*----------------------------------------------------------------------*/
  413. /* f l F o r m a t */
  414. /* */
  415. /* Formats the Flash volume */
  416. /* */
  417. /* Parameters: */
  418. /* volNo : Physical drive no. */
  419. /* formatParams : Address of FormatParams structure to use */
  420. /* flash : Location where the flash media record can be */
  421. /* stored. Note that it is not yet initialized */
  422. /* */
  423. /* Returns: */
  424. /* FLStatus : 0 on success, failed otherwise */
  425. /*----------------------------------------------------------------------*/
  426. FLStatus flFormat(unsigned volNo, TLFormatParams * formatParams,
  427. FLFlash * flash)
  428. {
  429. BinaryPartitionFormatParams FAR1* partitionPtr;
  430. FLSocket * socket = flSocketOf(volNo);
  431. FLStatus status = flUnknownMedia;
  432. int iTL,partitionNo;
  433. FLStatus flashStatus = flIdentifyFlash(socket,flash);
  434. if (flashStatus != flOK && flashStatus != flUnknownMedia)
  435. return flashStatus;
  436. /* Validity check for formatParams */
  437. if (!(flash->flags & INFTL_ENABLED)) /* Flash does not support INFTL */
  438. {
  439. if ((formatParams->noOfBDTLPartitions > 1) ||
  440. #ifdef HW_PROTECTION
  441. ((formatParams->BDTLPartitionInfo != NULL) &&
  442. (formatParams->BDTLPartitionInfo->protectionType & PROTECTABLE)) ||
  443. ((formatParams->noOfBinaryPartitions > 0)&&
  444. (formatParams->binaryPartitionInfo->protectionType & PROTECTABLE)) ||
  445. #endif /* HW_PROTECTION */
  446. (formatParams->noOfBinaryPartitions > 1))
  447. {
  448. DEBUG_PRINT(("Debug: feature not supported by the TL.\r\n"));
  449. return flFeatureNotSupported;
  450. }
  451. }
  452. for(partitionNo = 0 , partitionPtr = formatParams->binaryPartitionInfo;
  453. partitionNo < formatParams->noOfBinaryPartitions;
  454. partitionNo++,partitionPtr++)
  455. {
  456. if(*((dword FAR1*)(partitionPtr->sign)) == 0xffffffffL)
  457. {
  458. DEBUG_PRINT(("Debug: can not use 'FFFF' signature for Binary partition\r\n"));
  459. return flBadParameter;
  460. }
  461. }
  462. /* Try each of the registered TL */
  463. #ifndef NO_NFTL_2_INFTL
  464. checkStatus(check43Format(flash));
  465. #endif /* NO_NFTL_2_INFTL */
  466. for (iTL = 0; iTL < noOfTLs && status == flUnknownMedia; iTL++)
  467. if (tlTable[iTL].formatRoutine != NULL) /* not a block-device filter */
  468. status = tlTable[iTL].formatRoutine(volNo,formatParams,flashStatus == flOK ? flash : NULL);
  469. return status;
  470. }
  471. #endif
  472. FLStatus noFormat (unsigned volNo, TLFormatParams * formatParams, FLFlash *flash)
  473. {
  474. return flOK;
  475. }