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.

2771 lines
108 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/DISKONC.C_V $
  3. *
  4. * Rev 1.33 Apr 15 2002 07:35:04 oris
  5. * Changed usage and logic of checkToggle to be more intuitive.
  6. * Added support for new access layer (docsys). MTD now initializes the
  7. * access layer accessing the DiskOnChip registers.
  8. * Bug fix - doc2write did not report write faults in case runtime verify
  9. * write was not required.
  10. * Bug fix - bad compilation ifdef in readBBT routine might cause a write
  11. * operation while FL_READ_ONLY is defined or to compile the
  12. * reconstruct BBT code even if MTD_RECONSTRUCT_BBT is
  13. * not defined.
  14. *
  15. * Rev 1.32 Jan 29 2002 20:07:30 oris
  16. * Changed sanity check of write IPL modes.
  17. *
  18. * Rev 1.31 Jan 28 2002 21:23:58 oris
  19. * Removed the use of back-slashes in macro definitions.
  20. * Added FL_IPL_DOWNLOAD flag to writeIPL routine in order to control whether the IPL will be reloaded after the update.
  21. * Bug fix - writeIPL routine did not support buffers smaller then 1024 bytes.
  22. * Bug fix - writeIPL routine did not write the second copy of the IPL correctly (for both 512 bytes).
  23. * Changed docwrite and docset calls to separate DiskOnChip base window pointer and IO registers offset (for address shifting).
  24. * Replaced FLFlash argument with DiskOnChip memory base pointer in calls to docwrite , docset and docread.
  25. * Removed win_io initialization (one of FLFlash record fields).
  26. * Improved check for flSuspend.
  27. *
  28. * Rev 1.30 Jan 23 2002 23:31:04 oris
  29. * Added writeIPL routine (copied from blockdev.c).
  30. * Made writeIPL and download routines available even when MTD_STANDALONE is defined.
  31. * Bug fix - checkErase routine was unreasonably slow.
  32. * Changed DFORMAT_PRINT syntax.
  33. *
  34. * Rev 1.29 Jan 21 2002 20:43:50 oris
  35. * Compilation errors for MTD_STANDALONE with BDK_VERIFY_WRITE.
  36. * Bug fix - PARTIAL_EDC flag to doc2read was negated prior to readOneSector.
  37. *
  38. * Rev 1.28 Jan 20 2002 20:57:00 oris
  39. * physicalToPointer was called with wrong size argument.
  40. *
  41. * Rev 1.27 Jan 20 2002 20:28:06 oris
  42. * Changed doc2000FreeWindow return type to remove warnings.
  43. *
  44. * Rev 1.26 Jan 17 2002 22:57:56 oris
  45. * Replaced vol with *flash.
  46. * Removed flPreInit memory access routines.
  47. * Added new memory access routine implementation.
  48. * Compilation problems fixed with VERIFY_ERASE
  49. * Added support for flSuspendMode environment variable.
  50. *
  51. * Rev 1.25 Nov 21 2001 11:39:10 oris
  52. * Changed FL_WITH_VERIFY_WRITE and FL_WITHOUT_VERIFY_WRITE to FL_ON and FL_OFF.
  53. *
  54. * Rev 1.24 Nov 20 2001 20:24:58 oris
  55. * Removed warnings.
  56. *
  57. * Rev 1.23 Nov 16 2001 00:19:38 oris
  58. * Compilation problem for FL_READ_ONLY.
  59. *
  60. * Rev 1.22 Nov 08 2001 10:44:30 oris
  61. * Added run-time control over verify write mode.
  62. * Added support for more up to 64K units - erase / readbbt
  63. * Restricted BBT block search to BBT_MAX_DISTANCE and not the entire floor.
  64. * Bug fix - Replacing a DiskOnChip Millennium with DiskOnChip 2000 failed identifying DiskOnChip2000 (gang).
  65. *
  66. * Rev 1.21 Sep 24 2001 18:23:08 oris
  67. * Removed warnings.
  68. *
  69. * Rev 1.20 Sep 15 2001 23:44:42 oris
  70. * Placed YIELD_CPU definition under ifdef to prevent redeclaration.
  71. * Changed doc2erase to support up to 64K erase blocks.
  72. * Added reconstruct flag to readBBT routine - stating whether to reconstruct BBT if it is not available.
  73. * Added support for block multiplication in readBBT - several erase blocks in a single unit.
  74. * Added support for 128MB flashes.
  75. *
  76. * Rev 1.19 Jul 29 2001 16:14:06 oris
  77. * Support for number of units per floor not power of 2
  78. *
  79. * Rev 1.18 Jul 16 2001 22:47:58 oris
  80. * Compilation error when using the FL_READ_ONLY compilation flag.
  81. *
  82. * Rev 1.17 Jul 15 2001 20:44:48 oris
  83. * Removed warnings.
  84. * Bug fix - virgin card dformat print was repeated for DiskOnChip with several floors.
  85. *
  86. * Rev 1.16 Jul 13 2001 00:59:42 oris
  87. * Added docsys.h include.
  88. * Improved VERIFY_WRITE support - added socket readBack buffer.
  89. * Added PARTIAL_EDC read flag to the read routine.
  90. * Revised checkErase routine to include extra area.
  91. * Revised readBBT routine not to use MTD buffer.
  92. * Added dformat debug print massages.
  93. * Changed firstUsable block to 0 for DOC2000 tsop.
  94. *
  95. * Rev 1.15 Jun 17 2001 08:17:02 oris
  96. * Added brackets to remove warnnings.
  97. * Changed NO_READ_BBT_CODE to MTD_NO_READ_BBT_CODE.
  98. *
  99. * Rev 1.14 May 16 2001 21:16:32 oris
  100. * Removed warnings.
  101. * Changed code variable name to flCode (avoid name clashes).
  102. *
  103. * Rev 1.13 May 09 2001 00:31:28 oris
  104. * Changed the DOC2000_TSOP_SUPPORT and READ_BBT_CODE compilation flags to NO_READ_BBT_CODE.
  105. *
  106. * Rev 1.12 May 07 2001 10:00:04 oris
  107. * Compilation problems under MTD_STANDLAONE compilation flag.
  108. *
  109. * Rev 1.11 May 06 2001 22:41:22 oris
  110. * Added the READ_BBT_CODE to allow reading the BBT even in the MTD_STANDALONE mode.
  111. * Removed warnings.
  112. *
  113. * Rev 1.10 May 02 2001 06:44:38 oris
  114. * Bug fix - readBBT routine.
  115. * Removed the lastUsableBlock variable.
  116. *
  117. * Rev 1.9 Apr 30 2001 17:58:18 oris
  118. * Added EDC check when reading the BBT.
  119. *
  120. * Rev 1.8 Apr 24 2001 17:06:22 oris
  121. * Removed warrnings.
  122. * Added lastUsableBlock initialization field in the FLFlash record.
  123. *
  124. * Rev 1.7 Apr 16 2001 13:04:20 oris
  125. * Removed warrnings.
  126. *
  127. * Rev 1.6 Apr 12 2001 06:49:06 oris
  128. * Added forceDownload routine
  129. * Changed checkWinForDoc routine to be under ifndef MTD_STANDALONE.
  130. *
  131. * Rev 1.5 Apr 10 2001 16:39:16 oris
  132. * Added multiple floor support for readbbt routine.
  133. * Added call for docSocketInit which initializes the socket routines.
  134. * Added validity check after flMap call in order to support pccard premoutn routine.
  135. *
  136. * Rev 1.4 Apr 09 2001 14:58:40 oris
  137. * Removed debug buffer from readBBT routine.
  138. * Bug fix in doc2000Identify if ASIC id was not mdoc 8 is was assumed to be doc2000.
  139. * Added if_cfg field initialization in doc2000Identify.
  140. *
  141. * Rev 1.3 Apr 01 2001 07:38:58 oris
  142. * Moved include diskonc.h from docsys.h.
  143. * Removed waitForReadyWithYieldCPU for MTD_STANDALONE configuration.
  144. * Removed NO_PPP compilation flag support.
  145. * Left alligned all # directives.
  146. * Moved pageSize,noOfFloors filed from the MTDs internal stucture to FLFlash record.
  147. * Changed writeOneSector,doc2Write,readOneSector,doc2Read prototype.
  148. * Added readbbt routine for alon.
  149. * Removed pageAndTailSize from mtdVars record.
  150. *
  151. * Rev 1.2 Mar 01 2001 14:15:56 vadimk
  152. * Add proper MDOC and DOC2300 support
  153. *
  154. * Rev 1.1 Feb 07 2001 18:28:38 oris
  155. * Bug fix - restored antialise mechanizm to flDocWindowBaseAddress
  156. * Added seperetaed floors compilation flag
  157. * Changed mdoc \ alon distingishing algorithm
  158. * Removed checkWinForDoc routine under the mtd_standalone comilation flag
  159. * removed MAX_FLASH_DEVICES_MDOC define since alone DiskOnChips can support 16 chips just like doc2000
  160. *
  161. * Rev 1.0 Feb 02 2001 15:35:38 oris
  162. * Initial revision.
  163. *
  164. */
  165. /************************************************************************/
  166. /* */
  167. /* FAT-FTL Lite Software Development Kit */
  168. /* Copyright (C) M-Systems Ltd. 1995-2001 */
  169. /* */
  170. /************************************************************************/
  171. #include "reedsol.h"
  172. #include "diskonc.h"
  173. extern NFDC21Vars docMtdVars[SOCKETS];
  174. /* When the MTD is used as a standalone package some of the routine */
  175. /* are replaced with the following macroes */
  176. #ifdef MTD_STANDALONE
  177. #define flReadBackBufferOf(a) &(globalReadBack[a][0])
  178. #define flSocketNoOf(volume) 0 /* currently we support only a single device */
  179. #define flMap(socket,address) addToFarPointer(socket->base,address & (socket->size - 1));
  180. #endif /* MTD_STANDALONE */
  181. /* Yield CPU time in msecs */
  182. #ifndef YIELD_CPU
  183. #define YIELD_CPU 10
  184. #endif /* YIELD_CPU */
  185. /* maximum waiting time in msecs */
  186. #define MAX_WAIT 30
  187. #ifndef NO_EDC_MODE
  188. /*���������������������������.*/
  189. /* EDC control */
  190. /*���������������������������.*/
  191. /*----------------------------------------------------------------------*/
  192. /* e c c O N r e a d */
  193. /* */
  194. /* Enable ECC in read mode and reset it. */
  195. /* */
  196. /* Parameters: */
  197. /* flash : Pointer identifying drive */
  198. /* */
  199. /*----------------------------------------------------------------------*/
  200. static void eccONread (FLFlash * flash)
  201. {
  202. flWrite8bitReg(flash,NECCconfig,ECC_RESET);
  203. flWrite8bitReg(flash,NECCconfig,ECC_EN);
  204. }
  205. #ifndef FL_READ_ONLY
  206. /*----------------------------------------------------------------------*/
  207. /* e c c O n w r i t e */
  208. /* */
  209. /* Enable ECC in write mode and reset it. */
  210. /* */
  211. /* Parameters: */
  212. /* flash : Pointer identifying drive */
  213. /* */
  214. /*----------------------------------------------------------------------*/
  215. static void eccONwrite (FLFlash * flash)
  216. {
  217. flWrite8bitReg(flash,NECCconfig,ECC_RESET);
  218. flWrite8bitReg(flash,NECCconfig,(ECC_RW | ECC_EN));
  219. }
  220. #endif /* FL_READ_ONLY */
  221. #endif
  222. /*----------------------------------------------------------------------*/
  223. /* e c c O F F */
  224. /* */
  225. /* Disable ECC. */
  226. /* */
  227. /* Parameters: */
  228. /* flash : Pointer identifying drive */
  229. /* */
  230. /*----------------------------------------------------------------------*/
  231. static void eccOFF (FLFlash * flash)
  232. {
  233. flWrite8bitReg(flash,NECCconfig,ECC_RESERVED);
  234. }
  235. #ifndef NO_EDC_MODE
  236. /*----------------------------------------------------------------------*/
  237. /* e c c E r r o r */
  238. /* */
  239. /* Check for EDC error. */
  240. /* */
  241. /* Parameters: */
  242. /* flash : Pointer identifying drive */
  243. /* */
  244. /*----------------------------------------------------------------------*/
  245. static FLBoolean eccError (FLFlash * flash)
  246. {
  247. register int i;
  248. volatile Reg8bitType junk = 0;
  249. Reg8bitType ret;
  250. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  251. for(i=0;( i < 2 ); i++)
  252. junk += flRead8bitReg(flash,NECCconfig);
  253. ret = flRead8bitReg(flash,NECCconfig);
  254. }
  255. else {
  256. for(i=0;( i < 2 ); i++)
  257. junk += flRead8bitReg(flash,NECCstatus);
  258. ret = flRead8bitReg(flash,NECCstatus);
  259. }
  260. ret &= ECC_ERROR;
  261. return ((FLBoolean)ret);
  262. }
  263. #endif
  264. /*���������������������������.*/
  265. /* Miscellaneous routines */
  266. /*���������������������������.*/
  267. /*----------------------------------------------------------------------*/
  268. /* m a k e C o m m a n d */
  269. /* */
  270. /* Set Page Pointer to Area A, B or C in page. */
  271. /* */
  272. /* Parameters: */
  273. /* flash : Pointer identifying drive */
  274. /* cmd : receives command relevant to area */
  275. /* addr : receives the address to the right area. */
  276. /* modes : mode of operation (EXTRA ...) */
  277. /* */
  278. /*----------------------------------------------------------------------*/
  279. static void makeCommand ( FLFlash * flash, PointerOp *cmd,
  280. CardAddress *addr, int modes )
  281. {
  282. dword offset;
  283. #ifdef BIG_PAGE_ENABLED
  284. if ( !(flash->flags & BIG_PAGE) )
  285. { /* 2 Mb components */
  286. if( modes & EXTRA )
  287. {
  288. offset = (*addr) & (SECTOR_SIZE - 1);
  289. *cmd = AREA_C;
  290. if( offset < EXTRA_LEN ) /* First half of extra area */
  291. *addr += 0x100; /* ... assigned to 2nd page */
  292. else /* Second half of extra area */
  293. *addr -= EXTRA_LEN; /* ... assigned to 1st page */
  294. }
  295. else
  296. *cmd = AREA_A;
  297. }
  298. else
  299. #endif /* BIG_PAGE_ENABLED */
  300. { /* 4 Mb components */
  301. offset = (word)(*addr) & NFDC21thisVars->pageMask; /* offset within device Page */
  302. *addr -= offset; /* align at device Page */
  303. if(modes & EXTRA)
  304. offset += SECTOR_SIZE;
  305. if( offset < NFDC21thisVars->pageAreaSize ) /* starting in area A */
  306. *cmd = AREA_A;
  307. else if( offset < flash->pageSize ) /* starting in area B */
  308. *cmd = AREA_B;
  309. else /* got into area C */
  310. *cmd = AREA_C;
  311. offset &= (NFDC21thisVars->pageAreaSize - 1); /* offset within area of device Page */
  312. *addr += offset;
  313. }
  314. }
  315. /*----------------------------------------------------------------------*/
  316. /* b u s y */
  317. /* */
  318. /* Check if the selected flash device is ready. */
  319. /* */
  320. /* Parameters: */
  321. /* flash : Pointer identifying drive */
  322. /* */
  323. /* Returns: */
  324. /* Zero is ready. */
  325. /* */
  326. /*----------------------------------------------------------------------*/
  327. static FLBoolean busy (FLFlash * flash)
  328. {
  329. register int i;
  330. Reg8bitType stat;
  331. volatile Reg8bitType junk = 0;
  332. Reg8bitType ret;
  333. /* before polling for BUSY status perform 4 read operations from
  334. CDSN_control_reg */
  335. for(i=0;( i < 4 ); i++ )
  336. junk += flRead8bitReg(flash,NNOPreg);
  337. /* read BUSY status */
  338. stat = flRead8bitReg(flash,Nsignals);
  339. /* after BUSY status is obtained perform 2 read operations from
  340. CDSN_control_reg */
  341. for(i=0;( i < 2 ); i++ )
  342. junk += flRead8bitReg(flash,NNOPreg);
  343. ret = (!(stat & (Reg8bitType)RB));
  344. return ((FLBoolean)ret);
  345. }
  346. /*----------------------------------------------------------------------*/
  347. /* w a i t F o r R e a d y */
  348. /* */
  349. /* Wait until flash device is ready or timeout. */
  350. /* */
  351. /* Parameters: */
  352. /* flash : Pointer identifying drive */
  353. /* Returns: */
  354. /* FALSE if timeout error, otherwise TRUE. */
  355. /* */
  356. /*----------------------------------------------------------------------*/
  357. static FLBoolean waitForReady (FLFlash * flash)
  358. {
  359. int i;
  360. for(i=0;( i < BUSY_DELAY ); i++)
  361. {
  362. if( busy(flash) )
  363. {
  364. continue;
  365. }
  366. return( TRUE ); /* ready at last.. */
  367. }
  368. DEBUG_PRINT(("Debug: timeout error in NFDC 2148.\r\n"));
  369. return( FALSE );
  370. }
  371. #ifndef MTD_STANDALONE
  372. #ifndef DO_NOT_YIELD_CPU
  373. /*----------------------------------------------------------------------*/
  374. /* w a i t F o r R e a d y W i t h Y i e l d C P U */
  375. /* */
  376. /* Wait until flash device is ready or timeout. */
  377. /* The function yields CPU while it waits till flash is ready */
  378. /* */
  379. /* Parameters: */
  380. /* flash : Pointer identifying drive */
  381. /* Returns: */
  382. /* FALSE if timeout error, otherwise TRUE. */
  383. /* */
  384. /*----------------------------------------------------------------------*/
  385. static FLBoolean waitForReadyWithYieldCPU (FLFlash * flash,
  386. int millisecToSleep)
  387. {
  388. int i;
  389. for (i=0; i < (millisecToSleep / YIELD_CPU); i++) {
  390. #ifndef NT5PORT
  391. flsleep(YIELD_CPU);
  392. #endif /*NT5PORT*/
  393. if( busy(flash) )
  394. continue;
  395. return( TRUE ); /* ready at last.. */
  396. }
  397. return( FALSE );
  398. }
  399. #endif /* DO_NOT_YIELD_CPU */
  400. #endif /* MTD_STANDALONE */
  401. /*----------------------------------------------------------------------*/
  402. /* w r i t e S i g n a l s */
  403. /* */
  404. /* Write to CDSN_control_reg. */
  405. /* */
  406. /* Parameters: */
  407. /* flash : Pointer identifying drive */
  408. /* val : Value to write to register */
  409. /* */
  410. /*----------------------------------------------------------------------*/
  411. static void writeSignals (FLFlash * flash, Reg8bitType val)
  412. {
  413. register int i;
  414. volatile Reg8bitType junk = 0;
  415. flWrite8bitReg(flash,Nsignals,val);
  416. /* after writing to CDSN_control perform 2 reads from there */
  417. for(i = 0;( i < 2 ); i++ )
  418. junk += flRead8bitReg(flash,NNOPreg);
  419. }
  420. /*----------------------------------------------------------------------*/
  421. /* s e l e c t C h i p */
  422. /* */
  423. /* Write to deviceSelector register. */
  424. /* */
  425. /* Parameters: */
  426. /* flash : Pointer identifying drive */
  427. /* dev : Chip to select. */
  428. /* */
  429. /*----------------------------------------------------------------------*/
  430. static void selectChip (FLFlash * flash, Reg8bitType dev)
  431. {
  432. flWrite8bitReg(flash,NdeviceSelector,dev);
  433. }
  434. /*----------------------------------------------------------------------*/
  435. /* c h k A S I C m o d e */
  436. /* */
  437. /* Check mode of ASIC and if RESET set to NORMAL. */
  438. /* */
  439. /* Parameters: */
  440. /* flash : Pointer identifying drive */
  441. /* */
  442. /*----------------------------------------------------------------------*/
  443. static void chkASICmode (FLFlash * flash)
  444. {
  445. if( flRead8bitReg(flash,NDOCstatus) == ASIC_CHECK_RESET ) {
  446. flWrite8bitReg(flash,NDOCcontrol,ASIC_NORMAL_MODE);
  447. flWrite8bitReg(flash,NDOCcontrol,ASIC_NORMAL_MODE);
  448. #ifndef SEPARATED_CASCADED
  449. NFDC21thisVars->currentFloor = 0;
  450. #endif /* SEPARATED_CASCADED */
  451. }
  452. }
  453. /*----------------------------------------------------------------------*/
  454. /* s e t A S I C m o d e */
  455. /* */
  456. /* Set mode of ASIC. */
  457. /* */
  458. /* Parameters: */
  459. /* flash : Pointer identifying drive */
  460. /* mode : mode to set. */
  461. /* */
  462. /*----------------------------------------------------------------------*/
  463. static void setASICmode (FLFlash * flash, Reg8bitType mode)
  464. {
  465. NDOC2window p = (NDOC2window)flMap(flash->socket, 0);
  466. if (p!=NULL)
  467. {
  468. flWrite8bitReg(flash,NDOCcontrol,mode);
  469. flWrite8bitReg(flash,NDOCcontrol,mode);
  470. #ifdef SEPARATED_CASCADED
  471. flWrite8bitReg(flash,NASICselect,NFDC21thisVars->currentFloor);
  472. #endif /* SEPARATED_CASCADED */
  473. }
  474. }
  475. /*----------------------------------------------------------------------*/
  476. /* c h e c k T o g g l e */
  477. /* */
  478. /* Check DiskOnChip toggle bit. Verify this is not simple RAM. */
  479. /* */
  480. /* Note : This routine assumes that the memory access routines have */
  481. /* already been initialized by the called routine. */
  482. /* */
  483. /* Parameters: */
  484. /* FLFlash : Pointer to flash structure. */
  485. /* */
  486. /* Returns: */
  487. /* FLStatus: TRUE if the bit toggles verifing that this is indeed */
  488. /* a DiskOnChip device, otherwise FALSE. */
  489. /*----------------------------------------------------------------------*/
  490. static FLBoolean checkToggle(FLFlash * flash)
  491. {
  492. volatile Reg8bitType toggle1;
  493. volatile Reg8bitType toggle2;
  494. if(flRead8bitReg(flash,NchipId) == CHIP_ID_MDOC ) {
  495. toggle1 = flRead8bitReg(flash,NECCconfig);
  496. toggle2 = toggle1 ^ flRead8bitReg(flash,NECCconfig);
  497. }
  498. else {
  499. toggle1 = flRead8bitReg(flash,NECCstatus);
  500. toggle2 = toggle1 ^ flRead8bitReg(flash,NECCstatus);
  501. }
  502. if( (toggle2 & TOGGLE) == 0 )
  503. return FALSE;
  504. return TRUE;
  505. }
  506. #ifndef MTD_STANDALONE
  507. /*----------------------------------------------------------------------*/
  508. /* c h e c k W i n F o r D O C */
  509. /* */
  510. /* Check for a DiskOnChip on a specific socket and memory windows */
  511. /* */
  512. /* Parameters: */
  513. /* socketNo : Number of socket to check. */
  514. /* memWinPtr : Pointer to DiskOnChip memory window. */
  515. /* */
  516. /* Returns: TRUE if this is an MDOCP, otherwise FALSE. */
  517. /*----------------------------------------------------------------------*/
  518. FLBoolean checkWinForDOC(unsigned socketNo, NDOC2window memWinPtr)
  519. {
  520. FLFlash * flash = flFlashOf(socketNo);
  521. /* Initialize socket memory access routine */
  522. flash->win = memWinPtr;
  523. #ifndef FL_NO_USE_FUNC
  524. if(setBusTypeOfFlash(flash, flBusConfig[socketNo] |
  525. FL_8BIT_DOC_ACCESS | FL_8BIT_FLASH_ACCESS))
  526. return FALSE;
  527. #endif /* FL_NO_USE_FUNC */
  528. /* set ASIC to RESET MODE */
  529. flWrite8bitReg(flash,NDOCcontrol,ASIC_RESET_MODE);
  530. flWrite8bitReg(flash,NDOCcontrol,ASIC_RESET_MODE);
  531. flWrite8bitReg(flash,NDOCcontrol,ASIC_NORMAL_MODE);
  532. flWrite8bitReg(flash,NDOCcontrol,ASIC_NORMAL_MODE);
  533. if( (flRead8bitReg(flash,NchipId) != CHIP_ID_DOC ) &&
  534. (flRead8bitReg(flash,NchipId) != CHIP_ID_MDOC))
  535. return FALSE;
  536. return checkToggle(flash);
  537. }
  538. #endif /* MTD_STANDALONE */
  539. #ifndef NO_IPL_CODE
  540. /*----------------------------------------------------------------------*/
  541. /* f o r c e D o w n l o a d */
  542. /* */
  543. /* Force download of IPL code. */
  544. /* */
  545. /* Parameters: */
  546. /* flash : Pointer identifying drive */
  547. /* */
  548. /* Returns: */
  549. /* FLStatus : 0 on success */
  550. /*----------------------------------------------------------------------*/
  551. static FLStatus forceDownLoad(FLFlash * flash)
  552. {
  553. flWrite8bitReg(flash, NfoudaryTest, 0x36);
  554. flWrite8bitReg(flash, NfoudaryTest, 0x63);
  555. flDelayMsecs(1000);
  556. return flOK;
  557. }
  558. #ifndef FL_READ_ONLY
  559. /*----------------------------------------------------------------------*/
  560. /* w r i t e I P L */
  561. /* */
  562. /* Write new IPL. */
  563. /* */
  564. /* Note : Can not start write operation from middle of IPL , unless */
  565. /* previous operation started from offset 0. */
  566. /* */
  567. /* Parameters: */
  568. /* flash : Pointer identifying drive. */
  569. /* buffer : buffer to write from. */
  570. /* length : number of bytes to write - must use full 512 bytes. */
  571. /* offset : sector number to start from. */
  572. /* flags : Modes to write IPL : */
  573. /* FL_IPL_MODE_NORMAL - Normal mode (none Strong Arm). */
  574. /* FL_IPL_DOWNLOAD - Download new IPL when done */
  575. /* FL_IPL_MODE_SA - Strong Arm IPL mode */
  576. /* FL_IPL_MODE_XSCALE - X-Scale IPL mode */
  577. /* */
  578. /* Returns: */
  579. /* flOK on success, none zero otherwise. */
  580. /*----------------------------------------------------------------------*/
  581. static FLStatus writeIPL(FLFlash * flash, const void FAR1 * buffer,
  582. word length,byte offset, unsigned flags)
  583. {
  584. dword curWrite;
  585. dword addrOffset = (dword)offset << SECTOR_SIZE_BITS;
  586. if((flags & (FL_IPL_MODE_SA | FL_IPL_MODE_XSCALE)) != 0)
  587. {
  588. DFORMAT_PRINT(("ERROR - DiskOnChip does not support this IPL mode.\r\n"));
  589. return flFeatureNotSupported;
  590. }
  591. if ((flash->erase != NULL)||(flash->write != NULL))
  592. {
  593. if ((length + addrOffset > 1024) || /* required length to long */
  594. (offset>1) ) /* only single sector or none */
  595. {
  596. DFORMAT_PRINT(("ERROR - IPL size or offset are too big for this DiskOnChip.\r\n"));
  597. return flBadLength;
  598. }
  599. if((length % SECTOR_SIZE) != 0)
  600. {
  601. DFORMAT_PRINT(("ERROR - IPL size must be a multiplication of 512 bytes.\r\n"));
  602. return flBadLength;
  603. }
  604. if(offset==0) /* Erase only if offset is 0 */
  605. checkStatus(flash->erase(flash,0,1));
  606. for (addrOffset = addrOffset << 1 ; length > 0 ;
  607. addrOffset += (SECTOR_SIZE<<1))
  608. {
  609. curWrite = TFFSMIN(length,SECTOR_SIZE);
  610. checkStatus(flash->write(flash,addrOffset,buffer,curWrite,PARTIAL_EDC));
  611. checkStatus(flash->write(flash,addrOffset+SECTOR_SIZE,buffer,curWrite,PARTIAL_EDC));
  612. buffer = (byte FAR1 *)BYTE_ADD_FAR(buffer,SECTOR_SIZE);
  613. length -= (word)curWrite;
  614. }
  615. if((flags & FL_IPL_DOWNLOAD) == 0)
  616. return flOK;
  617. if(flash->download != NULL)
  618. return flash->download(flash);
  619. DFORMAT_PRINT(("ERROR - IPL was not downloaded since MTD does not support the feature\r\n"));
  620. }
  621. DFORMAT_PRINT(("ERROR - IPL was not written since MTD is in read only mode\r\n"));
  622. return flFeatureNotSupported;
  623. }
  624. #endif /* FL_READ_ONLY */
  625. #endif /* NO_IPL_CODE */
  626. /*----------------------------------------------------------------------*/
  627. /* f l D o c W i n d o w B a s e A d d r e s s */
  628. /* */
  629. /* Return the host base address of the window. */
  630. /* If the window base address is programmable, this routine selects */
  631. /* where the base address will be programmed to. */
  632. /* */
  633. /* Parameters: */
  634. /* socketNo FLite socket No (0..SOCKETS-1) */
  635. /* lowAddress, */
  636. /* highAddress : host memory range to search for DiskOnChip 2000 */
  637. /* memory window */
  638. /* */
  639. /* Returns: */
  640. /* Host physical address of window divided by 4 KB */
  641. /* nextAddress : The address of the next DiskOnChip. */
  642. /*----------------------------------------------------------------------*/
  643. static unsigned flDocWindowBaseAddress(byte socketNo, dword lowAddress,
  644. dword highAddress, dword *nextAddress)
  645. {
  646. #ifndef NT5PORT
  647. FLBoolean stopSearch = FALSE;
  648. volatile byte deviceSearch;
  649. dword winSize;
  650. FLFlash *flash;
  651. #ifdef SEPARATED_CASCADED
  652. /* This flag is used to seperate the cascaded devices into SEPARATED volumes */
  653. /* Only the first floor responds therfore once it is found all the others are */
  654. /* reported without searching */
  655. static byte noOfFloors = 0; /* floor counter of the cascaded device */
  656. static socketOfFirstFloor = 0; /* Number of sockets already found */
  657. static dword savedNextAddress; /* Next search address (skipping aliases */
  658. switch ( noOfFloors )
  659. {
  660. case 0 : /* First access to a device */
  661. socketOfFirstFloor = noOfSockets;
  662. break;
  663. case 1 : /* Last floor of a cascaded device */
  664. *nextAddress = savedNextAddress;
  665. default : /* One of a cascaded device floors */
  666. docMtdVars[noOfSockets].currentFloor = noOfSockets - socketOfFirstFloor;
  667. noOfFloors--;
  668. return((unsigned)(lowAddress >> 12));
  669. }
  670. #endif /* SEPARATED_CASCADED */
  671. /* if memory range to search for DiskOnChip 2000 window is not specified */
  672. /* assume the standard x86 PC architecture where DiskOnChip 2000 appears */
  673. /* in a memory range reserved for BIOS expansions */
  674. if (lowAddress == 0x0L) {
  675. lowAddress = START_ADR;
  676. highAddress = STOP_ADR;
  677. }
  678. flash = flFlashOf(socketNo);
  679. #ifndef FL_NO_USE_FUNC
  680. /* Initialize socket memory access routine */
  681. if(setBusTypeOfFlash(flash, flBusConfig[socketNo] |
  682. FL_8BIT_DOC_ACCESS | FL_8BIT_FLASH_ACCESS))
  683. return ( 0 );
  684. #endif /* FL_NO_USE_FUNC */
  685. winSize = DOC_WIN;
  686. /* set all possible controllers to RESET MODE */
  687. for(*nextAddress = lowAddress ; *nextAddress <= highAddress ;
  688. *nextAddress += winSize)
  689. {
  690. flash->win = (NDOC2window )physicalToPointer(*nextAddress,winSize,socketNo);
  691. flWrite8bitReg(flash,NDOCcontrol,ASIC_RESET_MODE);
  692. flWrite8bitReg(flash,NDOCcontrol,ASIC_RESET_MODE);
  693. }
  694. /* set controller (ASIC) to NORMAL MODE and try and detect it */
  695. *nextAddress = lowAddress; /* current address initialization */
  696. for( ; *nextAddress <= highAddress; *nextAddress += winSize)
  697. {
  698. flash->win = (NDOC2window)physicalToPointer(*nextAddress,winSize,socketNo);
  699. /* set controller (ASIC) to NORMAL MODE */
  700. flWrite8bitReg(flash,NDOCcontrol,ASIC_NORMAL_MODE);
  701. flWrite8bitReg(flash,NDOCcontrol,ASIC_NORMAL_MODE);
  702. if( (flRead8bitReg(flash,NchipId) != CHIP_ID_DOC &&
  703. flRead8bitReg(flash,NchipId) != CHIP_ID_MDOC))
  704. {
  705. if( stopSearch == TRUE ) /* DiskOnChip was found */
  706. break;
  707. else continue;
  708. }
  709. if( stopSearch == FALSE ) {
  710. /* detect card - identify bit toggles on consequitive reads */
  711. if(checkToggle(flash) == FALSE)
  712. continue;
  713. /* DiskOnChip found */
  714. if( flRead8bitReg(flash,NchipId)) {
  715. flWrite8bitReg(flash,NaliasResolution,ALIAS_RESOLUTION);
  716. }
  717. else {
  718. flWrite8bitReg(flash,NdeviceSelector,ALIAS_RESOLUTION);
  719. }
  720. stopSearch = TRUE;
  721. lowAddress = *nextAddress; /* save DiskOnChip address */
  722. }
  723. else { /* DiskOnChip found, continue to skip aliases */
  724. if( (flRead8bitReg(flash,NchipId) != CHIP_ID_DOC) &&
  725. (flRead8bitReg(flash,NchipId) != CHIP_ID_MDOC) )
  726. break;
  727. /* detect card - identify bit toggles on consequitive reads */
  728. if(checkToggle(flash) == FALSE)
  729. break;
  730. /* check for Alias */
  731. deviceSearch = (byte)((flRead8bitReg(flash,NchipId) == CHIP_ID_MDOC) ?
  732. flRead8bitReg(flash,NaliasResolution) :
  733. flRead8bitReg(flash,NdeviceSelector));
  734. if( deviceSearch != ALIAS_RESOLUTION )
  735. break;
  736. }
  737. }
  738. if( stopSearch == FALSE ) /* DiskOnChip 2000 memory window not found */
  739. return( 0 );
  740. #ifdef SEPARATED_CASCADED
  741. /* count the number of floors cascaded to this address */
  742. flash->win = (NDOC2window)physicalToPointer(lowAddress,winSize,socketNo);
  743. for ( noOfFloors=1; noOfFloors < MAX_FLASH_DEVICES_DOC ;noOfFloors++)
  744. {
  745. flWrite8bitReg(flash,NASICselect,noOfFloors);
  746. if(checkToggle(flash) == FALSE)
  747. break;
  748. }
  749. /* If there are more then 1 floor on this address save the next device address and report
  750. that the next device is actualy on the same address as the current */
  751. if ( noOfFloors > 1)
  752. {
  753. flWrite8bitReg(flash,NASICselect,0);
  754. savedNextAddress = *nextAddress;
  755. *nextAddress = lowAddress;
  756. }
  757. noOfFloors--;
  758. #endif /* SEPARATED_CASCADED */
  759. return((unsigned)(lowAddress >> 12));
  760. #else /*NT5PORT*/
  761. DEBUG_PRINT(("Tffsport mdocplus.c :flDocWindowBaseAddress(): Before returning baseAddress()\n"));
  762. return (unsigned)(((ULONG_PTR)pdriveInfo[socketNo].winBase)>> 12);
  763. #endif /*NT5PORT*/
  764. }
  765. /*----------------------------------------------------------------------*/
  766. /* s e t A d d r e s s */
  767. /* */
  768. /* Latch address to selected flash device. */
  769. /* */
  770. /* Parameters: */
  771. /* flash : Pointer identifying drive */
  772. /* address : address to set. */
  773. /* */
  774. /*----------------------------------------------------------------------*/
  775. static void setAddress (FLFlash * flash, CardAddress address)
  776. {
  777. address &= (flash->chipSize * flash->interleaving - 1); /* address within flash device */
  778. #ifdef BIG_PAGE_ENABLED
  779. if ( flash->flags & BIG_PAGE )
  780. #endif /* BIG_PAGE_ENABLED */
  781. {
  782. /*
  783. bits 0..7 stays as are
  784. bit 8 is thrown away from address
  785. bits 31..9 -> bits 30..8
  786. */
  787. address = ((address >> 9) << 8) | ((byte)address);
  788. }
  789. writeSignals (flash, FLASH_IO | ALE | CE);
  790. #ifdef SLOW_IO_FLAG
  791. flWrite8bitReg(flash,NslowIO,(Reg8bitType)address);
  792. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)address);
  793. flWrite8bitReg(flash,NslowIO,(Reg8bitType)(address >> 8));
  794. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(address >> 8));
  795. flWrite8bitReg(flash,NslowIO,(Reg8bitType)(address >> 16));
  796. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(address >> 16));
  797. if( flash->flags & BIG_ADDR ) {
  798. flWrite8bitReg(flash,NslowIO,(Reg8bitType)(address >> 24));
  799. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(address >> 24));
  800. }
  801. #else
  802. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)address);
  803. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(address >> 8));
  804. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(address >> 16));
  805. if( flash->flags & BIG_ADDR )
  806. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(address >> 24));
  807. #endif
  808. if( NFDC21thisVars->flags & MDOC_ASIC )
  809. flWrite8bitReg(flash,NwritePipeTerm,(Reg8bitType)0);
  810. writeSignals (flash, ECC_IO | FLASH_IO | CE);
  811. }
  812. /*----------------------------------------------------------------------*/
  813. /* c o m m a n d */
  814. /* */
  815. /* Latch command byte to selected flash device. */
  816. /* */
  817. /* Parameters: */
  818. /* flash : Pointer identifying drive */
  819. /* code : Command to set. */
  820. /* */
  821. /*----------------------------------------------------------------------*/
  822. static void command(FLFlash * flash, Reg8bitType flCode)
  823. {
  824. writeSignals (flash, FLASH_IO | CLE | CE);
  825. #ifdef SLOW_IO_FLAG
  826. flWrite8bitReg(flash,NslowIO,flCode);
  827. #endif
  828. flWrite8bitReg(flash,NFDC21thisIO,flCode);
  829. if( NFDC21thisVars->flags & MDOC_ASIC )
  830. flWrite8bitReg(flash,NwritePipeTerm,flCode);
  831. }
  832. /*----------------------------------------------------------------------*/
  833. /* s e l e c t F l o o r */
  834. /* */
  835. /* Select floor (0 .. totalFloors-1). */
  836. /* */
  837. /* Parameters: */
  838. /* flash : Pointer identifying drive */
  839. /* address : Select floor for this address. */
  840. /* */
  841. /*----------------------------------------------------------------------*/
  842. #ifndef SEPARATED_CASCADED
  843. static void selectFloor (FLFlash * flash, CardAddress *address)
  844. {
  845. if( flash->noOfFloors > 1 )
  846. {
  847. byte floorToUse = (byte)((*address) / NFDC21thisVars->floorSize);
  848. NFDC21thisVars->currentFloor = floorToUse;
  849. flWrite8bitReg(flash,NASICselect,floorToUse);
  850. *address -= (floorToUse * NFDC21thisVars->floorSize);
  851. }
  852. }
  853. #endif /* SEPARATED_CASCADED */
  854. /*----------------------------------------------------------------------*/
  855. /* m a p W i n */
  856. /* */
  857. /* Map window to selected flash device. */
  858. /* */
  859. /* Parameters: */
  860. /* flash : Pointer identifying drive */
  861. /* address : Map window to this address. */
  862. /* */
  863. /*----------------------------------------------------------------------*/
  864. static void mapWin (FLFlash * flash, CardAddress *address)
  865. {
  866. /* NOTE: normally both ways to obtain DOC 2000 window segment should
  867. return the same value. */
  868. NFDC21thisWin = (NDOC2window)flMap(flash->socket, 0);
  869. #ifndef SEPARATED_CASCADED
  870. selectFloor (flash, address);
  871. #else
  872. flWrite8bitReg(flash,NASICselect,NFDC21thisVars->currentFloor);
  873. #endif /* SEPARATED_CASCADED */
  874. /* select chip within floor */
  875. selectChip (flash, (Reg8bitType)((*address) / (flash->chipSize * flash->interleaving))) ;
  876. }
  877. /*----------------------------------------------------------------------*/
  878. /* r d B u f */
  879. /* */
  880. /* Auxiliary routine for Read(), read from page. */
  881. /* */
  882. /* Parameters: */
  883. /* flash : Pointer identifying drive */
  884. /* buf : Buffer to read into. */
  885. /* howmany : Number of bytes to read. */
  886. /* */
  887. /*----------------------------------------------------------------------*/
  888. static void rdBuf (FLFlash * flash, byte FAR1 *buf, word howmany)
  889. {
  890. volatile Reg8bitType junk = 0;
  891. register word i;
  892. #ifdef SLOW_IO_FLAG
  893. /* slow flash requires first read to be done from CDSN_Slow_IO
  894. and only second one from CDSN_IO - this extends read access */
  895. for( i = 0 ;( i < howmany ); i++ ) {
  896. junk = flRead8bitReg(flash,NslowIO);
  897. buf[i] = (byte)flRead8bitReg(flash,NFDC21thisIO+(i & 0x01));
  898. }
  899. #else
  900. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  901. junk += flRead8bitReg(flash,NreadPipeInit);
  902. howmany--;
  903. i = TFFSMIN( howmany, MDOC_ALIAS_RANGE );
  904. docread(flash->win,NFDC21thisIO,buf,i);
  905. }
  906. else i = 0;
  907. if( howmany > i )
  908. docread(flash->win,NFDC21thisIO,buf+i,(word)(howmany-i));
  909. if( NFDC21thisVars->flags & MDOC_ASIC )
  910. buf[howmany] = flRead8bitReg(flash,NreadLastData);
  911. #endif
  912. }
  913. #ifndef FL_READ_ONLY
  914. /*----------------------------------------------------------------------*/
  915. /* w r B u f */
  916. /* */
  917. /* Auxiliary routine for Write(), write to page from buffer. */
  918. /* */
  919. /* Parameters: */
  920. /* flash : Pointer identifying drive */
  921. /* buf : Buffer to write from. */
  922. /* howmany : Number of bytes to write. */
  923. /* */
  924. /*----------------------------------------------------------------------*/
  925. static void wrBuf (FLFlash * flash, const byte FAR1 *buf, word howmany )
  926. {
  927. #ifdef SLOW_IO_FLAG
  928. register int i;
  929. /* slow flash requires first write go to CDSN_Slow_IO and
  930. only second one to CDSN_IO - this extends write access */
  931. for ( i = 0 ;( i < howmany ); i++ ) {
  932. flWrite8bitReg(flash,NslowIO,(Reg8bitType)buf[i]);
  933. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)buf[i]);
  934. }
  935. #else
  936. docwrite(flash->win,NFDC21thisIO,(byte FAR1 *)buf,howmany);
  937. if( NFDC21thisVars->flags & MDOC_ASIC )
  938. flWrite8bitReg(flash,NwritePipeTerm,(Reg8bitType)0);
  939. #endif
  940. }
  941. /*----------------------------------------------------------------------*/
  942. /* w r S e t */
  943. /* */
  944. /* Auxiliary routine for Write(), set page data. */
  945. /* */
  946. /* Parameters: */
  947. /* flash : Pointer identifying drive */
  948. /* ch : Set page to this byte */
  949. /* howmany : Number of bytes to set. */
  950. /* */
  951. /*----------------------------------------------------------------------*/
  952. static void wrSet (FLFlash * flash, const Reg8bitType ch, word howmany )
  953. {
  954. #ifdef SLOW_IO_FLAG
  955. register int i;
  956. /* slow flash requires first write go to CDSN_Slow_IO and
  957. only second one to CDSN_IO - this extends write access */
  958. for (i = 0 ;( i < howmany ); i++ ) {
  959. flWrite8bitReg(flash,NslowIO,(Reg8bitType)ch);
  960. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)ch);
  961. }
  962. #else
  963. docset(flash->win,NFDC21thisIO,howmany,ch);
  964. if( NFDC21thisVars->flags & MDOC_ASIC )
  965. flWrite8bitReg(flash,NwritePipeTerm,(Reg8bitType)0);
  966. #endif
  967. }
  968. /*----------------------------------------------------------------------*/
  969. /* r e a d S t a t u s */
  970. /* */
  971. /* Read status of selected flash device. */
  972. /* */
  973. /* Parameters: */
  974. /* flash : Pointer identifying drive */
  975. /* */
  976. /* Returns: */
  977. /* Chip status. */
  978. /* */
  979. /*----------------------------------------------------------------------*/
  980. static Reg8bitType readStatus (FLFlash * flash)
  981. {
  982. Reg8bitType chipStatus;
  983. volatile Reg8bitType junk = 0;
  984. flWrite8bitReg(flash,NFDC21thisIO,READ_STATUS);
  985. if( NFDC21thisVars->flags & MDOC_ASIC )
  986. flWrite8bitReg(flash,NwritePipeTerm,READ_STATUS);
  987. writeSignals (flash, FLASH_IO | CE | WP);
  988. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  989. junk += flRead8bitReg(flash,NreadPipeInit); /* load first data into pipeline */
  990. chipStatus = flRead8bitReg(flash,NreadLastData); /* read flash status */
  991. }
  992. else {
  993. junk += flRead8bitReg(flash,NslowIO);
  994. chipStatus = flRead8bitReg(flash,NFDC21thisIO);
  995. }
  996. return chipStatus;
  997. }
  998. #endif /* FL_READ_ONLY */
  999. /*----------------------------------------------------------------------*/
  1000. /* r e a d C o m m a n d */
  1001. /* */
  1002. /* Issue read command. */
  1003. /* */
  1004. /* Parametes: */
  1005. /* flash : Pointer identifying drive */
  1006. /* cmd : Command to issue (according to area). */
  1007. /* addr : address to read from. */
  1008. /* */
  1009. /*----------------------------------------------------------------------*/
  1010. static void readCommand (FLFlash * flash, PointerOp cmd, CardAddress addr)
  1011. {
  1012. command (flash, (Reg8bitType)cmd); /* move flash pointer to respective area of the page */
  1013. setAddress (flash, addr);
  1014. waitForReady(flash);
  1015. }
  1016. #ifndef FL_READ_ONLY
  1017. /*----------------------------------------------------------------------*/
  1018. /* w r i t e C o m m a n d */
  1019. /* */
  1020. /* Issue write command. */
  1021. /* */
  1022. /* Parametes: */
  1023. /* flash : Pointer identifying drive */
  1024. /* cmd : Command to issue (according to area). */
  1025. /* addr : address to write to. */
  1026. /* */
  1027. /*----------------------------------------------------------------------*/
  1028. static void writeCommand (FLFlash * flash, PointerOp cmd, CardAddress addr)
  1029. {
  1030. if( flash->flags & FULL_PAGE ) {
  1031. command (flash, RESET_FLASH);
  1032. waitForReady(flash);
  1033. if( cmd != AREA_A ) {
  1034. #ifdef SLOW_IO_FLAG
  1035. flWrite8bitReg(flash,NslowIO,(byte)cmd);
  1036. #endif
  1037. flWrite8bitReg(flash,NFDC21thisIO,(byte)cmd);
  1038. if( NFDC21thisVars->flags & MDOC_ASIC )
  1039. flWrite8bitReg(flash,NwritePipeTerm,(byte)cmd);
  1040. }
  1041. }
  1042. else
  1043. command (flash, (Reg8bitType)cmd); /* move flash pointer to respective area of the page */
  1044. #ifdef SLOW_IO_FLAG
  1045. flWrite8bitReg(flash,NslowIO,SERIAL_DATA_INPUT);
  1046. #endif
  1047. flWrite8bitReg(flash,NFDC21thisIO,SERIAL_DATA_INPUT);
  1048. if( NFDC21thisVars->flags & MDOC_ASIC )
  1049. flWrite8bitReg(flash,NwritePipeTerm,SERIAL_DATA_INPUT);
  1050. setAddress (flash, addr);
  1051. waitForReady(flash);
  1052. }
  1053. /*----------------------------------------------------------------------*/
  1054. /* w r i t e E x e c u t e */
  1055. /* */
  1056. /* Execute write. */
  1057. /* */
  1058. /* Parametes: */
  1059. /* flash : Pointer identifying drive */
  1060. /* */
  1061. /* Returns: */
  1062. /* FLStatus : 0 on success, otherwise failed. */
  1063. /* */
  1064. /*----------------------------------------------------------------------*/
  1065. static FLStatus writeExecute (FLFlash * flash)
  1066. {
  1067. command (flash, SETUP_WRITE); /* execute page program */
  1068. waitForReady(flash);
  1069. if( readStatus(flash) & (byte)(FAIL) ) {
  1070. DEBUG_PRINT(("Debug: NFDC 2148 write failed.\r\n"));
  1071. return( flWriteFault );
  1072. }
  1073. return( flOK );
  1074. }
  1075. /*----------------------------------------------------------------------*/
  1076. /* w r i t e O n e S e c t o r */
  1077. /* */
  1078. /* Write data in one 512-byte block to flash. */
  1079. /* Assuming that EDC mode never requested on partial block writes. */
  1080. /* */
  1081. /* Parameters: */
  1082. /* flash : Pointer identifying drive */
  1083. /* address : Address of sector to write to. */
  1084. /* buffer : buffer to write from. */
  1085. /* length : number of bytes to write (up to sector size). */
  1086. /* modes : OVERWRITE, EDC flags etc. */
  1087. /* */
  1088. /* Returns: */
  1089. /* FLStatus : 0 on success, otherwise failed. */
  1090. /* */
  1091. /*----------------------------------------------------------------------*/
  1092. static FLStatus writeOneSector(FLFlash * flash,
  1093. CardAddress address,
  1094. const void FAR1 *buffer,
  1095. word length,
  1096. word modes)
  1097. {
  1098. byte FAR1 *pbuffer = (byte FAR1 *)buffer; /* to write from */
  1099. FLStatus status;
  1100. #ifndef NO_EDC_MODE
  1101. byte syndrom[SYNDROM_BYTES];
  1102. static byte anandMark[2] = { 0x55, 0x55 };
  1103. #endif
  1104. PointerOp cmd = AREA_A ;
  1105. word prePad;
  1106. #ifdef BIG_PAGE_ENABLED
  1107. word toFirstPage = 0, toSecondPage = 0;
  1108. #endif /* BIG_PAGE_ENABLED */
  1109. #ifndef MTD_STANDALONE
  1110. if (flWriteProtected(flash->socket))
  1111. return( flWriteProtect );
  1112. #endif
  1113. mapWin(flash, &address); /* select flash device */
  1114. /* move flash pointer to areas A,B or C of page */
  1115. makeCommand(flash, &cmd, &address, modes);
  1116. if( (flash->flags & FULL_PAGE) && (cmd == AREA_B) ) {
  1117. prePad = (word)(2 + ((word) address & NFDC21thisVars->pageMask));
  1118. writeCommand(flash, AREA_A, address + NFDC21thisVars->pageAreaSize - prePad);
  1119. wrSet(flash, 0xFF, prePad);
  1120. }
  1121. else
  1122. writeCommand(flash, cmd, address);
  1123. #ifndef NO_EDC_MODE
  1124. if( modes & EDC )
  1125. eccONwrite(flash); /* ECC ON for write */
  1126. #endif
  1127. #ifdef BIG_PAGE_ENABLED
  1128. if( !(flash->flags & BIG_PAGE) ) /* 2M on INLV=1 */
  1129. {
  1130. /* write up to two pages separately */
  1131. if( modes & EXTRA )
  1132. toFirstPage = EXTRA_LEN - ((word)address & (EXTRA_LEN-1));
  1133. else
  1134. toFirstPage = CHIP_PAGE_SIZE - ((word)address & (CHIP_PAGE_SIZE-1));
  1135. if(toFirstPage > length)
  1136. toFirstPage = length;
  1137. toSecondPage = length - toFirstPage;
  1138. wrBuf(flash, pbuffer, toFirstPage); /* starting page .. */
  1139. if ( toSecondPage > 0 )
  1140. {
  1141. if (toFirstPage > 0) /* started on 1st page */
  1142. checkStatus( writeExecute(flash) ); /* done with 1st page */
  1143. if( modes & EXTRA )
  1144. address -= (CHIP_PAGE_SIZE + ((word)address & (EXTRA_LEN-1)));
  1145. writeCommand(flash, cmd, address + toFirstPage);
  1146. wrBuf (flash, pbuffer + toFirstPage, toSecondPage); /* user data */
  1147. }
  1148. }
  1149. else /* 4M or 8M */
  1150. #endif /* BIG_PAGE_ENABLED */
  1151. wrBuf (flash, pbuffer, length); /* user data */
  1152. #ifndef NO_EDC_MODE
  1153. if(modes & EDC)
  1154. {
  1155. register int i;
  1156. writeSignals (flash, ECC_IO | CE ); /* disable flash access */
  1157. /* 3 dummy zero-writes to clock the data through pipeline */
  1158. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  1159. for( i = 0;( i < 3 ); i++ ) {
  1160. flWrite8bitReg(flash,NNOPreg,(Reg8bitType)0);
  1161. }
  1162. }
  1163. else {
  1164. wrSet (flash, 0x00, 3 );
  1165. }
  1166. writeSignals (flash, ECC_IO | FLASH_IO | CE ); /* enable flash access */
  1167. docread(flash->win,Nsyndrom,syndrom,SYNDROM_BYTES);
  1168. #ifdef D2TST
  1169. tffscpy(saveSyndromForDumping,syndrom,SYNDROM_BYTES);
  1170. #endif
  1171. eccOFF(flash); /* ECC OFF */
  1172. wrBuf (flash, (const byte FAR1 *)syndrom, SYNDROM_BYTES);
  1173. wrBuf (flash, (const byte FAR1 *)anandMark, sizeof(anandMark) );
  1174. }
  1175. #endif /* NO_EDC_MODE */
  1176. status = writeExecute(flash); /* abort if write failure */
  1177. if(status != flOK)
  1178. return status;
  1179. writeSignals(flash, FLASH_IO | WP);
  1180. #ifdef VERIFY_WRITE
  1181. #ifndef MTD_STANDALONE
  1182. if (flash->socket->verifyWrite==FL_OFF)
  1183. return status;
  1184. #endif /* MTD_STANDALONE */
  1185. /* Read back after write and verify */
  1186. if( modes & OVERWRITE )
  1187. pbuffer = (byte FAR1 *) buffer; /* back to original data */
  1188. readCommand (flash, cmd, address); /* move flash pointer to areas A,B or C of page */
  1189. #ifdef BIG_PAGE_ENABLED
  1190. if( !(flash->flags & BIG_PAGE) )
  1191. {
  1192. rdBuf (flash, NFDC21thisVars->readBackBuffer, toFirstPage);
  1193. if(tffscmp (pbuffer, NFDC21thisVars->readBackBuffer, toFirstPage) ) {
  1194. DEBUG_PRINT(("Debug: NFDC 2148 write failed in verification.\r\n"));
  1195. return( flWriteFault );
  1196. }
  1197. if ( toSecondPage > 0 )
  1198. {
  1199. readCommand (flash, AREA_A, address + toFirstPage);
  1200. rdBuf (flash, NFDC21thisVars->readBackBuffer + toFirstPage, toSecondPage);
  1201. if( tffscmp (pbuffer + toFirstPage, NFDC21thisVars->readBackBuffer + toFirstPage, toSecondPage)) {
  1202. DEBUG_PRINT(("Debug: NFDC 2148 write failed in verification.\r\n"));
  1203. return( flWriteFault );
  1204. }
  1205. }
  1206. }
  1207. else
  1208. #endif /* BIG_PAGE_ENABLED */
  1209. {
  1210. rdBuf (flash, NFDC21thisVars->readBackBuffer, length);
  1211. if( tffscmp (pbuffer, NFDC21thisVars->readBackBuffer, length) ) {
  1212. DEBUG_PRINT(("Debug: NFDC 2148 write failed in verification.\r\n"));
  1213. return( flWriteFault );
  1214. }
  1215. }
  1216. /* then ECC and special ANAND mark */
  1217. #ifndef NO_EDC_MODE
  1218. if( modes & EDC )
  1219. {
  1220. rdBuf (flash, NFDC21thisVars->readBackBuffer, SYNDROM_BYTES);
  1221. if( tffscmp (syndrom, NFDC21thisVars->readBackBuffer, SYNDROM_BYTES) )
  1222. return( flWriteFault );
  1223. rdBuf (flash, NFDC21thisVars->readBackBuffer, sizeof(anandMark));
  1224. if( tffscmp (anandMark, NFDC21thisVars->readBackBuffer, sizeof(anandMark)) )
  1225. return( flWriteFault );
  1226. }
  1227. #endif /* NO_EDC_MODE */
  1228. writeSignals (flash, FLASH_IO | WP);
  1229. waitForReady(flash); /* Serial Read Cycle Entry */
  1230. #endif /* VERIFY_WRITE */
  1231. return( flOK );
  1232. }
  1233. /*----------------------------------------------------------------------*/
  1234. /* d o c 2 W r i t e */
  1235. /* */
  1236. /* Write some data to the flash. This routine will be registered as the */
  1237. /* write routine for this MTD. */
  1238. /* */
  1239. /* Parameters: */
  1240. /* flash : Pointer identifying drive */
  1241. /* address : Address of sector to write to. */
  1242. /* buffer : buffer to write from. */
  1243. /* length : number of bytes to write (up to sector size). */
  1244. /* modes : OVERWRITE, EDC flags etc. */
  1245. /* */
  1246. /* Returns: */
  1247. /* FLStatus : 0 on success, otherwise failed. */
  1248. /* */
  1249. /*----------------------------------------------------------------------*/
  1250. static FLStatus doc2Write(FLFlash * flash,
  1251. CardAddress address,
  1252. const void FAR1 *buffer,
  1253. dword length,
  1254. word modes)
  1255. {
  1256. char FAR1 *temp = (char FAR1 *)buffer;
  1257. FLStatus status;
  1258. #ifdef BIG_PAGE_ENABLED
  1259. word block = (word)((modes & EXTRA) ? EXTRA_LEN : SECTOR_SIZE);
  1260. #else
  1261. word block = (word)((modes & EXTRA) ? SECTOR_EXTRA_LEN : SECTOR_SIZE);
  1262. #endif /* BIG_PAGE_ENABLED */
  1263. word writeNow = block - ((word)address & (block - 1));
  1264. #ifdef ENVIRONMENT_VARS
  1265. if(flSuspendMode & FL_SUSPEND_WRITE)
  1266. return flIOCommandBlocked;
  1267. #endif /* ENVIRONMENT_VARS */
  1268. /* write in BLOCKs; first and last might be partial */
  1269. chkASICmode(flash);
  1270. while( length > 0 )
  1271. {
  1272. if(writeNow > length)
  1273. writeNow = (word)length;
  1274. /* turn off EDC on partial block write */
  1275. status = writeOneSector(flash, address, temp, writeNow,
  1276. (word)((writeNow != SECTOR_SIZE) ? (modes &= ~EDC) : modes) );
  1277. if(status!=flOK)
  1278. return status;
  1279. length -= writeNow;
  1280. address += writeNow;
  1281. temp += writeNow;
  1282. writeNow = block; /* align at BLOCK */
  1283. }
  1284. return( flOK );
  1285. }
  1286. #endif /* FL_READ_ONLY */
  1287. /*----------------------------------------------------------------------*/
  1288. /* r e a d O n e S e c t o r */
  1289. /* */
  1290. /* Read up to one 512-byte block from flash. */
  1291. /* */
  1292. /* Parameters: */
  1293. /* flash : Pointer identifying drive */
  1294. /* address : Address to read from. */
  1295. /* buffer : buffer to read to. */
  1296. /* length : number of bytes to read (up to sector size). */
  1297. /* modes : EDC flag etc. */
  1298. /* */
  1299. /* Notes: big_page_enabled does not support PARTIAL_EDC FLAG */
  1300. /* */
  1301. /* Returns: */
  1302. /* FLStatus : 0 on success, otherwise failed. */
  1303. /* */
  1304. /*----------------------------------------------------------------------*/
  1305. static FLStatus readOneSector (FLFlash * flash,
  1306. CardAddress address,
  1307. void FAR1 *buffer,
  1308. word length,
  1309. word modes)
  1310. {
  1311. #ifndef NO_EDC_MODE
  1312. byte extraBytes[SYNDROM_BYTES];
  1313. #ifdef MTD_STANDALONE
  1314. int index;
  1315. #endif
  1316. #endif
  1317. FLStatus stat = flOK;
  1318. PointerOp cmd = AREA_A; /* default for .... */
  1319. CardAddress addr = address; /* .... KM29N16000 */
  1320. #ifdef BIG_PAGE_ENABLED
  1321. int toFirstPage, toSecondPage;
  1322. #endif /* BIG_PAGE_ENABLED */
  1323. mapWin(flash, &addr);
  1324. makeCommand(flash, &cmd, &addr, modes); /* move flash pointer to areas A,B or C of page */
  1325. readCommand(flash, cmd, addr);
  1326. #ifndef NO_EDC_MODE
  1327. if( modes & EDC )
  1328. eccONread(flash);
  1329. #endif
  1330. #ifdef BIG_PAGE_ENABLED
  1331. if( !(flash->flags & BIG_PAGE) )
  1332. {
  1333. /* read up to two pages separately */
  1334. if( modes & EXTRA )
  1335. toFirstPage = EXTRA_LEN - ((word)addr & (EXTRA_LEN-1));
  1336. else
  1337. toFirstPage = CHIP_PAGE_SIZE - ((word)addr & (CHIP_PAGE_SIZE-1));
  1338. if(toFirstPage > length)
  1339. toFirstPage = length;
  1340. toSecondPage = length - toFirstPage;
  1341. rdBuf (flash, (byte FAR1 *)buffer, toFirstPage ); /* starting page */
  1342. if ( toSecondPage > 0 ) /* next page */
  1343. {
  1344. if( modes & EXTRA )
  1345. addr -= (CHIP_PAGE_SIZE + ((word)addr & (EXTRA_LEN-1)));
  1346. readCommand (flash, cmd, addr + toFirstPage);
  1347. rdBuf(flash, (byte FAR1 *)buffer + toFirstPage, toSecondPage );
  1348. }
  1349. }
  1350. else
  1351. #endif /* BIG_PAGE_ENABLED */
  1352. {
  1353. rdBuf(flash, (byte FAR1 *)buffer, length );
  1354. #ifndef NO_EDC_MODE
  1355. if((modes & PARTIAL_EDC) &&
  1356. (((word)address & NFDC21thisVars->pageMask) == 0))
  1357. {
  1358. /* Partial page read with EDC must let rest of page through
  1359. the HW edc mechanism */
  1360. word unreadBytes;
  1361. for (unreadBytes = SECTOR_SIZE - length;unreadBytes > 0;unreadBytes--)
  1362. {
  1363. cmd = (PointerOp)flRead8bitReg(flash, NFDC21thisIO);
  1364. }
  1365. }
  1366. #endif /* NO_EDC_MODE */
  1367. }
  1368. #ifndef NO_EDC_MODE
  1369. if( modes & EDC )
  1370. { /* read syndrom to let it through the ECC unit */
  1371. rdBuf(flash, extraBytes, SYNDROM_BYTES );
  1372. if( eccError(flash) ) /* An EDC error was found */
  1373. {
  1374. #ifdef MTD_STANDALONE
  1375. /* Check if all of the EDC bytes are FF's. If so ignore the EDC */
  1376. /* assuming that it has'nt been used due to programing of less then */
  1377. /* 512 bytes */
  1378. for(index=0;index<SYNDROM_BYTES;index++)
  1379. {
  1380. if (extraBytes[index]!=0xFF)
  1381. break;
  1382. }
  1383. if (index!=SYNDROM_BYTES) /* not all of the EDC bytes are FF's */
  1384. #endif /* MTD_STANDALONE */
  1385. {
  1386. /* try to fix ECC error */
  1387. if ( modes & NO_SECOND_TRY ) /* 2nd try */
  1388. {
  1389. byte syndrom[SYNDROM_BYTES];
  1390. byte tmp;
  1391. docread(flash->win,Nsyndrom,syndrom,SYNDROM_BYTES);
  1392. tmp = syndrom[0]; /* Swap 1 and 3 words */
  1393. syndrom[0] = syndrom[4];
  1394. syndrom[4] = tmp;
  1395. tmp = syndrom[1];
  1396. syndrom[1] = syndrom[5];
  1397. syndrom[5] = tmp;
  1398. if( flCheckAndFixEDC( (char FAR1 *)buffer, (char*)syndrom, 1) != NO_EDC_ERROR)
  1399. {
  1400. DEBUG_PRINT(("Debug: EDC error for NFDC 2148.\r\n"));
  1401. stat = flDataError;
  1402. }
  1403. }
  1404. else /* 1st try - try once more */
  1405. return( readOneSector( flash, address, buffer, length,
  1406. (word)(modes | NO_SECOND_TRY) ) );
  1407. }
  1408. }
  1409. eccOFF(flash);
  1410. }
  1411. #endif /* NO_EDC_MODE */
  1412. writeSignals (flash, FLASH_IO | WP);
  1413. if( (modes & EXTRA) && /* Serial Read Cycle Entry */
  1414. ((length + (((word)addr) & (NFDC21thisVars->tailSize - 1)))
  1415. == NFDC21thisVars->tailSize) )
  1416. waitForReady(flash);
  1417. return( stat );
  1418. }
  1419. /*----------------------------------------------------------------------*/
  1420. /* d o c 2 R e a d */
  1421. /* */
  1422. /* Read some data from the flash. This routine will be registered as */
  1423. /* the read routine for this MTD. */
  1424. /* */
  1425. /* Parameters: */
  1426. /* flash : Pointer identifying drive */
  1427. /* address : Address to read from. */
  1428. /* buffer : buffer to read to. */
  1429. /* length : number of bytes to read (up to sector size). */
  1430. /* modes : EDC flag etc. */
  1431. /* */
  1432. /* Returns: */
  1433. /* FLStatus : 0 on success, otherwise failed. */
  1434. /* */
  1435. /*----------------------------------------------------------------------*/
  1436. static FLStatus doc2Read(FLFlash * flash,
  1437. CardAddress address,
  1438. void FAR1 *buffer,
  1439. dword length,
  1440. word modes)
  1441. {
  1442. char FAR1 *temp = (char FAR1 *)buffer;
  1443. FLStatus status;
  1444. word readNow;
  1445. #ifdef BIG_PAGE_ENABLED
  1446. word block = (word)(( modes & EXTRA ) ? EXTRA_LEN : SECTOR_SIZE );
  1447. #else
  1448. word block = (word)(( modes & EXTRA ) ? SECTOR_EXTRA_LEN : SECTOR_SIZE );
  1449. #endif /* BIG_PAGE_ENABLED */
  1450. #ifdef ENVIRONMENT_VARS
  1451. if((flSuspendMode & FL_SUSPEND_IO) == FL_SUSPEND_IO)
  1452. return flIOCommandBlocked;
  1453. #endif /* ENVIRONMENT_VARS */
  1454. chkASICmode(flash);
  1455. /* read in BLOCKs; first and last might be partial */
  1456. readNow = block - ((word)address & (block - 1));
  1457. while( length > 0 ) {
  1458. if( readNow > length )
  1459. readNow = (word)length;
  1460. /* turn off EDC on partial block read */
  1461. status = readOneSector(flash, address, temp, readNow, (word)(
  1462. ((readNow != SECTOR_SIZE) && (modes != PARTIAL_EDC)) ?
  1463. modes &=~PARTIAL_EDC : modes));
  1464. if(status != flOK)
  1465. return status;
  1466. length -= readNow;
  1467. address += readNow;
  1468. temp += readNow;
  1469. readNow = block; /* align at BLOCK */
  1470. }
  1471. return( flOK );
  1472. }
  1473. #ifndef FL_READ_ONLY
  1474. #if (defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT))
  1475. /*----------------------------------------------------------------------*/
  1476. /* c h e c k E r a s e */
  1477. /* */
  1478. /* Check if media is truly erased (main areas of page only). */
  1479. /* */
  1480. /* Note to save on memory consumption the 1k read back buffer is used */
  1481. /* Only when the VERIFY_ERASE compilation flag is set. */
  1482. /* */
  1483. /* Parameters: */
  1484. /* flash : Pointer identifying drive */
  1485. /* address : Address of page to check. */
  1486. /* */
  1487. /* Returns: */
  1488. /* FLStatus : 0 if page is erased, otherwise writeFault. */
  1489. /* */
  1490. /*----------------------------------------------------------------------*/
  1491. static FLStatus checkErase( FLFlash * flash, CardAddress address )
  1492. {
  1493. register int i, j;
  1494. word inc = READ_BACK_BUFFER_SIZE;
  1495. dword * bufPtr = (dword *)NFDC21thisVars->readBackBuffer;
  1496. CardAddress curAddress = address;
  1497. word block = (word)(flash->erasableBlockSize / inc);
  1498. dword * endBufPtr = bufPtr+(inc / sizeof(dword));
  1499. dword * curBufPtr;
  1500. /* Check main area */
  1501. for ( i = 0 ; i < block ; i++, curAddress += inc )
  1502. {
  1503. if ( doc2Read(flash,curAddress,(void FAR1 *)bufPtr,(dword)inc,0) != flOK )
  1504. return( flWriteFault );
  1505. for ( curBufPtr = bufPtr ;
  1506. curBufPtr < endBufPtr ; curBufPtr++)
  1507. if ( *bufPtr != 0xFFFFFFFFL )
  1508. return( flWriteFault );
  1509. }
  1510. /* Check extra area */
  1511. for ( i = 0 ; i < NFDC21thisVars->pagesPerBlock ; i++,address+=SECTOR_SIZE)
  1512. {
  1513. if ( doc2Read(flash,address,(void FAR1 *)bufPtr,
  1514. NFDC21thisVars->tailSize, EXTRA) != flOK )
  1515. return( flWriteFault );
  1516. for (j=0;j<(NFDC21thisVars->tailSize>>2);j++)
  1517. {
  1518. if (bufPtr[j] != 0xFFFFFFFFL)
  1519. return( flWriteFault );
  1520. }
  1521. }
  1522. return( flOK );
  1523. }
  1524. #endif /* VERIFY_ERASE or MTD_RECONSTRUCT_BBT */
  1525. /*----------------------------------------------------------------------*/
  1526. /* d o c 2 E r a s e */
  1527. /* */
  1528. /* Erase number of blocks. This routine will be registered as the */
  1529. /* erase routine for this MTD. */
  1530. /* */
  1531. /* Note - can not erase all units of 1GB DiskOnChip. */
  1532. /* */
  1533. /* Parameters: */
  1534. /* flash : Pointer identifying drive */
  1535. /* blockNo : First block to erase. */
  1536. /* blocksToErase : Number of blocks to erase. */
  1537. /* */
  1538. /* Returns: */
  1539. /* FLStatus : 0 on success, otherwise failed. */
  1540. /* */
  1541. /*----------------------------------------------------------------------*/
  1542. static FLStatus doc2Erase(FLFlash * flash,
  1543. word blockNo,
  1544. word blocksToErase)
  1545. {
  1546. FLStatus status = flOK;
  1547. word floorToUse;
  1548. word nextFloorBlockNo, i;
  1549. CardAddress startAddress = (CardAddress)blockNo * flash->erasableBlockSize;
  1550. CardAddress address = startAddress;
  1551. #ifdef ENVIRONMENT_VARS
  1552. if(flSuspendMode & FL_SUSPEND_WRITE)
  1553. return flIOCommandBlocked;
  1554. #endif /* ENVIRONMENT_VARS */
  1555. #ifndef MTD_STANDALONE
  1556. if (flWriteProtected(flash->socket))
  1557. return( flWriteProtect );
  1558. #endif /* MTD_STANDALONE */
  1559. if( (dword)((dword)blockNo + (dword)blocksToErase) >
  1560. (dword)((dword)NFDC21thisVars->noOfBlocks * (dword)flash->noOfChips))
  1561. return( flWriteFault ); /* out of media */
  1562. chkASICmode(flash);
  1563. /* handle erase accross floors */
  1564. #ifndef SEPARATED_CASCADED
  1565. floorToUse = (word)(startAddress / NFDC21thisVars->floorSize) + 1;
  1566. if (floorToUse != flash->noOfFloors)
  1567. {
  1568. nextFloorBlockNo = (word)(floorToUse * (NFDC21thisVars->floorSize /
  1569. flash->erasableBlockSize));
  1570. if( blockNo + blocksToErase > nextFloorBlockNo )
  1571. { /* erase on higher floors */
  1572. status = ( doc2Erase( flash, nextFloorBlockNo,
  1573. (word)(blocksToErase - (nextFloorBlockNo - blockNo))) );
  1574. blocksToErase = nextFloorBlockNo - blockNo;
  1575. if(status!=flOK)
  1576. return status;
  1577. }
  1578. }
  1579. #endif /* SEPARATED_CASCADED */
  1580. /* erase on this floor */
  1581. mapWin (flash, &address);
  1582. for (i = 0; i < blocksToErase ; i++, blockNo++ ) {
  1583. dword pageNo = ((dword)blockNo * NFDC21thisVars->pagesPerBlock);
  1584. command(flash, RESET_FLASH);
  1585. writeSignals (flash, FLASH_IO | CE);
  1586. waitForReady(flash);
  1587. command(flash, SETUP_ERASE);
  1588. writeSignals (flash, FLASH_IO | ALE | CE);
  1589. #ifdef SLOW_IO_FLAG
  1590. flWrite8bitReg(flash,NslowIO,(Reg8bitType)pageNo);
  1591. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)pageNo);
  1592. flWrite8bitReg(flash,NslowIO,(Reg8bitType)(pageNo >> 8));
  1593. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(pageNo >> 8));
  1594. if( flash->flags & BIG_ADDR ) {
  1595. flWrite8bitReg(flash,NslowIO,(Reg8bitType)(pageNo >> 16));
  1596. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(pageNo >> 16));
  1597. }
  1598. #else
  1599. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)pageNo);
  1600. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(pageNo >> 8));
  1601. if( flash->flags & BIG_ADDR )
  1602. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)(pageNo >> 16));
  1603. if( NFDC21thisVars->flags & MDOC_ASIC )
  1604. flWrite8bitReg(flash,NwritePipeTerm,(Reg8bitType)0);
  1605. #endif /* SLOW_IO_FLAG */
  1606. writeSignals(flash, FLASH_IO | CE);
  1607. /* if only one block may be erase at a time then do it */
  1608. /* otherwise leave it for later */
  1609. command(flash, CONFIRM_ERASE);
  1610. #ifndef MTD_STANDALONE
  1611. #ifndef DO_NOT_YIELD_CPU
  1612. if(waitForReadyWithYieldCPU(flash,MAX_WAIT)==FALSE)
  1613. #endif /* DO_NOT_YIELD_CPU */
  1614. #endif /* MTD_STANDALONE */
  1615. {
  1616. waitForReady(flash);
  1617. }
  1618. if ( readStatus(flash) & (byte)(FAIL) ) { /* erase operation failed */
  1619. DEBUG_PRINT(("Debug: NFDC 2148 erase failed.\r\n"));
  1620. status = flWriteFault;
  1621. /* reset flash device and abort */
  1622. command(flash, RESET_FLASH);
  1623. waitForReady(flash);
  1624. break;
  1625. }
  1626. else { /* no failure reported */
  1627. #ifdef VERIFY_ERASE
  1628. if ( checkErase( flash, startAddress + i * flash->erasableBlockSize) != flOK ) {
  1629. DEBUG_PRINT(("Debug: NFDC 2148 erase failed in verification.\r\n"));
  1630. return flWriteFault ;
  1631. }
  1632. #endif /* VERIFY_ERASE */
  1633. }
  1634. } /* block loop */
  1635. #ifdef MULTI_ERASE
  1636. /* do multiple block erase as was promised */
  1637. command(flash, CONFIRM_ERASE);
  1638. #ifndef MTD_STANDALONE
  1639. #ifndef DO_NOT_YIELD_CPU
  1640. waitForReadyWithYieldCPU(flash,MAX_WAIT);
  1641. #endif /* DO_NOT_YIELD_CPU */
  1642. #endif /* MTD_STANDALONE */
  1643. if ( readStatus(flash) & (byte)(FAIL) ) { /* erase operation failed */
  1644. DEBUG_PRINT(("Debug: NFDC 2148 erase failed.\r\n"));
  1645. status = flWriteFault;
  1646. /* reset flash device and abort */
  1647. command(flash, RESET_FLASH);
  1648. waitForReady(flash);
  1649. }
  1650. #endif /* MULTI_ERASE */
  1651. writeSignals (flash, FLASH_IO | WP);
  1652. return( status );
  1653. }
  1654. #endif /* FL_READ_ONLY */
  1655. #ifndef MTD_STANDALONE
  1656. /*----------------------------------------------------------------------*/
  1657. /* d o c 2 M a p */
  1658. /* */
  1659. /* Map through buffer. This routine will be registered as the map */
  1660. /* routine for this MTD. */
  1661. /* */
  1662. /* Parameters: */
  1663. /* flash : Pointer identifying drive */
  1664. /* address : Flash address to be mapped. */
  1665. /* length : number of bytes to map. */
  1666. /* */
  1667. /* Returns: */
  1668. /* Pointer to the buffer data was mapped to. */
  1669. /* */
  1670. /*----------------------------------------------------------------------*/
  1671. static void FAR0 *doc2Map ( FLFlash * flash, CardAddress address, int length )
  1672. {
  1673. doc2Read(flash,address,NFDC21thisBuffer,length, 0);
  1674. /* Force remapping of internal catched sector */
  1675. flash->socket->remapped = TRUE;
  1676. return( (void FAR0 *)NFDC21thisBuffer );
  1677. }
  1678. #endif /* MTD_STANDALONE */
  1679. #ifdef MTD_READ_BBT
  1680. /*----------------------------------------------------------------------*/
  1681. /* R e a d B B T */
  1682. /* */
  1683. /* Read the media Bad Blocks Table to a user buffer. */
  1684. /* */
  1685. /* Parameters: */
  1686. /* flash : Pointer identifying drive */
  1687. /* unitNo : indicated which unit number to start checking from. */
  1688. /* unitToRead : indicating how many units to check */
  1689. /* buffer : buffer to read into. */
  1690. /* reconstruct : TRUE for reconstruct BBT from virgin card */
  1691. /* */
  1692. /* Note: blocks is a minimal flash erasable area. */
  1693. /* Note: unit can contain several blocks. */
  1694. /* Note: There is no current implementation of a unit that contains */
  1695. /* more then a single block. */
  1696. /* Note: The format of the BBT is byte per unit 0 for bad any other */
  1697. /* value for good. */
  1698. /* Note: global variables changed at doc2Read: */
  1699. /* global variable NFDC21thisVars->currentFloor is updated */
  1700. /* flash->socket.window.currentPage = pageToMap; */
  1701. /* flash->socket.remapped = TRUE; */
  1702. /* Note: At least 4 bytes must be read */
  1703. /* */
  1704. /* RETURNS: */
  1705. /* flOK on success */
  1706. /* flBadLength if one of the units is out of the units range */
  1707. /* flBadBBT on read fault */
  1708. /*----------------------------------------------------------------------*/
  1709. static FLStatus readBBT(FLFlash * flash, dword unitNo, dword unitsToRead,
  1710. byte blockMultiplier, byte FAR1 * buffer,
  1711. FLBoolean reconstruct)
  1712. {
  1713. CardAddress bbtAddr,floorEndAddr;
  1714. CardAddress addr,floorStartAddr,alignAddr;
  1715. dword unitsPerFloor = NFDC21thisVars->floorSize >> flash->erasableBlockSizeBits;
  1716. word curRead,actualRead;
  1717. CardAddress mediaSize = (CardAddress)flash->chipSize*flash->noOfChips;
  1718. FLStatus status = flOK;
  1719. dword unitOffset;
  1720. dword sizeOfBBT;
  1721. word counter;
  1722. byte FAR1* bufPtr = buffer;
  1723. #if (defined (MTD_RECONSTRUCT_BBT) && !defined(FL_READ_ONLY))
  1724. CardAddress bbtCurAddr;
  1725. dword i;
  1726. byte reconstructBBT = 0;
  1727. #endif /* MTD_RECONSTRUCT_BBT && not FL_READ_ONLY */
  1728. /* Arg sanity check */
  1729. if (((dword)(unitNo+unitsToRead) <<
  1730. (blockMultiplier+flash->erasableBlockSizeBits)) > mediaSize)
  1731. return flBadParameter;
  1732. /* Calculate size of BBT blocks */
  1733. for(sizeOfBBT = flash->erasableBlockSize;
  1734. sizeOfBBT < unitsPerFloor ;sizeOfBBT = sizeOfBBT<<1);
  1735. #ifndef MTD_STANDALONE
  1736. /* Force remapping of internal catched sector */
  1737. flash->socket->remapped = TRUE;
  1738. #endif /* MTD_STANDALONE */
  1739. /* Adjust no' of blocks per floor according to blocks multiplier */
  1740. unitsPerFloor = unitsPerFloor >> blockMultiplier;
  1741. /* Mark all user buffer as good units */
  1742. tffsset(buffer,BBT_GOOD_UNIT,unitsToRead);
  1743. /* Loop over all of the floors */
  1744. for (floorStartAddr = 0 ; (floorStartAddr < mediaSize) && (unitsToRead > 0);
  1745. floorStartAddr += NFDC21thisVars->floorSize)
  1746. {
  1747. floorEndAddr = TFFSMIN(floorStartAddr+NFDC21thisVars->floorSize,mediaSize);
  1748. /* Look for bbt signature in extra area start looking from last unit */
  1749. for(bbtAddr = floorEndAddr - sizeOfBBT,
  1750. counter = BBT_MAX_DISTANCE;
  1751. (bbtAddr > floorStartAddr) && (counter > 0);
  1752. bbtAddr -= flash->erasableBlockSize , counter--)
  1753. {
  1754. status = doc2Read(flash,bbtAddr+8,NFDC21thisBuffer,BBT_SIGN_SIZE,EXTRA);
  1755. if (status != flOK)
  1756. return flBadBBT;
  1757. if(tffscmp(NFDC21thisBuffer,BBT_SIGN,BBT_SIGN_SIZE)==0)
  1758. break;
  1759. }
  1760. /* No BBT was found virgin card */
  1761. if((bbtAddr==floorStartAddr) || (counter == 0))
  1762. {
  1763. #if (defined (MTD_RECONSTRUCT_BBT) && !defined(FL_READ_ONLY))
  1764. if (reconstruct == TRUE)
  1765. {
  1766. reconstructBBT++;
  1767. if (reconstructBBT == 1)
  1768. DFORMAT_PRINT(("\rVirgin card rebuilding unit map.\r\n\n"));
  1769. /* Find good unit for BBT */
  1770. for(bbtAddr = floorEndAddr - sizeOfBBT ;
  1771. bbtAddr > floorStartAddr ;
  1772. bbtAddr -= flash->erasableBlockSize , status = flOK)
  1773. {
  1774. /* Find enough consequtive units for the BBT */
  1775. for(i=0;(status == flOK)&&(i<sizeOfBBT);i+=flash->erasableBlockSize)
  1776. {
  1777. status = checkErase(flash, bbtAddr+i);
  1778. }
  1779. if(status == flOK)
  1780. break;
  1781. }
  1782. if (bbtAddr == floorStartAddr) /* Could not find place for BBT */
  1783. {
  1784. DFORMAT_PRINT(("Debug: no good block found.\r\n"));
  1785. return flBadBBT;
  1786. }
  1787. /* Search and mark the entire floor BBT (512 at a time) */
  1788. bbtCurAddr = bbtAddr;
  1789. for (addr=floorStartAddr;
  1790. addr<floorEndAddr; bbtCurAddr+=SECTOR_SIZE)
  1791. {
  1792. /* Mark all blocks as good */
  1793. tffsset(NFDC21thisBuffer,BBT_GOOD_UNIT,SECTOR_SIZE);
  1794. /* Mark IPL as unused */
  1795. for (i=0;i<SECTOR_SIZE;i++,addr+=flash->erasableBlockSize)
  1796. {
  1797. #ifndef NT5PORT
  1798. DFORMAT_PRINT(("Checking block %u\r",(word)(addr>>flash->erasableBlockSizeBits)));
  1799. #endif// NT5PORT
  1800. /* Bad block table is marked as unavailable */
  1801. if ((addr>=bbtAddr) && (addr<bbtAddr+sizeOfBBT))
  1802. {
  1803. NFDC21thisBuffer[i] = BBT_UNAVAIL_UNIT;
  1804. }
  1805. else /* The unerased blocks are marked as bad */
  1806. {
  1807. if(checkErase(flash, addr) != flOK)
  1808. {
  1809. NFDC21thisBuffer[i] = BBT_BAD_UNIT;
  1810. }
  1811. }
  1812. }
  1813. if(addr == (flash->erasableBlockSize<<SECTOR_SIZE_BITS))
  1814. {
  1815. /* If IPL unit is good mark it as unavailable */
  1816. if(NFDC21thisBuffer[0] != BBT_BAD_UNIT)
  1817. NFDC21thisBuffer[0] = BBT_UNAVAIL_UNIT;
  1818. }
  1819. status = doc2Write(flash,bbtCurAddr,NFDC21thisBuffer,SECTOR_SIZE,EDC);
  1820. if (status != flOK)
  1821. {
  1822. DFORMAT_PRINT(("ERROR - Failed writting bad block table.\r\n"));
  1823. return flBadBBT;
  1824. }
  1825. }
  1826. /* Mark bad blocks table with special mark */
  1827. status = doc2Write(flash,bbtAddr+8,BBT_SIGN, BBT_SIGN_SIZE,EXTRA);
  1828. }
  1829. else
  1830. #endif /* MTD_RECONSTRUCT_BBT && not FL_READ_ONLY */
  1831. {
  1832. return flBadBBT;
  1833. }
  1834. }
  1835. /* Return only blocks that are in this floor */
  1836. addr = floorStartAddr >> (flash->erasableBlockSizeBits + blockMultiplier);
  1837. if ((unitNo >= addr) && (unitNo < addr + unitsPerFloor))
  1838. {
  1839. unitOffset = (unitNo % unitsPerFloor);
  1840. curRead = ((word)TFFSMIN(unitsToRead,unitsPerFloor - unitOffset));
  1841. unitsToRead -= curRead;
  1842. /* Convert to real number of bytes to read and address */
  1843. unitOffset <<= blockMultiplier;
  1844. curRead <<= blockMultiplier;
  1845. alignAddr = ((bbtAddr + unitOffset) >> SECTOR_SIZE_BITS)<<SECTOR_SIZE_BITS;
  1846. do /* Read and copy into buffer 512 blocks at a time */
  1847. {
  1848. if (doc2Read(flash,alignAddr, NFDC21thisBuffer,SECTOR_SIZE,EDC) != flOK)
  1849. return flBadBBT;
  1850. unitOffset = unitOffset % SECTOR_SIZE;
  1851. actualRead = (word)TFFSMIN(SECTOR_SIZE - unitOffset,curRead);
  1852. curRead -= actualRead;
  1853. /* Copy relevant blocks into user buffer */
  1854. for (actualRead += (word)unitOffset ;
  1855. unitOffset < actualRead ;
  1856. bufPtr = BYTE_ADD_FAR(bufPtr,1)) /* increment buffer */
  1857. {
  1858. for (counter = 1 << blockMultiplier ; counter > 0 ;
  1859. counter-- , unitOffset++)
  1860. {
  1861. if (NFDC21thisBuffer[unitOffset] != BBT_GOOD_UNIT)
  1862. {
  1863. *bufPtr = NFDC21thisBuffer[unitOffset];
  1864. }
  1865. }
  1866. }
  1867. alignAddr+=SECTOR_SIZE;
  1868. }while(curRead > 0);
  1869. if (unitsToRead > 0)
  1870. unitNo = addr + unitsPerFloor;
  1871. }
  1872. }
  1873. #if (defined (MTD_RECONSTRUCT_BBT) && !defined(FL_READ_ONLY))
  1874. if (reconstructBBT > 0)
  1875. DFORMAT_PRINT(("\rMedia has been scanned. \r\n"));
  1876. #endif /* MTD_RECONSTRUCT_BBT && not FL_READ_ONLY */
  1877. return flOK;
  1878. }
  1879. #endif /* MTD_READ_BBT */
  1880. /*----------------------------------------------------------------------*/
  1881. /* i s K n o w n M e d i a */
  1882. /* */
  1883. /* Check if this flash media is supported. Initialize relevant fields */
  1884. /* in data structures. */
  1885. /* */
  1886. /* Parameters: */
  1887. /* flash : Pointer identifying drive */
  1888. /* vendorId_P : vendor ID read from chip. */
  1889. /* chipId_p : chip ID read from chip. */
  1890. /* dev : dev chips were accessed before this one. */
  1891. /* */
  1892. /* Returns: */
  1893. /* TRUE if this media is supported, FALSE otherwise. */
  1894. /* */
  1895. /*----------------------------------------------------------------------*/
  1896. static FLBoolean isKnownMedia( FLFlash * flash, Reg8bitType vendorId_p, Reg8bitType chipId_p, int dev )
  1897. {
  1898. if((dev == 0)
  1899. #ifndef SEPARATED_CASCADED
  1900. && (NFDC21thisVars->currentFloor == 0)
  1901. #endif /* SEPARATED_CASCADED */
  1902. ) { /* First Identification */
  1903. NFDC21thisVars->vendorID = (word)vendorId_p; /* remember for next chips */
  1904. NFDC21thisVars->chipID = (word)chipId_p;
  1905. NFDC21thisVars->pagesPerBlock = PAGES_PER_BLOCK;
  1906. flash->maxEraseCycles = 1000000L;
  1907. flash->flags |= BIG_PAGE;
  1908. flash->pageSize = 0x200;
  1909. switch( (byte)vendorId_p ) {
  1910. case 0xEC : /* Samsung */
  1911. switch( (byte)chipId_p ) {
  1912. #ifdef BIG_PAGE_ENABLED
  1913. case 0x64 : /* 2 Mb */
  1914. case 0xEA :
  1915. flash->type = KM29N16000_FLASH;
  1916. flash->pageSize = 0x100;
  1917. flash->chipSize = 0x200000L;
  1918. flash->flags &= ~BIG_PAGE;
  1919. break;
  1920. #endif /* BIG_PAGE_ENABLED */
  1921. case 0xE3 : /* 4 Mb */
  1922. case 0xE5 :
  1923. flash->type = KM29N32000_FLASH;
  1924. flash->chipSize = 0x400000L;
  1925. break;
  1926. case 0xE6 : /* 8 Mb */
  1927. flash->type = KM29V64000_FLASH;
  1928. flash->chipSize = 0x800000L;
  1929. break;
  1930. case 0x73 : /* 16 Mb */
  1931. flash->type = KM29V128000_FLASH;
  1932. flash->chipSize = 0x1000000L;
  1933. NFDC21thisVars->pagesPerBlock *= 2;
  1934. break;
  1935. case 0x75 : /* 32 Mb */
  1936. flash->type = KM29V256000_FLASH;
  1937. flash->chipSize = 0x2000000L;
  1938. NFDC21thisVars->pagesPerBlock *= 2;
  1939. break;
  1940. case 0x76 : /* 64 Mb */
  1941. flash->type = KM29V512000_FLASH;
  1942. flash->chipSize = 0x4000000L;
  1943. flash->flags |= BIG_ADDR;
  1944. NFDC21thisVars->pagesPerBlock *= 2;
  1945. break;
  1946. default : /* Undefined Flash */
  1947. return(FALSE);
  1948. }
  1949. break;
  1950. case 0x98 : /* Toshiba */
  1951. switch( chipId_p ) {
  1952. #ifdef BIG_PAGE_ENABLED
  1953. case 0x64 : /* 2 Mb */
  1954. case 0xEA :
  1955. flash->type = TC5816_FLASH;
  1956. flash->pageSize = 0x100;
  1957. flash->chipSize = 0x200000L;
  1958. flash->flags &= ~BIG_PAGE;
  1959. break;
  1960. #endif /* BIG_PAGE_ENABLED */
  1961. case 0x6B : /* 4 Mb */
  1962. case 0xE5 :
  1963. flash->type = TC5832_FLASH;
  1964. flash->chipSize = 0x400000L;
  1965. break;
  1966. case 0xE6 : /* 8 Mb */
  1967. flash->type = TC5864_FLASH;
  1968. flash->chipSize = 0x800000L;
  1969. break;
  1970. case 0x73 : /* 16 Mb */
  1971. flash->type = TC58128_FLASH;
  1972. flash->chipSize = 0x1000000L;
  1973. NFDC21thisVars->pagesPerBlock *= 2;
  1974. break;
  1975. case 0x75 : /* 32 Mb */
  1976. flash->type = TC58256_FLASH;
  1977. flash->chipSize = 0x2000000L;
  1978. NFDC21thisVars->pagesPerBlock *= 2;
  1979. break;
  1980. case 0x76 : /* 64 Mb */
  1981. flash->type = TC58512_FLASH;
  1982. flash->chipSize = 0x4000000L;
  1983. flash->flags |= BIG_ADDR;
  1984. NFDC21thisVars->pagesPerBlock *= 2;
  1985. break;
  1986. case 0x79: /* 128 Mb */
  1987. flash->type = TC581024_FLASH;
  1988. flash->chipSize = 0x8000000L;
  1989. flash->flags |= BIG_ADDR;
  1990. NFDC21thisVars->pagesPerBlock *= 2;
  1991. break;
  1992. default : /* Undefined Flash */
  1993. return( FALSE );
  1994. }
  1995. flash->flags |= FULL_PAGE; /* no partial page programming */
  1996. break;
  1997. default : /* Undefined Flash */
  1998. return( FALSE );
  1999. }
  2000. return( TRUE );
  2001. }
  2002. else /* dev != 0 */
  2003. if( (vendorId_p == NFDC21thisVars->vendorID) && (chipId_p == NFDC21thisVars->chipID) )
  2004. return( TRUE );
  2005. return( FALSE );
  2006. }
  2007. /*----------------------------------------------------------------------*/
  2008. /* r e a d F l a s h I D */
  2009. /* */
  2010. /* Read vendor and chip IDs, count flash devices. Initialize relevant */
  2011. /* fields in data structures. */
  2012. /* */
  2013. /* Parameters: */
  2014. /* flash : Pointer identifying drive */
  2015. /* dev : dev chips were accessed before this one. */
  2016. /* */
  2017. /* Returns: */
  2018. /* TRUE if this media is supported, FALSE otherwise. */
  2019. /* */
  2020. /*----------------------------------------------------------------------*/
  2021. static int readFlashID ( FLFlash * flash, int dev )
  2022. {
  2023. byte vendorId_p, chipId_p;
  2024. register int i;
  2025. volatile Reg8bitType junk = 0;
  2026. command (flash, READ_ID);
  2027. writeSignals (flash, FLASH_IO | ALE | CE | WP);
  2028. #ifdef SLOW_IO_FLAG
  2029. flWrite8bitReg(flash,NslowIO,(Reg8bitType)0);
  2030. #endif
  2031. flWrite8bitReg(flash,NFDC21thisIO,(Reg8bitType)0);
  2032. if( NFDC21thisVars->flags & MDOC_ASIC )
  2033. flWrite8bitReg(flash,NwritePipeTerm,(Reg8bitType)0);
  2034. writeSignals (flash, FLASH_IO | CE | WP);
  2035. /* read vendor ID */
  2036. flDelayMsecs( 10 ); /* 10 microsec delay */
  2037. for( i = 0;( i < 2 ); i++ ) /* perform 2 reads from NOP reg for delay */
  2038. junk += flRead8bitReg(flash,NNOPreg);
  2039. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  2040. junk += flRead8bitReg(flash,NreadPipeInit); /* load first data into pipeline */
  2041. vendorId_p = flRead8bitReg(flash,NreadLastData); /* finally read vendor ID */
  2042. }
  2043. else {
  2044. junk += flRead8bitReg(flash,NslowIO); /* read CDSN_slow_IO ignoring the data */
  2045. vendorId_p = flRead8bitReg(flash,NFDC21thisIO); /* finally read vendor ID */
  2046. }
  2047. /* read chip ID */
  2048. flDelayMsecs( 10 ); /* 10 microsec delay */
  2049. for( i = 0;( i < 2 ); i++ ) /* perform 2 reads from NOP reg for delay */
  2050. junk += flRead8bitReg(flash,NNOPreg);
  2051. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  2052. junk += flRead8bitReg(flash,NreadPipeInit); /* load first data into pipeline */
  2053. chipId_p = flRead8bitReg(flash,NreadLastData); /* finally read chip ID */
  2054. }
  2055. else {
  2056. junk += flRead8bitReg(flash,NslowIO); /* read CDSN_slow_IO ignoring the data */
  2057. chipId_p = flRead8bitReg(flash,NFDC21thisIO); /* finally read chip ID */
  2058. }
  2059. if ( isKnownMedia(flash, vendorId_p, chipId_p, dev) != TRUE ) /* no chip or diff. */
  2060. return( FALSE ); /* type of flash */
  2061. flash->noOfChips++;
  2062. writeSignals (flash, FLASH_IO);
  2063. /* set flash parameters */
  2064. if((dev == 0)
  2065. #ifndef SEPARATED_CASCADED
  2066. && (NFDC21thisVars->currentFloor == 0)
  2067. #endif /* SEPARATED_CASCADED */
  2068. )
  2069. {
  2070. NFDC21thisVars->pageAreaSize = 0x100;
  2071. #ifdef BIG_PAGE_ENABLED
  2072. if ( !(flash->flags & BIG_PAGE) )
  2073. NFDC21thisVars->tailSize = EXTRA_LEN; /* = 8 */
  2074. else
  2075. #endif /* BIG_PAGE_ENABLED */
  2076. NFDC21thisVars->tailSize = SECTOR_EXTRA_LEN; /* = 16 */
  2077. NFDC21thisVars->pageMask = (word)(flash->pageSize - 1);
  2078. flash->erasableBlockSize = NFDC21thisVars->pagesPerBlock * flash->pageSize;
  2079. NFDC21thisVars->noOfBlocks = (word)( flash->chipSize / flash->erasableBlockSize );
  2080. NFDC21thisVars->if_cfg = 8;
  2081. }
  2082. return( TRUE );
  2083. }
  2084. /*----------------------------------------------------------------------*/
  2085. /* d o c 2 I d e n t i f y */
  2086. /* */
  2087. /* Identify flash. This routine will be registered as the */
  2088. /* identification routine for this MTD. */
  2089. /* */
  2090. /* Parameters: */
  2091. /* flash : Pointer identifying drive */
  2092. /* */
  2093. /* Returns: */
  2094. /* FLStatus : 0 on success, flUnknownMedia failed. */
  2095. /* */
  2096. /*----------------------------------------------------------------------*/
  2097. #ifndef MTD_STANDALONE
  2098. static
  2099. #endif
  2100. FLStatus doc2000Identify(FLFlash * flash)
  2101. {
  2102. dword address = 0L;
  2103. int maxDevs, dev;
  2104. volatile Reg8bitType toggle1;
  2105. volatile Reg8bitType toggle2;
  2106. byte floorCnt = 0;
  2107. byte floor = 0;
  2108. #ifdef NT5PORT
  2109. byte socketNo = (byte)flSocketNoOf(flash->socket);
  2110. #else
  2111. byte socketNo = flSocketNoOf(flash->socket);
  2112. #endif NT5PORT
  2113. DEBUG_PRINT(("Debug: entering NFDC 2148 identification routine.\r\n"));
  2114. flash->mtdVars = &docMtdVars[socketNo];
  2115. #ifndef FL_NO_USE_FUNC
  2116. /* Initialize socket memory access routine */
  2117. if(setBusTypeOfFlash(flash, flBusConfig[socketNo] |
  2118. FL_8BIT_DOC_ACCESS | FL_8BIT_FLASH_ACCESS))
  2119. return flUnknownMedia;
  2120. #endif /* FL_NO_USE_FUNC */
  2121. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT))
  2122. /* Get pointer to read back buffer */
  2123. NFDC21thisVars->readBackBuffer = flReadBackBufferOf(socketNo);
  2124. #endif /* VERIFY_WRITE || VERIFY_ERASE || MTD_RECONSTRUCT_BBT */
  2125. #ifndef MTD_STANDALONE
  2126. /* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
  2127. NFDC21thisVars->buffer = flBufferOf(socketNo);
  2128. flSetWindowBusWidth(flash->socket, 16);/* use 8-bits */
  2129. flSetWindowSpeed(flash->socket, 250); /* 250 nsec. */
  2130. #else
  2131. #ifdef MTD_READ_BBT
  2132. NFDC21thisVars->buffer = &globalMTDBuffer;
  2133. #endif /* MTD_READ_BBT */
  2134. #endif /* MTD_STANDALONE */
  2135. /* assume flash parameters for KM29N16000 */
  2136. NFDC21thisVars->floorSize = 1L;
  2137. #ifdef SEPARATED_CASCADED
  2138. /* NFDC21thisVars->currentFloor = flSocketNoOf(flash->socket);*/
  2139. #else
  2140. flash->noOfFloors = MAX_FLOORS;
  2141. NFDC21thisVars->currentFloor = MAX_FLOORS;
  2142. #endif /* SEPARATED_CASCADED */
  2143. flash->noOfChips = 0;
  2144. flash->chipSize = 0x200000L; /* Assume something ... */
  2145. flash->interleaving = 1; /* unimportant for now */
  2146. /* detect card - identify bit toggles on consequitive reads */
  2147. NFDC21thisWin = (NDOC2window)flMap(flash->socket, 0);
  2148. flash->win = NFDC21thisWin;
  2149. if (NFDC21thisWin == NULL)
  2150. return flUnknownMedia;
  2151. setASICmode (flash, ASIC_RESET_MODE);
  2152. setASICmode (flash, ASIC_NORMAL_MODE);
  2153. switch (flRead8bitReg(flash,NchipId))
  2154. {
  2155. case CHIP_ID_MDOC:
  2156. /* Mdoc and alon asics have the same ID only on
  2157. the forth read distigushes them */
  2158. for(dev=0;dev<3;dev++)
  2159. toggle1 = flRead8bitReg(flash,NchipId);
  2160. if (toggle1 != CHIP_ID_MDOC)
  2161. {
  2162. flash->mediaType = DOC2000TSOP_TYPE;
  2163. }
  2164. else
  2165. {
  2166. flash->mediaType = MDOC_TYPE;
  2167. }
  2168. NFDC21thisVars->flags |= MDOC_ASIC;
  2169. NFDC21thisVars->win_io = NIPLpart2;
  2170. break;
  2171. case CHIP_ID_DOC: /* Doc2000 */
  2172. NFDC21thisVars->flags &= ~MDOC_ASIC;
  2173. NFDC21thisVars->win_io = Nio;
  2174. flash->mediaType = DOC_TYPE;
  2175. break;
  2176. default:
  2177. DEBUG_PRINT(("Debug: failed to identify NFDC 2148.\r\n"));
  2178. return( flUnknownMedia );
  2179. }
  2180. mapWin (flash, &address);
  2181. if( NFDC21thisVars->flags & MDOC_ASIC ) {
  2182. toggle1 = flRead8bitReg(flash,NECCconfig);
  2183. toggle2 = toggle1 ^ flRead8bitReg(flash,NECCconfig);
  2184. }
  2185. else {
  2186. toggle1 = flRead8bitReg(flash,NECCstatus);
  2187. toggle2 = toggle1 ^ flRead8bitReg(flash,NECCstatus);
  2188. }
  2189. if ( (toggle2 & TOGGLE) == 0 ) {
  2190. DEBUG_PRINT(("Debug: failed to identify NFDC 2148.\r\n"));
  2191. return( flUnknownMedia );
  2192. }
  2193. /* reset all flash devices */
  2194. maxDevs = MAX_FLASH_DEVICES_DOC;
  2195. #ifndef SEPARATED_CASCADED
  2196. for ( NFDC21thisVars->currentFloor = 0 ;
  2197. NFDC21thisVars->currentFloor < MAX_FLOORS ;
  2198. NFDC21thisVars->currentFloor++ )
  2199. {
  2200. /* select floor */
  2201. flWrite8bitReg(flash,NASICselect,(Reg8bitType)NFDC21thisVars->currentFloor);
  2202. #endif /* SEPARATED_CASCADED */
  2203. for ( dev = 0 ; dev < maxDevs ; dev++ ) {
  2204. selectChip(flash, (Reg8bitType)dev );
  2205. command(flash, RESET_FLASH);
  2206. }
  2207. #ifndef SEPARATED_CASCADED
  2208. }
  2209. NFDC21thisVars->currentFloor = (byte)0;
  2210. /* back to ground floor */
  2211. flWrite8bitReg(flash,NASICselect,(Reg8bitType)NFDC21thisVars->currentFloor);
  2212. #endif /* SEPARATED_CASCADED */
  2213. writeSignals (flash, FLASH_IO | WP);
  2214. /* identify and count flash chips, figure out flash parameters */
  2215. #ifndef SEPARATED_CASCADED
  2216. for( floor = 0; floor < MAX_FLOORS; floor++ )
  2217. #endif /* SEPARATED_CASCADED */
  2218. for ( dev = 0; dev < maxDevs; dev++ )
  2219. {
  2220. dword addr = address;
  2221. mapWin(flash, &addr);
  2222. if ( readFlashID(flash, dev) == TRUE ) /* identified OK */
  2223. {
  2224. floorCnt = (byte)(floor + 1);
  2225. #ifndef SEPARATED_CASCADED
  2226. if (floor == 0)
  2227. #endif /* SEPARATED_CASCADED */
  2228. NFDC21thisVars->floorSize += flash->chipSize * flash->interleaving;
  2229. address += flash->chipSize * flash->interleaving;
  2230. }
  2231. else
  2232. {
  2233. #ifndef SEPARATED_CASCADED
  2234. if (floor != 0)
  2235. {
  2236. dev = maxDevs;
  2237. floor = MAX_FLOORS;
  2238. }
  2239. else
  2240. #endif /* SEPARATED_CASCADED */
  2241. {
  2242. maxDevs = dev;
  2243. NFDC21thisVars->floorSize = maxDevs * flash->chipSize * flash->interleaving;
  2244. }
  2245. }
  2246. }
  2247. #ifndef SEPARATED_CASCADED
  2248. NFDC21thisVars->currentFloor = (byte)0;
  2249. #endif /* SEPARATED_CASCADED */
  2250. flWrite8bitReg(flash,NASICselect,(Reg8bitType)NFDC21thisVars->currentFloor); /* back to ground floor */
  2251. if (flash->noOfChips == 0) {
  2252. DEBUG_PRINT(("Debug: failed to identify NFDC 2148.\r\n"));
  2253. return( flUnknownMedia );
  2254. }
  2255. address = 0L;
  2256. mapWin (flash, &address);
  2257. flash->noOfFloors = floorCnt;
  2258. eccOFF(flash);
  2259. /* Register our flash handlers */
  2260. #ifndef FL_READ_ONLY
  2261. flash->write = doc2Write;
  2262. flash->erase = doc2Erase;
  2263. #else
  2264. flash->erase = NULL;
  2265. flash->write = NULL;
  2266. #endif
  2267. flash->read = doc2Read;
  2268. #ifndef MTD_STANDALONE
  2269. flash->map = doc2Map;
  2270. #else
  2271. flash->map = NULL;
  2272. #endif /* MTD_STANDALONE */
  2273. /* doc2000 tsop uses INFTL instead of NFTL , does not use
  2274. * the last block and has a readBBT routine
  2275. */
  2276. if (flash->mediaType == DOC2000TSOP_TYPE)
  2277. {
  2278. #ifdef MTD_READ_BBT
  2279. flash->readBBT = readBBT;
  2280. #endif /* MTD_READ_BBT */
  2281. #ifndef NO_IPL_CODE
  2282. flash->download = forceDownLoad;
  2283. #ifndef FL_READ_ONLY
  2284. flash->writeIPL = writeIPL;
  2285. #endif /* FL_READ_ONLY */
  2286. #endif /* NO_IPL_CODE */
  2287. flash->flags |= INFTL_ENABLED;
  2288. }
  2289. else
  2290. {
  2291. flash->flags |= NFTL_ENABLED;
  2292. }
  2293. #ifndef SEPARATED_CASCADED
  2294. if (flash->mediaType == MDOC_TYPE)
  2295. flash->flags |= EXTERNAL_EPROM; /* Supports external eprom */
  2296. #endif /* SEPARATED_CASCADED */
  2297. DEBUG_PRINT(("Debug: identified NFDC 2148.\r\n"));
  2298. return( flOK );
  2299. }
  2300. #ifndef MTD_STANDALONE
  2301. /*----------------------------------------------------------------------*/
  2302. /* f l R e g i s t e r D O C S O C */
  2303. /* */
  2304. /* Installs routines for DiskOnChip 2000 family. */
  2305. /* */
  2306. /* Parameters: */
  2307. /* lowAddress, */
  2308. /* highAddress : host memory range to search for DiskOnChip */
  2309. /* 2000 memory window */
  2310. /* */
  2311. /* Returns: */
  2312. /* FLStatus : 0 on success, otherwise failure */
  2313. /*----------------------------------------------------------------------*/
  2314. #ifndef NT5PORT
  2315. FLStatus flRegisterDOCSOC(dword lowAddress, dword highAddress)
  2316. {
  2317. int serialNo;
  2318. if( noOfSockets >= SOCKETS )
  2319. return flTooManyComponents;
  2320. for(serialNo=0;( noOfSockets < SOCKETS );serialNo++,noOfSockets++)
  2321. {
  2322. FLSocket * socket = flSocketOf(noOfSockets);
  2323. socket->volNo = noOfSockets;
  2324. docSocketInit(socket);
  2325. /* call DiskOnChip MTD's routine to search for memory window */
  2326. flSetWindowSize(socket, 2); /* 4 KBytes */
  2327. socket->window.baseAddress = flDocWindowBaseAddress
  2328. ((byte)socket->volNo, lowAddress, highAddress, &lowAddress);
  2329. if (socket->window.baseAddress == 0) /* DiskOnChip not detected */
  2330. break;
  2331. }
  2332. if( serialNo == 0 )
  2333. return flAdapterNotFound;
  2334. return flOK;
  2335. }
  2336. #endif /*NT5PORT*/
  2337. #else /* MTD_STANDALONE */
  2338. /*----------------------------------------------------------------------*/
  2339. /* d o c 2 0 0 0 S e a r c h F o r W i n d o w */
  2340. /* */
  2341. /* Search for the DiskOnChip ASIC in a given memory range and */
  2342. /* initialize the given socket record. */
  2343. /* */
  2344. /* Parameters: */
  2345. /* socket : Record used to store the sockets parameters */
  2346. /* lowAddress : host memory range to search for DiskOnChip 2000 */
  2347. /* highAddress : memory window */
  2348. /* */
  2349. /* Output: initialize the following fields in the FLFlash record: */
  2350. /* */
  2351. /* base - Pointer to DiskOnChip window */
  2352. /* size - DiskOnChip window size usualy 8K */
  2353. /* */
  2354. /* Returns: */
  2355. /* FLStatus : 0 on success, flDriveNotAvailable on failure. */
  2356. /* */
  2357. /* NOTE: This routine is not used by OSAK. It is used by standalone */
  2358. /* applications using the MTD (BDK for example) as a replacement */
  2359. /* for the OSAK DOCSOC.C file. */
  2360. /* The FLSocket record used by this function is not the one used */
  2361. /* by OSAK defined in flsocket.h but a replacement record defined */
  2362. /* in flflash.h. */
  2363. /* */
  2364. /*----------------------------------------------------------------------*/
  2365. FLStatus doc2000SearchForWindow(FLSocket * socket,
  2366. dword lowAddress,
  2367. dword highAddress)
  2368. {
  2369. dword baseAddress; /* Physical base as a 4K page */
  2370. socket->size = 2 * 0x1000L; /* 4 KBytes */
  2371. baseAddress = (dword) flDocWindowBaseAddress(0, lowAddress, highAddress, &lowAddress);
  2372. socket->base = physicalToPointer(baseAddress << 12, socket->size,0);
  2373. if (baseAddress) /* DiskOnChip detected */
  2374. return flOK;
  2375. else /* DiskOnChip not detected */
  2376. return flDriveNotAvailable;
  2377. }
  2378. /*----------------------------------------------------------------------*/
  2379. /* d o c 2 0 0 0 F r e e W i n d o w */
  2380. /* */
  2381. /* Free any resources used for the DiskOnChip window */
  2382. /* */
  2383. /* Parameters: */
  2384. /* socket : Record used to store the sockets parameters */
  2385. /* */
  2386. /* Returns: None */
  2387. /* */
  2388. /* NOTE: This routine is used only by virtual memory systems in order */
  2389. /* to unmap the DiskOnChip window. */
  2390. /* */
  2391. /*----------------------------------------------------------------------*/
  2392. void doc2000FreeWindow(FLSocket * socket)
  2393. {
  2394. freePointer(socket->base,DOC_WIN);
  2395. }
  2396. #endif /* MTD_STANDALONE */
  2397. /*----------------------------------------------------------------------*/
  2398. /* f l R e g i s t e r D O C 2 0 0 0 */
  2399. /* */
  2400. /* Registers this MTD for use */
  2401. /* */
  2402. /* Parameters: */
  2403. /* None */
  2404. /* */
  2405. /* Returns: */
  2406. /* FLStatus : 0 on success, otherwise failure */
  2407. /*----------------------------------------------------------------------*/
  2408. FLStatus flRegisterDOC2000(void)
  2409. {
  2410. if (noOfMTDs >= MTDS)
  2411. return( flTooManyComponents );
  2412. #ifdef MTD_STANDALONE
  2413. socketTable[noOfMTDs] = doc2000SearchForWindow;
  2414. freeTable[noOfMTDs] = doc2000FreeWindow;
  2415. #endif /* MTD_STANDALONE */
  2416. mtdTable[noOfMTDs++] = doc2000Identify;
  2417. return( flOK );
  2418. }