Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1570 lines
62 KiB

  1. /*
  2. * $Log: P:/user/amir/lite/vcs/nfdc2048.c_v $
  3. *
  4. * Rev 1.28 19 Oct 1997 15:41:54 danig
  5. * Changed tffscpy16 and tffsset16 for far pointers &
  6. * cast to FAR0 in mapContInterface
  7. *
  8. * Rev 1.27 06 Oct 1997 18:37:34 ANDRY
  9. * no COBUX
  10. *
  11. * Rev 1.26 06 Oct 1997 18:04:34 ANDRY
  12. * 16-bit access only for interleave 2 cards, COBUX
  13. *
  14. * Rev 1.25 05 Oct 1997 12:02:32 danig
  15. * Support chip ID 0xEA
  16. *
  17. * Rev 1.24 10 Sep 1997 16:14:08 danig
  18. * Got rid of generic names
  19. *
  20. * Rev 1.23 08 Sep 1997 17:47:00 danig
  21. * fixed setAddress for big-endian
  22. *
  23. * Rev 1.22 04 Sep 1997 13:59:44 danig
  24. * Debug messages
  25. *
  26. * Rev 1.21 31 Aug 1997 15:18:04 danig
  27. * Registration routine return status
  28. *
  29. * Rev 1.20 28 Aug 1997 17:47:08 danig
  30. * Buffer\remapped per socket
  31. *
  32. * Rev 1.19 28 Jul 1997 15:10:36 danig
  33. * setPowerOnCallback & moved standard typedefs to flbase.h
  34. *
  35. * Rev 1.18 24 Jul 1997 18:04:12 amirban
  36. * FAR to FAR0
  37. *
  38. * Rev 1.17 21 Jul 1997 18:56:00 danig
  39. * nandBuffer static
  40. *
  41. * Rev 1.16 20 Jul 1997 18:21:14 danig
  42. * Moved vendorID and chipID to Vars
  43. *
  44. * Rev 1.15 20 Jul 1997 17:15:06 amirban
  45. * Added Toshiba 8MB
  46. *
  47. * Rev 1.14 07 Jul 1997 15:22:26 amirban
  48. * Ver 2.0
  49. *
  50. * Rev 1.13 02 Jul 1997 14:59:22 danig
  51. * More wait for socket to power up
  52. *
  53. * Rev 1.12 01 Jul 1997 13:39:54 danig
  54. * Wait for socket to power up
  55. *
  56. * Rev 1.11 22 Jun 1997 18:34:32 danig
  57. * Documentation
  58. *
  59. * Rev 1.10 12 Jun 1997 17:22:24 amirban
  60. * Allow LONG extra read/writes
  61. *
  62. * Rev 1.9 08 Jun 1997 19:18:06 danig
  63. * BIG_PAGE & FULL_PAGE moved to flash.h
  64. *
  65. * Rev 1.8 08 Jun 1997 17:03:40 amirban
  66. * Fast Toshiba and power on callback
  67. *
  68. * Rev 1.7 05 Jun 1997 12:31:38 amirban
  69. * Write corrections, and att reg changes
  70. *
  71. * Rev 1.6 03 Jun 1997 18:45:14 danig
  72. * powerUp()
  73. *
  74. * Rev 1.5 01 Jun 1997 13:42:52 amirban
  75. * Rewrite of read/write extra + major reduction
  76. *
  77. * Rev 1.4 25 May 1997 16:41:38 amirban
  78. * Bg-endian, Toshiba fix & simplifications
  79. *
  80. * Rev 1.3 18 May 1997 17:34:50 amirban
  81. * Use 'dataError'
  82. *
  83. * Rev 1.2 23 Apr 1997 11:02:14 danig
  84. * Update to TFFS revision 1.12
  85. *
  86. * Rev 1.1 15 Apr 1997 18:48:02 danig
  87. * Fixed FAR pointer issues.
  88. *
  89. * Rev 1.0 08 Apr 1997 18:29:28 danig
  90. * Initial revision.
  91. */
  92. /************************************************************************/
  93. /* */
  94. /* FAT-FTL Lite Software Development Kit */
  95. /* Copyright (C) M-Systems Ltd. 1995-1997 */
  96. /* */
  97. /************************************************************************/
  98. #include "ntddk.h"
  99. #include "flflash.h"
  100. #include "reedsol.h"
  101. #define NFDC2048 /* Support NFDC2048 ASIC controller */
  102. #define MAX_FLASH_DEVICES 16
  103. #define PAGES_PER_BLOCK 16 /* 16 pages per block on a single chip*/
  104. #define SYNDROM_BYTES 6 /* Number of syndrom bytes: 5 + 1 parity*/
  105. /* Flash IDs*/
  106. #define KM29N16000_FLASH 0xec64
  107. #define KM29N32000_FLASH 0xece5
  108. #define KM29V64000_FLASH 0xece6
  109. #define KM29V128000_FLASH 0xec73
  110. #define KM29V256000_FLASH 0xec75
  111. #define NM29N16_FLASH 0x8f64
  112. #define NM29N32_FLASH 0x8fe5
  113. #define NM29N64_FLASH 0x8fe6
  114. #define TC5816_FLASH 0x9864
  115. #define TC5832_FLASH 0x98e5
  116. #define TC5864_FLASH 0x98e6
  117. #define TC58128_FLASH 0x9873
  118. #define TC58256_FLASH 0x9875
  119. /* Flash commands:*/
  120. #define SERIAL_DATA_INPUT 0x80
  121. #define READ_MODE 0x00
  122. #define READ_MODE_2 0x50
  123. #define RESET_FLASH 0xff
  124. #define SETUP_WRITE 0x10
  125. #define SETUP_ERASE 0x60
  126. #define CONFIRM_ERASE 0xd0
  127. #define READ_STATUS 0x70
  128. #define READ_ID 0x90
  129. #define SUSPEND_ERASE 0xb0
  130. #define REGISTER_READ 0xe0
  131. /* commands for moving flash pointer to areeas A,B or C of page*/
  132. typedef enum { AREA_A = READ_MODE, AREA_B = 0x1, AREA_C = READ_MODE_2 } PointerOp;
  133. typedef union { USHORT w ; UCHAR b ; } WordByte;
  134. /*�������������������������������������������Ŀ
  135. Memory window to cards common memory
  136. */
  137. typedef struct
  138. {
  139. volatile WordByte signals; /* CDSN control register*/
  140. #define CE 0x01
  141. #define CLE 0x02
  142. #define ALE 0x04
  143. #define NOT_WP 0x08
  144. #define RB 0x80
  145. #define FAIL 0x01
  146. #define SUSPENDED 0x20
  147. #define READY 0x40
  148. #define NOT_PROTECTED 0x80
  149. UCHAR fillerA[1024 - sizeof(WordByte)];
  150. volatile LEushort deviceSelector;
  151. volatile WordByte eccConfig; /* EDC configuration register*/
  152. #define TOGGLE 0x04 /* Read*/
  153. #ifdef NFDC2048
  154. #define ECC_RST 0x04 /* Write*/
  155. #define ECC_EN 0x08 /* Read / Write*/
  156. #define PAR_DIS 0x10 /* Read / Write*/
  157. #define ECC_RW 0x20 /* Read / Write*/
  158. #define ECC_RDY 0x40 /* Read */
  159. #define ECC_ERROR 0x80 /* Read*/
  160. volatile USHORT syndrom[3];
  161. UCHAR fillerC[1024-10]; /* 1kbytes minus 10 bytes*/
  162. #else
  163. UCHAR fillerC[1024-4]; /* 1kbytes minus 3 words */
  164. #endif /* NFDC2048 */
  165. volatile WordByte io[1024];
  166. } ContComWin;
  167. /* #defines for writing to ContComWin.eccConfig */ /* HOOK - added */
  168. #define SET_ECC_CONFIG(win,val) tffsWriteByteFlash(&((win)->eccConfig.b), (UCHAR)(val))
  169. #define CHK_ECC_ERROR(win) (tffsReadByteFlash(&((win)->eccConfig.b)) & (UCHAR)ECC_ERROR)
  170. typedef ContComWin FAR0 * Interface;
  171. #define DBL(x) ( (UCHAR)(x) * 0x101u )
  172. #define SECOND_TRY 0x8000
  173. #ifdef NFDC2048
  174. /* Controller registers: Addresses & values */
  175. #define ATTRIBUTE_MEM_START 0x8000000L /* Attribute memory starts at 128MB */
  176. /* Controller configuration register */
  177. #define CONFIG1 ATTRIBUTE_MEM_START + 0x3ffc
  178. #define PWR_DN 0x01 /* Read / Write*/
  179. #define PWR_DN2 0x02 /* Read / Write*/
  180. #define STOP_CDSN 0x04 /* Read / Write*/
  181. #define STOP_CDSNS 0x08 /* Read / Write*/
  182. #define C_CDSN 0x10 /* Read / Write*/
  183. #define R_CDSN 0x20 /* Read / Write*/
  184. #define WP_C 0x40 /* Read / Write*/
  185. #define WP_A 0x80 /* Read / Write*/
  186. /* board's jumper settings*/
  187. #define JUMPERS ATTRIBUTE_MEM_START + 0x3ffe
  188. #define JMPER_INLV 0x08
  189. #define JMPER_CDSNS 0x10
  190. #define JMPER_EXT_CIS 0x20
  191. #define JMPER_LDR_MASK 0x40
  192. #define JMPER_MAX_MODE 0x80
  193. /* PCMCIA register #0*/
  194. #define CONFIG_OPTION ATTRIBUTE_MEM_START + 0x4000
  195. #define CONFIGIDX 0x3F /* Read / Write*/
  196. #define SREST 0x80 /* Read / Write*/
  197. /* PCMCIA register #1*/
  198. #define CARD_CONFIG ATTRIBUTE_MEM_START + 0x4002
  199. #define PWRDWN 0x04 /* Read / Write*/
  200. #else
  201. #define INLV 2 /* Must define interleaving statically */
  202. #endif /* NFDC2048 */
  203. /* customization for this MTD*/
  204. /*#define MULTI_ERASE */ /* use multiple block erase feature*/
  205. #define USE_EDC /* use Error Detection /Correction Code */
  206. /* #define VERIFY_AFTER_WRITE */
  207. typedef struct {
  208. USHORT vendorID;
  209. USHORT chipID;
  210. USHORT pageSize ; /* all....................*/
  211. USHORT pageMask ; /* ...these...............*/
  212. USHORT pageAreaSize ; /* .......variables.......*/
  213. USHORT tailSize ; /* .............interleave*/
  214. USHORT noOfBlocks ; /* total erasable blocks in flash device*/
  215. USHORT pagesPerBlock; /* number of pages per block */
  216. FLBuffer *buffer; /* buffer for map through buffer */
  217. } Vars;
  218. Vars mtdVars_nfdc2048[SOCKETS];
  219. #define thisVars ((Vars *) vol.mtdVars)
  220. #define thisBuffer (thisVars->buffer->flData)
  221. /*���������������������Ŀ
  222. Auxiliary methods
  223. */
  224. /*----------------------------------------------------------------------*/
  225. /* t f f s c p y 1 6 */
  226. /* */
  227. /* Move data in 16-bit words. */
  228. /* */
  229. /* Parameters: */
  230. /* dst : destination buffer */
  231. /* src : source buffer */
  232. /* len : bytes to move */
  233. /* */
  234. /*----------------------------------------------------------------------*/
  235. VOID tffscpy16fromMedia (UCHAR FAR0 *dst,
  236. const UCHAR FAR0 *src,
  237. LONG len)
  238. {
  239. register LONG i;
  240. USHORT FAR0 *dstPtr = (USHORT FAR0 *) dst;
  241. const USHORT FAR0 *srcPtr = (USHORT FAR0 *) src;
  242. /* move data in 16-bit words */
  243. for (i = len; i > 0; i -= 2)
  244. *dstPtr++ = tffsReadWordFlash(srcPtr++);
  245. }
  246. VOID tffscpy16toMedia (UCHAR FAR0 *dst,
  247. const UCHAR FAR0 *src,
  248. LONG len)
  249. {
  250. register LONG i;
  251. USHORT FAR0 *dstPtr = (USHORT FAR0 *) dst;
  252. const USHORT FAR0 *srcPtr = (USHORT FAR0 *) src;
  253. /* move data in 16-bit words */
  254. for (i = len; i > 0; i -= 2)
  255. tffsWriteWordFlash(dstPtr++,*srcPtr++);
  256. }
  257. /*----------------------------------------------------------------------*/
  258. /* t f f s s e t 1 6 */
  259. /* */
  260. /* Set data buffer in 16-bit words. */
  261. /* */
  262. /* Parameters: */
  263. /* dst : destination buffer */
  264. /* val : byte value tofill the buffer */
  265. /* len : setination buffer size in bytes */
  266. /* */
  267. /*----------------------------------------------------------------------*/
  268. VOID tffsset16 (UCHAR FAR0 *dst,
  269. UCHAR val,
  270. LONG len)
  271. {
  272. register USHORT wval = ((USHORT)val << 8) | val;
  273. register LONG i = 0;
  274. USHORT FAR0 *dstPtr;
  275. /* set data in 16-bit words */
  276. for (i = 0; i < len - 1; i += 2) {
  277. dstPtr = (USHORT FAR0 *)addToFarPointer(dst, i);
  278. tffsWriteWordFlash(dstPtr,wval);
  279. }
  280. /* set last byte (if any) */
  281. if (len & 1) {
  282. dstPtr = (USHORT FAR0 *)addToFarPointer(dst, len - 1);
  283. tffsWriteByteFlash(dstPtr,wval);
  284. }
  285. }
  286. #ifdef NFDC2048
  287. /*----------------------------------------------------------------------*/
  288. /* r e a d S y n d r o m */
  289. /* */
  290. /* Read ECC syndrom and swap words to prepare it for writing to flash. */
  291. /* */
  292. /* Parameters: */
  293. /* Interface : Pointer to window. */
  294. /* to : buffer to read to. */
  295. /* */
  296. /*----------------------------------------------------------------------*/
  297. VOID readSyndrom_nfdc2048( Interface interface, USHORT *to )
  298. {
  299. to[0] = tffsReadWordFlash(&(interface->syndrom[2]));
  300. to[1] = tffsReadWordFlash(&(interface->syndrom[1]));
  301. to[2] = tffsReadWordFlash(&(interface->syndrom[0]));
  302. }
  303. #ifdef USE_EDC
  304. /*----------------------------------------------------------------------*/
  305. /* r e a d S y n d r o m O n S y n d r o m */
  306. /* */
  307. /* Read ECC syndrom. */
  308. /* */
  309. /* Parameters: */
  310. /* Interface : Pointer to window. */
  311. /* to : buffer to read to. */
  312. /* */
  313. /*----------------------------------------------------------------------*/
  314. VOID readSyndromOnSyndrom ( Interface interface, USHORT *to )
  315. {
  316. to[0] = tffsReadWordFlash(&(interface->syndrom[0]));
  317. to[1] = tffsReadWordFlash(&(interface->syndrom[1]));
  318. to[2] = tffsReadWordFlash(&(interface->syndrom[2]));
  319. }
  320. #endif /* USE_EDC */
  321. /*���������������������������Ŀ
  322. Miscellaneous routines
  323. */
  324. /*----------------------------------------------------------------------*/
  325. /* g e t A t t R e g */
  326. /* */
  327. /* Get ASIC register residing in card's Attribute memory. */
  328. /* */
  329. /* Parameters: */
  330. /* vol : Pointer identifying drive */
  331. /* address : Address of register. */
  332. /* */
  333. /* Returns: */
  334. /* Value of register. */
  335. /* */
  336. /*----------------------------------------------------------------------*/
  337. UCHAR getAttReg(FLFlash vol, CardAddress reg)
  338. {
  339. return (UCHAR) (tffsReadByteFlash((USHORT FAR0 *) flMap(vol.socket,reg)));
  340. }
  341. /*----------------------------------------------------------------------*/
  342. /* s e t A t t R e g */
  343. /* */
  344. /* Set ASIC register residing in card's Attribute memory. */
  345. /* */
  346. /* Parameters: */
  347. /* vol : Pointer identifying drive */
  348. /* address : Address of register. */
  349. /* value : Value to set */
  350. /* */
  351. /*----------------------------------------------------------------------*/
  352. VOID setAttReg(FLFlash vol, CardAddress reg, UCHAR value)
  353. {
  354. tffsWriteWordFlash((USHORT FAR0 *) flMap(vol.socket,reg), DBL(value));
  355. }
  356. /*----------------------------------------------------------------------*/
  357. /* p o w e r U p */
  358. /* */
  359. /* Power up the controller. */
  360. /* */
  361. /* Parameters: */
  362. /* vol : Pointer identifying drive */
  363. /* */
  364. /*----------------------------------------------------------------------*/
  365. VOID powerUp(VOID *pVol)
  366. {
  367. flDelayMsecs(1);
  368. setAttReg ((FLFlash *) pVol, CONFIG1, WP_C); /* Power up the controller */
  369. }
  370. #endif /* NFDC2048 */
  371. /*----------------------------------------------------------------------*/
  372. /* m a p C o n t I n t e r f a c e */
  373. /* */
  374. /* Select flash device. */
  375. /* */
  376. /* Parameters: */
  377. /* vol : Pointer identifying drive */
  378. /* address : Address in flash. */
  379. /* */
  380. /* Returns: */
  381. /* Pointer to the mapped window. */
  382. /* */
  383. /*----------------------------------------------------------------------*/
  384. Interface mapContInterface(FLFlash vol, CardAddress address)
  385. {
  386. Interface interface = (Interface) flMap(vol.socket,(CardAddress)0);
  387. LEushort tmp;
  388. toLE2(*((LEushort FAR0 *) &tmp), (USHORT)(address / (vol.chipSize * vol.interleaving)));
  389. /* Select flash device with 16-bit write */
  390. tffsWriteWordFlash(((USHORT FAR0 *) &interface->deviceSelector), *((USHORT *) &tmp));
  391. return interface;
  392. }
  393. /*----------------------------------------------------------------------*/
  394. /* w a i t F o r R e a d y */
  395. /* */
  396. /* Wait for the selected device to be ready. */
  397. /* */
  398. /* Parameters: */
  399. /* Interface : Pointer tot the window. */
  400. /* */
  401. /* Returns: */
  402. /* TRUE if device is ready, FALSE if timeout error. */
  403. /* */
  404. /*----------------------------------------------------------------------*/
  405. FLBoolean waitForReady_nfdc2048 (Interface interface)
  406. {
  407. LONG i;
  408. for( i = 0; i < 20000; i++)
  409. {
  410. if( (~(tffsReadWordFlash(&(interface->signals.w))) & DBL(RB)) == 0)
  411. return TRUE ; /* ready at last..*/
  412. flDelayMsecs(1);
  413. }
  414. DEBUG_PRINT(("Debug: timeout error in NFDC 2048.\n"));
  415. return FALSE; /* timeout error */
  416. }
  417. /*----------------------------------------------------------------------*/
  418. /* m a k e C o m m a n d */
  419. /* */
  420. /* Set Page Pointer to Area A, B or C in page. */
  421. /* */
  422. /* Parameters: */
  423. /* vol : Pointer identifying drive */
  424. /* cmd : receives command relevant to area */
  425. /* addr : receives the address to the right area. */
  426. /* modes : mode of operation (EXTRA ...) */
  427. /* */
  428. /*----------------------------------------------------------------------*/
  429. VOID makeCommand_nfdc2048 (FLFlash vol, PointerOp *cmd, CardAddress *addr , LONG modes )
  430. {
  431. USHORT offset;
  432. if ( !(vol.flags & BIG_PAGE) ) {
  433. if (modes & EXTRA) {
  434. offset = (USHORT) (*addr & (SECTOR_SIZE - 1));
  435. *cmd = AREA_C;
  436. if (vol.interleaving == 1) {
  437. if (offset < 8) /* First half of extra area */
  438. *addr += 0x100; /* ... assigned to 2nd page */
  439. else /* Second half of extra area */
  440. *addr -= 8; /* ... assigned to 1st page */
  441. }
  442. }
  443. else
  444. *cmd = AREA_A;
  445. }
  446. else {
  447. offset = (USHORT)(*addr) & thisVars->pageMask ; /* offset within device Page */
  448. *addr -= offset; /* align at device Page*/
  449. if (vol.interleaving == 2 && offset >= 512)
  450. offset += 16; /* leave room for 1st extra area */
  451. if (modes & EXTRA)
  452. offset += SECTOR_SIZE;
  453. if ( offset < thisVars->pageAreaSize ) /* starting in area A*/
  454. *cmd = AREA_A ;
  455. else if ( offset < thisVars->pageSize ) /* starting in area B */
  456. *cmd = AREA_B ;
  457. else /* got into area C*/
  458. *cmd = AREA_C ;
  459. offset &= (thisVars->pageAreaSize - 1) ; /* offset within area of device Page*/
  460. *addr += offset ;
  461. }
  462. }
  463. /*----------------------------------------------------------------------*/
  464. /* c o m m a n d */
  465. /* */
  466. /* Latch command byte to selected flash device. */
  467. /* */
  468. /* Parameters: */
  469. /* vol : Pointer identifying drive */
  470. /* Interface : Pointer to window. */
  471. /* code : Command to set. */
  472. /* */
  473. /*----------------------------------------------------------------------*/
  474. VOID command2048(FLFlash vol, Interface interface, UCHAR code)
  475. {
  476. tffsWriteWordFlash(&(interface->signals.w), DBL( CLE | NOT_WP | CE ));
  477. if ( vol.interleaving == 1 ) { /* 8-bit */
  478. tffsWriteByteFlash(&(interface->io[0].b), code);
  479. } else { /* 16-bit */
  480. tffsWriteWordFlash(&(interface->io[0].w), DBL( code ));
  481. }
  482. tffsWriteWordFlash(&(interface->signals.w), DBL( NOT_WP ));
  483. }
  484. /*----------------------------------------------------------------------*/
  485. /* s e t A d d r e s s */
  486. /* */
  487. /* Latch address to selected flash device. */
  488. /* */
  489. /* Parameters: */
  490. /* vol : Pointer identifying drive */
  491. /* Interface : Pointer to window. */
  492. /* address : address to set. */
  493. /* */
  494. /*----------------------------------------------------------------------*/
  495. VOID setAddress2048(FLFlash vol, Interface interface, CardAddress address )
  496. {
  497. address &= (vol.chipSize * vol.interleaving - 1) ; /* address within flash device*/
  498. address /= vol.interleaving ; /* .................... chip */
  499. if ( vol.flags & BIG_PAGE )
  500. {
  501. /*
  502. bits 0..7 stays as are
  503. bit 8 is thrown away from address
  504. bits 31..9 -> bits 30..8
  505. */
  506. address = ((address >> 9) << 8) | ((UCHAR)address) ;
  507. }
  508. tffsWriteWordFlash(&(interface->signals.w), DBL(ALE | NOT_WP | CE));
  509. /* send address to flash in the following sequence: */
  510. /* bits 7...0 first */
  511. /* bits 15...8 next */
  512. /* bits 23..16 finally */
  513. if ( vol.interleaving == 1 )
  514. {
  515. tffsWriteByteFlash(&(interface->io[0].b), (UCHAR)address );
  516. tffsWriteByteFlash(&(interface->io[0].b), (UCHAR)(address >> 8));
  517. tffsWriteByteFlash(&(interface->io[0].b), (UCHAR)(address >> 16));
  518. }
  519. else
  520. {
  521. tffsWriteWordFlash(&(interface->io[0].w), (USHORT)DBL(address));
  522. tffsWriteWordFlash(&(interface->io[0].w), (USHORT)DBL(address >> 8));
  523. tffsWriteWordFlash(&(interface->io[0].w), (USHORT)DBL(address >> 16));
  524. }
  525. tffsWriteWordFlash(&(interface->signals.w), DBL( NOT_WP | CE));
  526. }
  527. /*----------------------------------------------------------------------*/
  528. /* r e a d C o m m a n d */
  529. /* */
  530. /* Issue read command. */
  531. /* */
  532. /* Parametes: */
  533. /* vol : Pointer identifying drive */
  534. /* Interface : Pointer to window. */
  535. /* cmd : Command to issue (according to area). */
  536. /* addr : address to read from. */
  537. /* */
  538. /*----------------------------------------------------------------------*/
  539. VOID readCommand2048 (FLFlash vol, Interface interface, PointerOp cmd, CardAddress addr)
  540. {
  541. command2048 (&vol, interface, (UCHAR) cmd) ; /* move flash pointer to respective area of the page*/
  542. setAddress2048 (&vol, interface, addr) ;
  543. waitForReady_nfdc2048(interface) ;
  544. }
  545. /*----------------------------------------------------------------------*/
  546. /* w r i t e C o m m a n d */
  547. /* */
  548. /* Issue write command. */
  549. /* */
  550. /* Parametes: */
  551. /* vol : Pointer identifying drive */
  552. /* interface : Pointer to window. */
  553. /* cmd : Command to issue (according to area). */
  554. /* addr : address to write to. */
  555. /* */
  556. /*----------------------------------------------------------------------*/
  557. VOID writeCommand2048 (FLFlash vol, Interface interface, PointerOp cmd, CardAddress addr)
  558. {
  559. if (vol.flags & FULL_PAGE) {
  560. command2048 (&vol, interface, RESET_FLASH); /* Clear page buffer */
  561. waitForReady_nfdc2048(interface);
  562. }
  563. command2048 (&vol, interface, (UCHAR) cmd) ; /* move flash pointer to respective area of the page */
  564. command2048 (&vol, interface, SERIAL_DATA_INPUT); /* start data loading for write */
  565. setAddress2048 (&vol, interface, addr) ;
  566. }
  567. /*----------------------------------------------------------------------*/
  568. /* r e a d S t a t u s */
  569. /* */
  570. /* Read status of selected flash device. */
  571. /* */
  572. /* Parameters: */
  573. /* vol : Pointer identifying drive */
  574. /* interface : Pointer to window. */
  575. /* */
  576. /* Returns: */
  577. /* Chip status. */
  578. /* */
  579. /*----------------------------------------------------------------------*/
  580. USHORT readStatus2048(FLFlash vol, Interface interface)
  581. {
  582. USHORT chipStatus ;
  583. command2048(&vol, interface, READ_STATUS);
  584. tffsWriteWordFlash(&(interface->signals.w), DBL( NOT_WP | CE ));
  585. if ( vol.interleaving == 1 ) /* 8-bit*/
  586. chipStatus = DBL(tffsReadByteFlash(&(interface->io[0].b)));
  587. else /* 16-bit */
  588. chipStatus = tffsReadWordFlash(&(interface->io[0].w));
  589. tffsWriteWordFlash(&(interface->signals.w), DBL( NOT_WP ));
  590. return chipStatus;
  591. }
  592. /*----------------------------------------------------------------------*/
  593. /* w r i t e E x e c u t e */
  594. /* */
  595. /* Execute write. */
  596. /* */
  597. /* Parametes: */
  598. /* vol : Pointer identifying drive */
  599. /* interface : Pointer to window. */
  600. /* Returns: */
  601. /* FLStatus : 0 on success, otherwise failed. */
  602. /* */
  603. /*----------------------------------------------------------------------*/
  604. FLStatus writeExecute2048 (FLFlash vol, Interface interface)
  605. {
  606. command2048 (&vol, interface, SETUP_WRITE); /* execute page program*/
  607. if (!waitForReady_nfdc2048(interface)) {
  608. return flTimedOut;
  609. }
  610. if( readStatus2048(&vol, interface) & DBL(FAIL) )
  611. return flWriteFault ;
  612. return flOK ;
  613. }
  614. /*----------------------------------------------------------------------*/
  615. /* r e a d O n e S e c t o r */
  616. /* */
  617. /* Read up to one 512-byte block from flash. */
  618. /* */
  619. /* Parameters: */
  620. /* vol : Pointer identifying drive */
  621. /* address : Address to read from. */
  622. /* buffer : buffer to read to. */
  623. /* length : number of bytes to read (up to sector size). */
  624. /* modes : EDC flag etc. */
  625. /* */
  626. /* Returns: */
  627. /* FLStatus: 0 on success, otherwise failed. */
  628. /* */
  629. /*----------------------------------------------------------------------*/
  630. FLStatus readOneSector_nfdc2048 (FLFlash vol,
  631. CardAddress address, /* starting flash address*/
  632. CHAR FAR1 *buffer, /* target buffer */
  633. LONG length, /* bytes to read */
  634. LONG modes) /* EDC flag etc.*/
  635. {
  636. FLStatus status = flOK;
  637. PointerOp cmd;
  638. CardAddress addr = address ;
  639. Interface interface = mapContInterface(&vol, address); /* select flash device */
  640. /* move flash pointer to areas A,B or C of page*/
  641. makeCommand_nfdc2048 (&vol, &cmd, &addr, modes) ;
  642. readCommand2048 (&vol, interface, cmd, addr);
  643. #ifdef NFDC2048
  644. if(modes & EDC) {
  645. SET_ECC_CONFIG(interface, ECC_RST | ECC_EN); /*ECC reset and ON for read*/
  646. }
  647. #endif /* NFDC2048 */
  648. if ((vol.interleaving == 1) && !(vol.flags & BIG_PAGE) ) /* 8-bit */
  649. {
  650. /* read up to two pages separately, starting page.. */
  651. LONG toFirstPage, toSecondPage;
  652. toFirstPage = (cmd == AREA_C ? 8 : 0x100) -
  653. ((USHORT)address & (cmd == AREA_C ? 7 : 0xff));
  654. if (toFirstPage > length)
  655. toFirstPage = length;
  656. toSecondPage = length - toFirstPage ;
  657. tffscpy16fromMedia ((UCHAR*)buffer, (const UCHAR FAR0 *) interface->io, toFirstPage ) ;
  658. if ( toSecondPage > 0 )
  659. {
  660. /* next page*/
  661. readCommand2048 (&vol, interface, AREA_A, address + toFirstPage) ;
  662. tffscpy16fromMedia( (UCHAR*)(buffer + toFirstPage),
  663. (const UCHAR FAR0 *) interface->io,
  664. toSecondPage ) ;
  665. }
  666. }
  667. else /* interleaving == 2 so 16-bit read*/
  668. tffscpy16fromMedia( (UCHAR*)buffer, (const UCHAR FAR0 *) interface->io, length );
  669. #ifdef NFDC2048
  670. if( modes & EDC )
  671. {
  672. UCHAR extraBytes[SYNDROM_BYTES];
  673. /* read syndrom to let it through the ECC unit*/
  674. SET_ECC_CONFIG(interface, ECC_EN | PAR_DIS); /* parity off in ECC*/
  675. tffscpy16fromMedia( extraBytes, (const UCHAR FAR0 *) interface->io, SYNDROM_BYTES ) ;
  676. if( CHK_ECC_ERROR(interface) ) /* ECC error*/
  677. {
  678. if( (vol.interleaving == 1) && !(vol.flags & BIG_PAGE) )
  679. { /* HOOK : make ECC working on 2M /INLV 1 */ }
  680. else
  681. {
  682. #ifdef USE_EDC
  683. /* try to fix ECC error*/
  684. if ( modes & SECOND_TRY ) /* 2nd try*/
  685. {
  686. UCHAR syndrom[SYNDROM_BYTES];
  687. /* read syndrom-on-syndrom from ASIC*/
  688. readSyndromOnSyndrom(interface, (USHORT*)syndrom );
  689. if (flCheckAndFixEDC(buffer, (CHAR FAR1 *)syndrom, vol.interleaving == 2) != NO_EDC_ERROR) {
  690. DEBUG_PRINT(("Debug: ECC error in NFDC 2048.\n"));
  691. status = flDataError;
  692. }
  693. }
  694. else /* 1st try - try once more*/
  695. {
  696. SET_ECC_CONFIG(interface, PAR_DIS); /* reset ECC*/
  697. return readOneSector_nfdc2048(&vol, address, buffer, length, modes | SECOND_TRY ) ;
  698. }
  699. #endif /* USE_EDC*/
  700. }
  701. }
  702. SET_ECC_CONFIG(interface, PAR_DIS); /* ECC off*/
  703. }
  704. #endif /* NFDC2048 */
  705. interface->signals.w = DBL(NOT_WP) ;
  706. return status;
  707. }
  708. /*----------------------------------------------------------------------*/
  709. /* w r i t e O n e S e c t o r */
  710. /* */
  711. /* Write data in one 512-byte block to flash. */
  712. /* Assuming that EDC mode never requested on partial block writes. */
  713. /* */
  714. /* Parameters: */
  715. /* vol : Pointer identifying drive */
  716. /* address : Address of sector to write to. */
  717. /* buffer : buffer to write from. */
  718. /* length : number of bytes to write (up to sector size). */
  719. /* modes : OVERWRITE, EDC flags etc. */
  720. /* */
  721. /* Returns: */
  722. /* FLStatus: 0 on success, otherwise failed. */
  723. /* */
  724. /*----------------------------------------------------------------------*/
  725. FLStatus writeOneSector_nfdc2048(FLFlash vol,
  726. CardAddress address, /* target flash addres */
  727. const CHAR FAR1 *buffer, /* source RAM buffer */
  728. LONG length, /* bytes to write (up to BLOCK) */
  729. LONG modes) /* OVERWRITE, EDC flags etc. */
  730. {
  731. FLStatus status;
  732. PointerOp cmd;
  733. Interface interface = mapContInterface(&vol, address); /* select flash device*/
  734. if (flWriteProtected(vol.socket))
  735. return flWriteProtect;
  736. /* move flash pointer to areas A,B or C of page */
  737. makeCommand_nfdc2048 (&vol, &cmd, &address, modes) ;
  738. if ((vol.flags & FULL_PAGE) && cmd == AREA_B) {
  739. ULONG prePad = 2 + ((USHORT) address & thisVars->pageMask);
  740. writeCommand2048(&vol, interface, AREA_A, address + thisVars->pageAreaSize - prePad);
  741. tffsset16( (UCHAR FAR0 *) interface->io, 0xff, prePad);
  742. }
  743. else
  744. writeCommand2048(&vol, interface, cmd, address);
  745. #ifdef NFDC2048
  746. if (modes & EDC)
  747. SET_ECC_CONFIG(interface, ECC_EN | ECC_RW); /* ECC ON for write*/
  748. #endif
  749. /* load data and syndrom*/
  750. if( (vol.interleaving == 1) && !(vol.flags & BIG_PAGE) ) /* 8-bit*/
  751. {
  752. LONG toFirstPage, toSecondPage ;
  753. /* write up to two pages separately*/
  754. toFirstPage = (modes & EXTRA ? 8 : 0x100) -
  755. ((USHORT)address & (modes & EXTRA ? 7 : 0xff));
  756. if (toFirstPage > length)
  757. toFirstPage = length;
  758. toSecondPage = length - toFirstPage ;
  759. tffscpy16toMedia( (UCHAR FAR0 *) interface->io, /* user data */
  760. (const UCHAR *)buffer,
  761. toFirstPage);
  762. if ( toSecondPage > 0 )
  763. {
  764. checkStatus( writeExecute2048(&vol, interface) ) ; /* done with 1st page */
  765. writeCommand2048(&vol, interface, AREA_A, address + toFirstPage);
  766. /* user data*/
  767. tffscpy16toMedia( (UCHAR FAR0 *) interface->io,
  768. (const UCHAR *)(buffer + toFirstPage),
  769. toSecondPage);
  770. }
  771. }
  772. else /* 16-bit*/
  773. tffscpy16toMedia( (UCHAR FAR0 *) interface->io, /* user data*/
  774. (const UCHAR *)buffer,
  775. length );
  776. if(modes & EDC)
  777. {
  778. USHORT extraBytes[SYNDROM_BYTES / sizeof(USHORT) + 1];
  779. /* Read the ECC syndrom*/
  780. #ifdef NFDC2048
  781. tffsWriteWordFlash(&(interface->signals.w), DBL(NOT_WP));
  782. SET_ECC_CONFIG(interface, ECC_EN | PAR_DIS | ECC_RW); /* ECC parity off*/
  783. readSyndrom_nfdc2048( interface, (USHORT*)extraBytes) ;
  784. /* Write ECC syndrom and ANAND mark to the tail*/
  785. SET_ECC_CONFIG(interface, PAR_DIS); /* ECC off*/
  786. interface->signals.w = DBL(NOT_WP | CE);
  787. #else
  788. extraBytes[0] = extraBytes[1] = extraBytes[2] = 0xffff;
  789. #endif /* NFDC2048 */
  790. extraBytes[SYNDROM_BYTES / sizeof(USHORT)] = 0x5555; /* Anand mark */
  791. tffscpy16toMedia((UCHAR FAR0 *) interface->io, (const UCHAR *)extraBytes,
  792. sizeof extraBytes);
  793. }
  794. status = writeExecute2048(&vol, interface);
  795. tffsWriteWordFlash(&(interface->signals.w), DBL(NOT_WP));
  796. return status;
  797. }
  798. /*��������������������������������������������Ŀ
  799. Core MTD methods - read, write and erase
  800. */
  801. /*----------------------------------------------------------------------*/
  802. /* c d s n R e a d */
  803. /* */
  804. /* Read some data from the flash. This routine will be registered as */
  805. /* the read routine for this MTD. */
  806. /* */
  807. /* Parameters: */
  808. /* vol : Pointer identifying drive */
  809. /* address : Address to read from. */
  810. /* buffer : buffer to read to. */
  811. /* length : number of bytes to read (up to sector size). */
  812. /* modes : EDC flag etc. */
  813. /* */
  814. /* Returns: */
  815. /* FLStatus: 0 on success, otherwise failed. */
  816. /* */
  817. /*----------------------------------------------------------------------*/
  818. FLStatus cdsnRead( FLFlash vol,
  819. CardAddress address, /* target flash address */
  820. VOID FAR1 *buffer, /* source RAM buffer */
  821. dword length, /* bytes to write */
  822. word modes) /* Overwrite, EDC flags etc. */
  823. {
  824. CHAR FAR1 *temp;
  825. ULONG readNow;
  826. /* read in sectors; first and last might be partial*/
  827. ULONG block = modes & EXTRA ? 8 : SECTOR_SIZE;
  828. readNow = block - ((USHORT)address & (block - 1));
  829. temp = (CHAR FAR1 *)buffer;
  830. for ( ; length > 0 ; )
  831. {
  832. if (readNow > length)
  833. readNow = length;
  834. /* turn off EDC on partial block read*/
  835. checkStatus( readOneSector_nfdc2048(&vol, address, temp, readNow,
  836. (readNow != SECTOR_SIZE ? (modes & ~EDC) : modes)) );
  837. length -= readNow;
  838. address += readNow;
  839. temp += readNow;
  840. /* align at sector */
  841. readNow = block;
  842. }
  843. return flOK ;
  844. }
  845. /*----------------------------------------------------------------------*/
  846. /* c d s n W r i t e */
  847. /* */
  848. /* Write some data to the flash. This routine will be registered as the */
  849. /* write routine for this MTD. */
  850. /* */
  851. /* Parameters: */
  852. /* vol : Pointer identifying drive */
  853. /* address : Address of sector to write to. */
  854. /* buffer : buffer to write from. */
  855. /* length : number of bytes to write (up to sector size). */
  856. /* modes : OVERWRITE, EDC flags etc. */
  857. /* */
  858. /* Returns: */
  859. /* FLStatus: 0 on success, otherwise failed. */
  860. /* */
  861. /*----------------------------------------------------------------------*/
  862. FLStatus cdsnWrite( FLFlash vol,
  863. CardAddress address, /* target flash address*/
  864. const VOID FAR1 *buffer, /* source RAM buffer */
  865. dword length, /* bytes to write */
  866. word modes) /* Overwrite, EDC flags etc.*/
  867. {
  868. ULONG writeNow;
  869. const CHAR FAR1 *temp;
  870. FLStatus status = flOK;
  871. #ifdef VERIFY_AFTER_WRITE
  872. CardAddress saveAddress = address;
  873. USHORT flReadback[SECTOR_SIZE / sizeof(USHORT)];
  874. #endif
  875. /* write in sectors; first and last might be partial*/
  876. LONG block = modes & EXTRA ? 8 : SECTOR_SIZE;
  877. writeNow = block - ((USHORT)address & (block - 1));
  878. temp = (const CHAR FAR1 *)buffer;
  879. for ( ; length > 0 ; )
  880. {
  881. if (writeNow > length)
  882. writeNow = length;
  883. /* turn off EDC on partial block write*/
  884. status = writeOneSector_nfdc2048(&vol, address, temp, writeNow,
  885. writeNow != SECTOR_SIZE ? (modes & ~EDC) : modes);
  886. if (status != flOK)
  887. break;
  888. #ifdef VERIFY_AFTER_WRITE
  889. status = readOneSector_nfdc2048 (&vol, address, (CHAR FAR1 *)flReadback,
  890. writeNow, (writeNow != SECTOR_SIZE ? (modes & ~EDC) : modes));
  891. if((status != flOK) || (tffscmp(temp, flReadback, writeNow) != 0))
  892. { status = flWriteFault; break; }
  893. #endif
  894. length -= writeNow;
  895. address += writeNow;
  896. temp += writeNow;
  897. /* align at sector */
  898. writeNow = block;
  899. }
  900. return flOK ;
  901. }
  902. /*----------------------------------------------------------------------*/
  903. /* c d s n E r a s e */
  904. /* */
  905. /* Erase number of blocks. This routine will be registered as the */
  906. /* erase routine for this MTD. */
  907. /* */
  908. /* Parameters: */
  909. /* vol : Pointer identifying drive */
  910. /* blockNo : First block to erase. */
  911. /* blocksToErase : Number of blocks to erase. */
  912. /* */
  913. /* Returns: */
  914. /* FLStatus : 0 on success, otherwise failed. */
  915. /* */
  916. /*----------------------------------------------------------------------*/
  917. FLStatus cdsnErase( FLFlash vol,
  918. word blockNo, /* start' block (0 .. chipNoOfBlocks-1)*/
  919. word blocksToErase) /* Number of blocks to be erased */
  920. {
  921. LONG i;
  922. FLStatus status = flOK;
  923. Interface interface =
  924. mapContInterface(&vol, (LONG)blockNo * vol.erasableBlockSize ) ; /* select device*/
  925. if (flWriteProtected(vol.socket))
  926. return flWriteProtect;
  927. blockNo %= thisVars->noOfBlocks ; /* within flash device */
  928. if ( blockNo + blocksToErase > thisVars->noOfBlocks ) /* accross device boundary */
  929. return flBadParameter;
  930. for ( i=0 ; i < blocksToErase ; i++, blockNo++ )
  931. {
  932. USHORT pageNo = (USHORT) (blockNo * thisVars->pagesPerBlock);
  933. command2048(&vol, interface, SETUP_ERASE);
  934. tffsWriteWordFlash(&(interface->signals.w), DBL(ALE | NOT_WP | CE));
  935. /* send 'pageNo' to the flash in the following sequence: */
  936. /* bits 7..0 first */
  937. /* bits 15..8 next */
  938. if (vol.interleaving == 1)
  939. {
  940. tffsWriteByteFlash(&(interface->io[0].b),(UCHAR)pageNo);
  941. tffsWriteByteFlash(&(interface->io[0].b),(UCHAR)(pageNo >> 8));
  942. }
  943. else
  944. {
  945. tffsWriteWordFlash(&(interface->io[0].w), DBL(pageNo));
  946. tffsWriteWordFlash(&(interface->io[0].w), DBL(pageNo >> 8));
  947. }
  948. tffsWriteWordFlash(&(interface->signals.w), DBL(NOT_WP | CE));
  949. /* if only one block may be erase at a time then do it
  950. otherwise leave it for later*/
  951. command2048(&vol, interface, CONFIRM_ERASE);
  952. if (!waitForReady_nfdc2048(interface))
  953. status = flTimedOut;
  954. if ( readStatus2048(&vol, interface) & DBL(FAIL)) { /* erase operation failed*/
  955. status = flWriteFault ;
  956. }
  957. if (status != flOK) { /* reset flash device and abort */
  958. DEBUG_PRINT(("Debug: erase failed in NFDC 2048.\n"));
  959. command2048(&vol, interface, RESET_FLASH ) ;
  960. waitForReady_nfdc2048(interface) ;
  961. break ;
  962. }
  963. } /* block loop */
  964. #ifdef MULTI_ERASE
  965. /* do multiple block erase as was promised*/
  966. command2048(&vol, interface, CONFIRM_ERASE);
  967. if (!waitForReady_nfdc2048(interface))
  968. status = flTimedOut;
  969. if ( readStatus2048(interface) & DBL(FAIL)) { /* erase operation failed*/
  970. status = flWriteFault ;
  971. }
  972. if (status != flOK) { /* reset flash device and abort*/
  973. DEBUG_PRINT(("Debug: erase failed in NFDC 2048.\n"));
  974. command2048(&vol, interface, RESET_FLASH ) ;
  975. waitForReady_nfdc2048(interface) ;
  976. }
  977. #endif /* MULTI_ERASE*/
  978. if(status == flOK)
  979. if ( readStatus2048(&vol, interface) & DBL(FAIL) ) {
  980. DEBUG_PRINT(("Debug: erase failed in NFDC 2048.\n"));
  981. status = flWriteFault;
  982. }
  983. return status;
  984. }
  985. /*----------------------------------------------------------------------*/
  986. /* c d s n M a p */
  987. /* */
  988. /* Map through buffer. This routine will be registered as the map */
  989. /* routine for this MTD. */
  990. /* */
  991. /* Parameters: */
  992. /* vol : Pointer identifying drive */
  993. /* address : Flash address to be mapped. */
  994. /* length : number of bytes to map. */
  995. /* */
  996. /* Returns: */
  997. /* Pointer to the buffer data was mapped to. */
  998. /* */
  999. /*----------------------------------------------------------------------*/
  1000. VOID FAR0 * cdsnMap ( FLFlash vol,
  1001. CardAddress address,
  1002. int length )
  1003. {
  1004. cdsnRead(&vol,address,thisBuffer,length, 0);
  1005. vol.socket->remapped = TRUE;
  1006. return (VOID FAR0 *)thisBuffer;
  1007. }
  1008. #ifdef NFDC2048
  1009. /*----------------------------------------------------------------------*/
  1010. /* c d s n S e t C a l l b a c k */
  1011. /* */
  1012. /* Register a routine (powerUp()) for power on callback. */
  1013. /* */
  1014. /* Parameters: */
  1015. /* vol : Pointer identifying drive */
  1016. /* */
  1017. /*----------------------------------------------------------------------*/
  1018. VOID cdsnSetCallback(FLFlash vol)
  1019. {
  1020. flSetPowerOnCallback(vol.socket, powerUp, &vol);
  1021. }
  1022. #endif /* NFDC2048 */
  1023. /*----------------------------------------------------------------------*/
  1024. /* i s K n o w n M e d i a */
  1025. /* */
  1026. /* Check if this flash media is supported. Initialize relevant fields */
  1027. /* in data structures. */
  1028. /* */
  1029. /* Parameters: */
  1030. /* vol : Pointer identifying drive */
  1031. /* vendorId_P : vendor ID read from chip. */
  1032. /* chipId_p : chip ID read from chip. */
  1033. /* dev : dev chips were accessed before this one. */
  1034. /* */
  1035. /* Returns: */
  1036. /* TRUE if this media is supported, FALSE otherwise. */
  1037. /* */
  1038. /*----------------------------------------------------------------------*/
  1039. FLBoolean isKnownMedia_nfdc2048( FLFlash vol,
  1040. USHORT vendorId_p,
  1041. USHORT chipId_p,
  1042. LONG dev )
  1043. {
  1044. #ifdef NFDC2048
  1045. if ((chipId_p & 0xff00) == 0x6400)
  1046. chipId_p = DBL(0x64); /* Workaround for TC5816/NFDC2048 problem */
  1047. #endif /* NFDC2048 */
  1048. if (dev == 0)
  1049. {
  1050. thisVars->vendorID = vendorId_p; /* remember for next chips */
  1051. thisVars->chipID = chipId_p;
  1052. thisVars->pagesPerBlock = PAGES_PER_BLOCK;
  1053. if (vendorId_p == DBL(0xEC)) /* Samsung */
  1054. {
  1055. switch (chipId_p)
  1056. {
  1057. case DBL(0x64): /* 2M */
  1058. case DBL(0xEA) :
  1059. vol.type = KM29N16000_FLASH ;
  1060. vol.chipSize = 0x200000L;
  1061. return TRUE;
  1062. case DBL(0xE5):
  1063. case DBL(0xE3): /* 4M */
  1064. vol.type = KM29N32000_FLASH;
  1065. vol.flags |= BIG_PAGE;
  1066. vol.chipSize = 0x400000L;
  1067. return TRUE;
  1068. case DBL(0xE6): /* 8M */
  1069. vol.type = KM29V64000_FLASH;
  1070. vol.flags |= BIG_PAGE;
  1071. vol.chipSize = 0x800000L;
  1072. return TRUE;
  1073. case DBL(0x73): /* 16 Mb */
  1074. vol.type = KM29V128000_FLASH;
  1075. vol.flags |= BIG_PAGE;
  1076. vol.chipSize = 0x1000000L;
  1077. thisVars->pagesPerBlock *= 2;
  1078. return TRUE;
  1079. case DBL(0x75): /* 32 Mb */
  1080. vol.type = KM29V256000_FLASH;
  1081. vol.flags |= BIG_PAGE;
  1082. vol.chipSize = 0x2000000L;
  1083. thisVars->pagesPerBlock *= 2;
  1084. return TRUE;
  1085. }
  1086. }
  1087. else
  1088. if (vendorId_p == DBL(0x8F)) /* National */
  1089. {
  1090. switch (chipId_p)
  1091. {
  1092. case DBL(0x64): /* 2M */
  1093. vol.type = NM29N16_FLASH;
  1094. vol.chipSize = 0x200000L;
  1095. return TRUE;
  1096. }
  1097. }
  1098. else
  1099. if (vendorId_p == DBL(0x98)) /* Toshiba */
  1100. {
  1101. vol.flags |= FULL_PAGE; /* no partial page programming */
  1102. switch (chipId_p)
  1103. {
  1104. case DBL(0x64): /* 2M */
  1105. case DBL(0xEA) :
  1106. vol.type = TC5816_FLASH;
  1107. vol.chipSize = 0x200000L;
  1108. return TRUE;
  1109. case DBL(0x6B): /* 4M */
  1110. case DBL(0xE5):
  1111. vol.type = TC5832_FLASH;
  1112. vol.flags |= BIG_PAGE;
  1113. vol.chipSize = 0x400000L;
  1114. return TRUE;
  1115. case DBL(0xE6): /* 8M */
  1116. vol.type = TC5816_FLASH;
  1117. vol.flags |= BIG_PAGE;
  1118. vol.chipSize = 0x800000L;
  1119. return TRUE;
  1120. case DBL(0x73): /* 16 Mb */
  1121. vol.type = TC58128_FLASH;
  1122. vol.flags |= BIG_PAGE;
  1123. vol.chipSize = 0x1000000L;
  1124. thisVars->pagesPerBlock *= 2;
  1125. return TRUE;
  1126. case DBL(0x75): /* 32 Mb */
  1127. vol.type = TC58256_FLASH;
  1128. vol.flags |= BIG_PAGE;
  1129. vol.chipSize = 0x2000000L;
  1130. thisVars->pagesPerBlock *= 2;
  1131. return TRUE;
  1132. }
  1133. }
  1134. }
  1135. else /* dev != 0*/
  1136. if( (vendorId_p == thisVars->vendorID) && (chipId_p == thisVars->chipID) )
  1137. return TRUE ;
  1138. return FALSE ;
  1139. }
  1140. /*----------------------------------------------------------------------*/
  1141. /* r e a d F l a s h I D */
  1142. /* */
  1143. /* Read vendor and chip IDs, count flash devices. Initialize relevant */
  1144. /* fields in data structures. */
  1145. /* */
  1146. /* Parameters: */
  1147. /* vol : Pointer identifying drive */
  1148. /* interface : Pointer to window. */
  1149. /* dev : dev chips were accessed before this one. */
  1150. /* */
  1151. /* Returns: */
  1152. /* TRUE if this media is supported, FALSE otherwise. */
  1153. /* */
  1154. /*----------------------------------------------------------------------*/
  1155. LONG readFlashID2048 (FLFlash vol, Interface interface, LONG dev)
  1156. {
  1157. USHORT vendorId_p, chipId_p ;
  1158. KeStallExecutionProcessor(250 * 1000);
  1159. command2048(&vol, interface, RESET_FLASH ) ;
  1160. flDelayMsecs(10);
  1161. command2048(&vol, interface, READ_ID);
  1162. tffsWriteWordFlash(&(interface->signals.w), DBL(ALE | NOT_WP | CE));
  1163. if (vol.interleaving == 1) {
  1164. tffsWriteByteFlash(&(interface->io[0].b), 0); /* Read ID from*/
  1165. } else { /* address 0. */
  1166. tffsWriteWordFlash(&(interface->io[0].w), 0);
  1167. }
  1168. tffsWriteWordFlash(&(interface->signals.w), DBL(NOT_WP | CE));
  1169. /* read vendor and chip IDs */
  1170. vendorId_p = (vol.interleaving == 1 ? DBL(tffsReadByteFlash(&(interface->io[0].b))) : tffsReadWordFlash(&(interface->io[0].w))) ;
  1171. chipId_p = (vol.interleaving == 1 ? DBL(tffsReadByteFlash(&(interface->io[0].b))) : tffsReadWordFlash(&(interface->io[0].w)));
  1172. tffsWriteWordFlash(&(interface->signals.w), DBL(NOT_WP));
  1173. if ( isKnownMedia_nfdc2048(&vol, vendorId_p, chipId_p, dev) != TRUE ) /* no chip or diff.*/
  1174. return FALSE ; /* type of flash */
  1175. /* set flash parameters*/
  1176. if ( dev == 0 )
  1177. {
  1178. thisVars->pageAreaSize = (USHORT) (0x100 * vol.interleaving);
  1179. thisVars->pageSize = (USHORT) ((vol.flags & BIG_PAGE ? 0x200 : 0x100) * vol.interleaving);
  1180. thisVars->tailSize = (USHORT) ((vol.flags & BIG_PAGE ? 16 : 8) * vol.interleaving);
  1181. thisVars->pageMask = thisVars->pageSize - 1 ;
  1182. vol.erasableBlockSize = thisVars->pagesPerBlock * thisVars->pageSize;
  1183. thisVars->noOfBlocks = (USHORT)( (vol.chipSize * vol.interleaving)
  1184. / vol.erasableBlockSize ) ;
  1185. }
  1186. return TRUE ;
  1187. }
  1188. /*----------------------------------------------------------------------*/
  1189. /* c d s n I d e n t i f y */
  1190. /* */
  1191. /* Identify flash. This routine will be registered as the */
  1192. /* identification routine for this MTD. */
  1193. /* */
  1194. /* Returns: */
  1195. /* FLStatus: 0 on success, otherwise failed. */
  1196. /* */
  1197. /*----------------------------------------------------------------------*/
  1198. FLStatus cdsnIdentify(FLFlash vol)
  1199. {
  1200. LONG addr = 0L ;
  1201. Interface interface;
  1202. DEBUG_PRINT(("Debug: Entering NFDC 2048 identification routine\n"));
  1203. flDelayMsecs(10); /* wait for socket to power up */
  1204. flSetWindowBusWidth(vol.socket,16);/* use 16-bits */
  1205. flSetWindowSpeed(vol.socket,250); /* 250 nsec. */
  1206. flSetWindowSize(vol.socket,2); /* 4 KBytes */
  1207. vol.mtdVars = &mtdVars_nfdc2048[flSocketNoOf(vol.socket)];
  1208. /* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
  1209. thisVars->buffer = flBufferOf(flSocketNoOf(vol.socket));
  1210. /* detect card - identify bit toggles on consequitive reads*/
  1211. vol.chipSize = 0x200000L ; /* Assume something ... */
  1212. vol.interleaving = 1; /* unimportant for now */
  1213. interface = mapContInterface(&vol, 0);
  1214. KeStallExecutionProcessor(250 * 1000);
  1215. if((tffsReadByteFlash(&(interface->eccConfig.b)) & TOGGLE) == (tffsReadByteFlash(&(interface->eccConfig.b)) & TOGGLE))
  1216. return flUnknownMedia;
  1217. /* read interleave from the card*/
  1218. #ifdef NFDC2048
  1219. vol.interleaving = ( (getAttReg(&vol, JUMPERS ) & JMPER_INLV) ? 1 : 2 );
  1220. powerUp((VOID *) &vol);
  1221. interface = mapContInterface(&vol, 0);
  1222. KeStallExecutionProcessor(250 * 1000);
  1223. if (vol.interleaving == 1)
  1224. flSetWindowBusWidth(vol.socket, 8);
  1225. #else
  1226. vol.interleaving = INLV;
  1227. #endif /* NFDC2048 */
  1228. /* reset all flash devices*/
  1229. tffsWriteWordFlash(&(interface->signals.w), DBL(NOT_WP));
  1230. /* identify and count flash chips, figure out flash parameters*/
  1231. for (vol.noOfChips = 0 ;
  1232. vol.noOfChips < MAX_FLASH_DEVICES;
  1233. vol.noOfChips += vol.interleaving,
  1234. addr += vol.chipSize * vol.interleaving)
  1235. {
  1236. interface = mapContInterface(&vol, addr) ;
  1237. if ( readFlashID2048(&vol, interface, vol.noOfChips) != TRUE ) /* no chip or different type of flash*/
  1238. break ;
  1239. }
  1240. if ( vol.noOfChips == 0 ) /* no chips were found */
  1241. return flUnknownMedia;
  1242. /* ECC off*/
  1243. interface = mapContInterface(&vol, 0);
  1244. KeStallExecutionProcessor(250 * 1000);
  1245. #ifdef NFDC2048
  1246. SET_ECC_CONFIG(interface, PAR_DIS); /* disable ECC and parity*/
  1247. setAttReg(&vol, CARD_CONFIG, PWRDWN);
  1248. #endif /* NFDC2048 */
  1249. /* Register our flash handlers */
  1250. vol.write = cdsnWrite;
  1251. vol.erase = cdsnErase;
  1252. vol.read = cdsnRead;
  1253. vol.map = cdsnMap;
  1254. #ifdef NFDC2048
  1255. vol.setPowerOnCallback = cdsnSetCallback;
  1256. #endif
  1257. vol.flags |= NFTL_ENABLED;
  1258. DEBUG_PRINT(("Debug: Identified NFDC 2048.\n"));
  1259. return flOK;
  1260. }
  1261. /*----------------------------------------------------------------------*/
  1262. /* f l R e g i s t e r C D S N */
  1263. /* */
  1264. /* Registers this MTD for use */
  1265. /* */
  1266. /* Parameters: */
  1267. /* None */
  1268. /* */
  1269. /* Returns: */
  1270. /* FLStatus : 0 on success, otherwise failure */
  1271. /*----------------------------------------------------------------------*/
  1272. FLStatus flRegisterCDSN(VOID)
  1273. {
  1274. if (noOfMTDs >= MTDS)
  1275. return flTooManyComponents;
  1276. mtdTable[noOfMTDs++] = cdsnIdentify;
  1277. return flOK;
  1278. }