amdmtd.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:22k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Log:   P:/user/amir/lite/vcs/amdmtd.c_v  $
  3.  * 
  4.  *    Rev 1.21   03 Nov 1997 16:07:06   danig
  5.  * Support RFA
  6.  *
  7.  *    Rev 1.20   02 Nov 1997 11:06:38   ANDRY
  8.  * bug fix in AMDErase() for RFA on PowerPC
  9.  *
  10.  *    Rev 1.19   20 Oct 1997 14:08:56   danig
  11.  * Resume erase only when needed
  12.  *
  13.  *    Rev 1.18   19 Oct 1997 16:39:50   danig
  14.  * Deal with the last word in interleaving 4
  15.  *
  16.  *    Rev 1.17   29 Sep 1997 18:21:08   danig
  17.  * Try different interleavings in amdMTDIdentify()
  18.  *
  19.  *    Rev 1.16   24 Sep 1997 17:45:52   danig
  20.  * Default interleaving value is 4
  21.  *
  22.  *    Rev 1.15   10 Sep 1997 16:22:00   danig
  23.  * Got rid of generic names
  24.  *
  25.  *    Rev 1.14   08 Sep 1997 18:56:50   danig
  26.  * Support interleaving 4
  27.  *
  28.  *    Rev 1.13   04 Sep 1997 17:39:34   danig
  29.  * Debug messages
  30.  *
  31.  *    Rev 1.12   31 Aug 1997 14:53:48   danig
  32.  * Registration routine return status
  33.  *
  34.  *    Rev 1.11   10 Aug 1997 17:56:02   danig
  35.  * Comments
  36.  *
  37.  *    Rev 1.10   24 Jul 1997 17:51:54   amirban
  38.  * FAR to FAR0
  39.  *
  40.  *    Rev 1.9   20 Jul 1997 17:16:54   amirban
  41.  * No watchDogTimer
  42.  *
  43.  *    Rev 1.8   07 Jul 1997 15:20:54   amirban
  44.  * Ver 2.0
  45.  *
  46.  *    Rev 1.5   06 Feb 1997 18:18:34   danig
  47.  * Different unlock addresses for series C
  48.  *
  49.  *    Rev 1.4   17 Nov 1996 15:45:16   danig
  50.  * added LV017 support.
  51.  *
  52.  *    Rev 1.3   14 Oct 1996 17:57:00   danig
  53.  * new IDs and eraseFirstBlockLV008.
  54.  *
  55.  *    Rev 1.2   09 Sep 1996 11:38:26   amirban
  56.  * Correction for Fujitsu 8-mbit
  57.  *
  58.  *    Rev 1.1   29 Aug 1996 14:14:46   amirban
  59.  * Warnings
  60.  *
  61.  *    Rev 1.0   15 Aug 1996 15:16:38   amirban
  62.  * Initial revision.
  63.  */
  64. /************************************************************************/
  65. /*                                                                      */
  66. /* FAT-FTL Lite Software Development Kit */
  67. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  68. /* */
  69. /************************************************************************/
  70. /*----------------------------------------------------------------------*/
  71. /*                                                                      */
  72. /* This MTD supports the following Flash technologies:                  */
  73. /*                                                                      */
  74. /* - AMD Am29F080 8-mbit devices */
  75. /* - AMD Am29LV080 8-mbit devices         */
  76. /* - AMD Am29F016 16-mbit devices */
  77. /* - Fujitsu MBM29F080 8-mbit devices */
  78. /* */
  79. /* And (among others) the following Flash media and cards: */
  80. /*                                                                      */
  81. /* - AMD Series-D PCMCIA cards                                         */
  82. /* - AMD AmMC0XXA Miniature cards */
  83. /* - AMD AmMCL0XXA Miniature cards */
  84. /* */
  85. /*----------------------------------------------------------------------*/
  86. #include "flflash.h"
  87. #include "backgrnd.h"
  88. #define NO_UNLOCK_ADDR 0xffffffffL
  89. typedef struct {
  90.   unsigned long  unlockAddr1,
  91.  unlockAddr2;
  92.   unsigned long  baseMask;
  93. } Vars;
  94. static Vars mtdVars[DRIVES];
  95. #define thisVars   ((Vars *) vol.mtdVars)
  96. #define SETUP_ERASE 0x80
  97. #define SETUP_WRITE 0xa0
  98. #define READ_ID  0x90
  99. #define SUSPEND_ERASE 0xb0
  100. #define SECTOR_ERASE 0x30
  101. #define RESUME_ERASE 0x30
  102. #define READ_ARRAY 0xf0
  103. #define UNLOCK_1 0xaa
  104. #define UNLOCK_2 0x55
  105. #define UNLOCK_ADDR1 0x5555u
  106. #define UNLOCK_ADDR2 0x2aaau
  107. #define D2 4 /* Toggles when erase suspended */
  108. #define D5 0x20 /* Set when programming timeout */
  109. #define D6 0x40 /* Toggles when programming */
  110. /* JEDEC ids for this MTD */
  111. #define Am29F040_FLASH          0x01a4
  112. #define Am29F080_FLASH 0x01d5
  113. #define Am29LV080_FLASH 0x0138
  114. #define Am29LV008_FLASH         0x0137
  115. #define Am29F016_FLASH          0x01ad
  116. #define Am29F016C_FLASH   0x013d
  117. #define Am29LV017_FLASH         0x01c8
  118. #define Fuj29F040_FLASH         0x04a4
  119. #define Fuj29F080_FLASH 0x04d5
  120. #define Fuj29LV080_FLASH 0x0438
  121. #define Fuj29LV008_FLASH        0x0437
  122. #define Fuj29F016_FLASH         0x04ad
  123. #define Fuj29F016C_FLASH   0x043d
  124. #define Fuj29LV017_FLASH        0x04c8
  125. /*----------------------------------------------------------------------*/
  126. /*                         m a p B a s e */
  127. /* */
  128. /* Map the window to a page base (page is 4KB or 32KB depends on the */
  129. /* media type) and return a pointer to the base. Also return the offset */
  130. /* of the given address from the base. */
  131. /* */
  132. /* Parameters:                                                          */
  133. /* vol : Pointer identifying drive */
  134. /*      address : Card address to map */
  135. /* offset : receives the offset from the base */
  136. /* length : length to map */
  137. /*                                                                      */
  138. /* Returns: */
  139. /* FlashPTR : pointer to the page base. */
  140. /* */
  141. /*----------------------------------------------------------------------*/
  142. static FlashPTR mapBase(FLFlash        vol,
  143.                         CardAddress    address,
  144.                         unsigned long *offset,
  145.                         int            length)
  146. {
  147.   CardAddress base = address & thisVars->baseMask;
  148.   *offset = (unsigned long)(address - base);
  149.   return (FlashPTR)vol.map(&vol, base, length + *offset);
  150. }
  151. /*----------------------------------------------------------------------*/
  152. /*                         a m d C o m m a n d */
  153. /* */
  154. /* Writes an AMD command with the required unlock sequence */
  155. /* */
  156. /* Parameters:                                                          */
  157. /* vol : Pointer identifying drive */
  158. /*      address : Card address at which to write command */
  159. /* command : command to write */
  160. /* flashPtr : pointer to the window */
  161. /*                                                                      */
  162. /*----------------------------------------------------------------------*/
  163. static void amdCommand(FLFlash vol,
  164.        CardAddress address,
  165.        unsigned char command,
  166.        FlashPTR flashPtr)
  167. {
  168.   if (thisVars->unlockAddr1 != NO_UNLOCK_ADDR) {
  169.     *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  170.              ((int) address & (vol.interleaving - 1)) + thisVars->unlockAddr1))
  171.                                                                    = UNLOCK_1;
  172.     *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  173.              ((int) address & (vol.interleaving - 1)) + thisVars->unlockAddr2))
  174.                                                                    = UNLOCK_2;
  175.     *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  176.              ((int) address & (vol.interleaving - 1)) + thisVars->unlockAddr1))
  177.                                                                    = command;
  178.   }
  179.   else {
  180.     CardAddress baseAddress = address & (-0x10000l | (vol.interleaving - 1));
  181.     *(FlashPTR) flMap(vol.socket,baseAddress + vol.interleaving * UNLOCK_ADDR1) = UNLOCK_1;
  182.     *(FlashPTR) flMap(vol.socket,baseAddress + vol.interleaving * UNLOCK_ADDR2) = UNLOCK_2;
  183.     *(FlashPTR) flMap(vol.socket,baseAddress + vol.interleaving * UNLOCK_ADDR1) = command;
  184.     flMap(vol.socket, address);
  185.   }
  186. }
  187. /*----------------------------------------------------------------------*/
  188. /*                      a m d M T D W r i t e */
  189. /* */
  190. /* Write a block of bytes to Flash */
  191. /* */
  192. /* This routine will be registered as the MTD vol.write routine */
  193. /* */
  194. /* Parameters:                                                          */
  195. /* vol : Pointer identifying drive */
  196. /*      address : Card address to write to */
  197. /*      buffer : Address of data to write */
  198. /* length : Number of bytes to write */
  199. /* overwrite : TRUE if overwriting old Flash contents */
  200. /*   FALSE if old contents are known to be erased */
  201. /*                                                                      */
  202. /* Returns:                                                             */
  203. /* FLStatus : 0 on success, failed otherwise */
  204. /*----------------------------------------------------------------------*/
  205. static FLStatus amdMTDWrite(FLFlash vol,
  206.   CardAddress address,
  207.   const void FAR1 *buffer,
  208.   int length,
  209.   FLBoolean overwrite)
  210. {
  211.   /* Set timeout to 5 seconds from now */
  212.   unsigned long writeTimeout = flMsecCounter + 5000;
  213.   int cLength;
  214.   FlashPTR flashPtr, unlockAddr1, unlockAddr2;
  215.   unsigned long offset;
  216.   if (flWriteProtected(vol.socket))
  217.     return flWriteProtect;
  218.   flashPtr = mapBase(&vol, address, &offset, length);
  219.   unlockAddr1 = (FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  220.                                                        thisVars->unlockAddr1);
  221.   unlockAddr2 = (FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  222.                                                        thisVars->unlockAddr2);
  223.   flashPtr    = (FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  224.                                                        offset);
  225.   cLength = length;
  226.   if (vol.interleaving == 1) {
  227. lastByte:
  228. #ifdef __cplusplus
  229.     #define bFlashPtr  flashPtr
  230.     #define bBuffer ((const unsigned char FAR1 * &) buffer)
  231. #else
  232.     #define bFlashPtr  flashPtr
  233.     #define bBuffer ((const unsigned char FAR1 *) buffer)
  234. #endif
  235.     while (cLength >= 1) {
  236.       *unlockAddr1 = UNLOCK_1;
  237.       *unlockAddr2 = UNLOCK_2;
  238.       *unlockAddr1 = SETUP_WRITE;
  239.       *bFlashPtr = *bBuffer;
  240.       cLength--;
  241.       buffer = (unsigned char *)buffer + 1;  /* bBuffer++; */
  242.       bFlashPtr++;
  243.       while (bFlashPtr[-1] != bBuffer[-1] && flMsecCounter < writeTimeout) {
  244. if ((bFlashPtr[-1] & D5) && bFlashPtr[-1] != bBuffer[-1]) {
  245.   bFlashPtr[-1] = READ_ARRAY;
  246. #ifdef DEBUG_PRINT
  247.   DEBUG_PRINT("Debug: write failed in AMD MTD.n");
  248. #endif
  249.   return flWriteFault;
  250. }
  251.       }
  252.     }
  253.   }
  254.   else if (vol.interleaving == 2)  {
  255. lastWord:
  256. #ifdef __cplusplus
  257.     #define wFlashPtr ((FlashWPTR &) flashPtr)
  258.     #define wBuffer ((const unsigned short FAR1 * &) buffer)
  259.     #define wUnlockAddr1 ((FlashWPTR &) unlockAddr1)
  260.     #define wUnlockAddr2 ((FlashWPTR &) unlockAddr2)
  261. #else
  262.     #define wFlashPtr ((FlashWPTR) flashPtr)
  263.     #define wBuffer ((const unsigned short FAR1 *) buffer)
  264.     #define wUnlockAddr1 ((FlashWPTR) unlockAddr1)
  265.     #define wUnlockAddr2 ((FlashWPTR) unlockAddr2)
  266. #endif
  267.     while (cLength >= 2) {
  268.       *wUnlockAddr1 = UNLOCK_1 * 0x101;
  269.       *wUnlockAddr2 = UNLOCK_2 * 0x101;
  270.       *wUnlockAddr1 = SETUP_WRITE * 0x101;
  271.       *wFlashPtr = *wBuffer;
  272.       cLength -= 2;
  273.       buffer = (unsigned char *)buffer + sizeof(short);  /* wBuffer++; */
  274.       flashPtr = (unsigned char *)flashPtr + sizeof(short); /* wFlashPtr++; */
  275.       while ((wFlashPtr[-1] != wBuffer[-1]) && (flMsecCounter < writeTimeout)) {
  276.         if (((wFlashPtr[-1] &  D5         ) && ((wFlashPtr[-1] ^ wBuffer[-1]) &   0xff))
  277.                           ||
  278.             ((wFlashPtr[-1] & (D5 * 0x100)) && ((wFlashPtr[-1] ^ wBuffer[-1]) & 0xff00))) {
  279.   wFlashPtr[-1] = READ_ARRAY * 0x101;
  280. #ifdef DEBUG_PRINT
  281.   DEBUG_PRINT("Debug: write failed in AMD MTD.n");
  282. #endif
  283.   return flWriteFault;
  284. }
  285.       }
  286.     }
  287.     if (cLength > 0)
  288.       goto lastByte;
  289.   }
  290.   else /* if (vol.interleaving >= 4) */ {
  291. #ifdef __cplusplus
  292.     #define dFlashPtr ((FlashDPTR &) flashPtr)
  293.     #define dBuffer ((const unsigned long FAR1 * &) buffer)
  294.     #define dUnlockAddr1 ((FlashDPTR &) unlockAddr1)
  295.     #define dUnlockAddr2 ((FlashDPTR &) unlockAddr2)
  296. #else
  297.     #define dFlashPtr ((FlashDPTR) flashPtr)
  298.     #define dBuffer ((const unsigned long FAR1 *) buffer)
  299.     #define dUnlockAddr1 ((FlashDPTR) unlockAddr1)
  300.     #define dUnlockAddr2 ((FlashDPTR) unlockAddr2)
  301. #endif
  302.     while (cLength >= 4) {
  303.       *dUnlockAddr1 = UNLOCK_1 * 0x1010101lu;
  304.       *dUnlockAddr2 = UNLOCK_2 * 0x1010101lu;
  305.       *dUnlockAddr1 = SETUP_WRITE * 0x1010101lu;
  306.       *dFlashPtr = *dBuffer;
  307.       cLength -= 4;
  308.       buffer = (unsigned char *)buffer + sizeof(long); /* dBuffer++; */
  309.       flashPtr = (unsigned char *)flashPtr + sizeof(long); /* dFlashPtr++; */
  310.       while ((dFlashPtr[-1] != dBuffer[-1]) && (flMsecCounter < writeTimeout)) {
  311.         if (((dFlashPtr[-1] &  D5               ) && ((dFlashPtr[-1]  ^ dBuffer[-1]) &         0xff))
  312.                                ||
  313.             ((dFlashPtr[-1] & (D5 *       0x100)) && ((dFlashPtr[-1]  ^ dBuffer[-1]) &       0xff00))
  314.                                ||
  315.             ((dFlashPtr[-1] & (D5 *   0x10000lu)) && ((dFlashPtr[-1]  ^ dBuffer[-1]) &   0xff0000lu))
  316.                                ||
  317.             ((dFlashPtr[-1] & (D5 * 0x1000000lu)) && ((dFlashPtr[-1]  ^ dBuffer[-1]) & 0xff000000lu))) {
  318.   dFlashPtr[-1] = READ_ARRAY * 0x1010101lu;
  319. #ifdef DEBUG_PRINT
  320.   DEBUG_PRINT("Debug: write failed in AMD MTD.n");
  321. #endif
  322.   return flWriteFault;
  323. }
  324.       }
  325.     }
  326.     if (cLength > 0)
  327.       goto lastWord;
  328.   }
  329.   flashPtr -= length;
  330.   buffer = (unsigned char *)buffer - length; /* bBuffer -= length; */
  331.   if (tffscmp((void FAR0 *) flashPtr,buffer,length)) {
  332.     /* verify the data */
  333. #ifdef DEBUG_PRINT
  334.   DEBUG_PRINT("Debug: write failed in AMD MTD on verification.n");
  335. #endif
  336.     return flWriteFault;
  337.   }
  338.   return flOK;
  339. }
  340. /*----------------------------------------------------------------------*/
  341. /*               e r a s e F i r s t B l o c k L V 0 0 8 */
  342. /* */
  343. /* Erase the first block in LV008 chip. This block is devided into four */
  344. /* subblocks 16, 8, 8, and 32 kbytes in size.   */
  345. /* */
  346. /* Parameters:                                                          */
  347. /* vol : Pointer identifying drive */
  348. /*      firstErasableBlock : Number of block to erase */
  349. /*                                                                      */
  350. /* Returns:                                                             */
  351. /* FLStatus : 0 on success, failed otherwise */
  352. /*----------------------------------------------------------------------*/
  353. static FLStatus eraseFirstBlockLV008(FLFlash vol, int firstErasableBlock)
  354. {
  355.   int iSubBlock;
  356.   long subBlockSize = 0;
  357.   for (iSubBlock = 0; iSubBlock < 4; iSubBlock++) {
  358.     int i;
  359.     FlashPTR flashPtr;
  360.     FLBoolean finished;
  361.     switch (iSubBlock) {
  362.       case 1:
  363. subBlockSize = 0x4000;
  364. break;
  365.       case 2:
  366.       case 3:
  367. subBlockSize = 0x2000;
  368. break;
  369.     }
  370.     flashPtr = (FlashPTR)
  371.   vol.map(&vol,
  372.     firstErasableBlock + subBlockSize * vol.interleaving,
  373.     vol.interleaving);
  374.     for (i = 0; i < vol.interleaving; i++) {
  375.       amdCommand(&vol, i,SETUP_ERASE, flashPtr);
  376.       *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  377.                                           i + thisVars->unlockAddr1)) = UNLOCK_1;
  378.       *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  379.                                           i + thisVars->unlockAddr2)) = UNLOCK_2;
  380.       flashPtr[i] = SECTOR_ERASE;
  381.     }
  382.     do {
  383. #ifdef BACKGROUND
  384.       while (flForeground(1) == BG_SUSPEND) { /* suspend */
  385. for (i = 0; i < vol.interleaving; i++) {
  386.   flashPtr[i] = SUSPEND_ERASE;
  387.   /* Wait for D6 to stop toggling */
  388.   while ((flashPtr[i] ^ flashPtr[i]) & D6)
  389.     ;
  390. }
  391.       }
  392. #endif
  393.       finished = TRUE;
  394.       for (i = 0; i < vol.interleaving; i++) {
  395. flashPtr[i] = RESUME_ERASE;
  396. if (flashPtr[i] != 0xff) {
  397.   if ((flashPtr[i] & D5) && flashPtr[i] != 0xff) {
  398.     flashPtr[i] = READ_ARRAY;
  399.     return flWriteFault;
  400.   }
  401.   finished = FALSE;
  402. }
  403.       }
  404.     } while (!finished);
  405.   }
  406.   return flOK;
  407. }
  408. /*----------------------------------------------------------------------*/
  409. /*                     a m d M T D E r a s e */
  410. /* */
  411. /* Erase one or more contiguous Flash erasable blocks */
  412. /* */
  413. /* This routine will be registered as the MTD vol.erase routine */
  414. /* */
  415. /* Parameters:                                                          */
  416. /* vol : Pointer identifying drive */
  417. /*      firstErasableBlock : Number of first block to erase */
  418. /* numOfErasableBlocks: Number of blocks to erase */
  419. /*                                                                      */
  420. /* Returns:                                                             */
  421. /* FLStatus : 0 on success, failed otherwise */
  422. /*----------------------------------------------------------------------*/
  423. static FLStatus amdMTDErase(FLFlash vol,
  424.   int firstErasableBlock,
  425.   int numOfErasableBlocks)
  426. {
  427.   int iBlock;
  428.   if (flWriteProtected(vol.socket))
  429.     return flWriteProtect;
  430.   for (iBlock = 0; iBlock < numOfErasableBlocks; iBlock++) {
  431.     int i;
  432.     FLBoolean finished;
  433.     FlashPTR flashPtr;
  434.     /* The first block in an LV008 chip requires special care.*/
  435.     if ((vol.type == Am29LV008_FLASH) || (vol.type == Fuj29LV008_FLASH))
  436.       if ((firstErasableBlock + iBlock) % (vol.chipSize / 0x10000l) == 0) {
  437. checkStatus(eraseFirstBlockLV008(&vol, firstErasableBlock + iBlock));
  438. continue;
  439.       }
  440.     /* No need to call mapBase because we know we are on a unit boundary */
  441.     flashPtr = (FlashPTR)
  442.   vol.map(&vol,
  443.     (firstErasableBlock + iBlock) * vol.erasableBlockSize,
  444.     vol.interleaving);
  445.     for (i = 0; i < vol.interleaving; i++) {
  446.       amdCommand(&vol, i,SETUP_ERASE, flashPtr);
  447.       *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  448.                                           i + thisVars->unlockAddr1)) = UNLOCK_1;
  449.       *((FlashPTR) flAddLongToFarPointer((void FAR0 *)flashPtr,
  450.                                           i + thisVars->unlockAddr2)) = UNLOCK_2;
  451.       flashPtr[i] = SECTOR_ERASE;
  452.     }
  453.     do {
  454. #ifdef BACKGROUND
  455.       FLBoolean eraseSuspended = FALSE;
  456.       while (flForeground(1) == BG_SUSPEND) { /* suspend */
  457.         eraseSuspended = TRUE;
  458. for (i = 0; i < vol.interleaving; i++) {
  459.   flashPtr[i] = SUSPEND_ERASE;
  460.   /* Wait for D6 to stop toggling */
  461.   while ((flashPtr[i] ^ flashPtr[i]) & D6)
  462.     ;
  463. }
  464.       }
  465.       if (eraseSuspended) {   /* resume */
  466.         eraseSuspended = FALSE;
  467.         for(i = 0; i < vol.interleaving; i++)
  468.           flashPtr[i] = RESUME_ERASE;
  469.       }
  470. #endif
  471.       finished = TRUE;
  472.       for (i = 0; i < vol.interleaving; i++) {
  473. if (flashPtr[i] != 0xff) {
  474.   if ((flashPtr[i] & D5) && flashPtr[i] != 0xff) {
  475.     flashPtr[i] = READ_ARRAY;
  476.   #ifdef DEBUG_PRINT
  477.     DEBUG_PRINT("Debug: erase failed in AMD MTD.n");
  478.   #endif
  479.     return flWriteFault;
  480.   }
  481.   finished = FALSE;
  482. }
  483.       }
  484.     } while (!finished);
  485.   }
  486.   return flOK;
  487. }
  488. /*----------------------------------------------------------------------*/
  489. /*                    a m d M T D I d e n t i f y */
  490. /* */
  491. /* Identifies AMD and Fujitsu flash media and registers as an MTD for   */
  492. /* such. */
  493. /* */
  494. /* On successful identification, the Flash structure is filled out and */
  495. /* the write and erase routines registered. */
  496. /* */
  497. /* Parameters:                                                          */
  498. /* vol : Pointer identifying drive */
  499. /*                                                                      */
  500. /* Returns:                                                             */
  501. /* FLStatus : 0 on positive identificaion, failed otherwise */
  502. /*----------------------------------------------------------------------*/
  503. FLStatus amdMTDIdentify(FLFlash vol)
  504. {
  505.   int inlv;
  506.   #ifdef DEBUG_PRINT
  507.     DEBUG_PRINT("Debug: entering AMD MTD identification routine.n");
  508.   #endif
  509.   flSetWindowBusWidth(vol.socket,16);/* use 16-bits */
  510.   flSetWindowSpeed(vol.socket,120);  /* 120 nsec. */
  511.   flSetWindowSize(vol.socket,2); /* 8 KBytes */
  512.   vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)];
  513.   thisVars->unlockAddr1 = NO_UNLOCK_ADDR;
  514.   /* try different interleavings */
  515.   for (inlv = 4; inlv > 0; inlv >>= 1) {
  516.     if (inlv == 1)
  517.       flSetWindowBusWidth(vol.socket,8); /* use 8-bits */
  518.     vol.interleaving = inlv;
  519.     flIntelIdentify(&vol, amdCommand,0);
  520.     if (vol.type == Am29F016_FLASH ||
  521. vol.type == Fuj29F016_FLASH ||
  522. vol.type == Am29F016C_FLASH ||
  523. vol.type == Fuj29F016C_FLASH ||
  524. vol.type == Am29F080_FLASH ||
  525. vol.type == Fuj29F080_FLASH ||
  526. vol.type == Am29LV080_FLASH ||
  527. vol.type == Fuj29LV080_FLASH ||
  528. vol.type == Am29LV008_FLASH ||
  529. vol.type == Fuj29LV008_FLASH ||
  530. vol.type == Am29F040_FLASH ||
  531. vol.type == Fuj29F040_FLASH ||
  532. vol.type == Am29LV017_FLASH ||
  533. vol.type == Fuj29LV017_FLASH)
  534.       break;
  535.   }
  536.   if (vol.type == Am29F016_FLASH ||
  537.       vol.type == Fuj29F016_FLASH ||
  538.       vol.type == Am29F016C_FLASH ||
  539.       vol.type == Fuj29F016C_FLASH ||
  540.       vol.type == Am29LV017_FLASH ||
  541.       vol.type == Fuj29LV017_FLASH)
  542.     vol.chipSize = 0x200000l;
  543.   else if (vol.type == Fuj29F080_FLASH ||
  544.    vol.type == Am29F080_FLASH ||
  545.    vol.type == Fuj29LV080_FLASH ||
  546.    vol.type == Am29LV080_FLASH ||
  547.    vol.type == Fuj29LV008_FLASH ||
  548.    vol.type == Am29LV008_FLASH)
  549.     vol.chipSize = 0x100000l;
  550.   else if (vol.type == Fuj29F040_FLASH ||
  551.    vol.type == Am29F040_FLASH)
  552.     vol.chipSize = 0x80000l;
  553.   else {
  554.   #ifdef DEBUG_PRINT
  555.     DEBUG_PRINT("Debug: did not identify AMD or Fujitsu flash media.n");
  556.   #endif
  557.     return flUnknownMedia;
  558.   }
  559.   if ((vol.type == Am29F016C_FLASH) || (vol.type == Fuj29F016C_FLASH)) {
  560.     thisVars->unlockAddr1 = thisVars->unlockAddr2 = 0L;
  561.     thisVars->baseMask = 0xfffff800L * vol.interleaving;
  562.   }
  563.   else if ((vol.type == Am29F040_FLASH) || (vol.type == Fuj29F040_FLASH)){
  564.     flSetWindowSize(vol.socket,8 * vol.interleaving);
  565.     thisVars->unlockAddr1 = 0x5555u * vol.interleaving;
  566.     thisVars->unlockAddr2 = 0x2aaau * vol.interleaving;
  567.     thisVars->baseMask = 0xffff8000L * vol.interleaving;
  568.   }
  569.   else {
  570.     thisVars->unlockAddr1 = 0x555 * vol.interleaving;
  571.     thisVars->unlockAddr2 = 0x2aa * vol.interleaving;
  572.     thisVars->baseMask = 0xfffff800L * vol.interleaving;
  573.   }
  574.   checkStatus(flIntelSize(&vol,amdCommand,0));
  575.   vol.erasableBlockSize = 0x10000l * vol.interleaving;
  576.   vol.flags |= SUSPEND_FOR_WRITE;
  577.   /* Register our flash handlers */
  578.   vol.write = amdMTDWrite;
  579.   vol.erase = amdMTDErase;
  580. #ifdef DEBUG_PRINT
  581.   DEBUG_PRINT("Debug: Identified AMD or Fujitsu flash media.n");
  582. #endif
  583.   return flOK;
  584. }
  585. #if FALSE
  586. /*----------------------------------------------------------------------*/
  587. /*                   f l R e g i s t e r A M D M T D */
  588. /* */
  589. /* Registers this MTD for use */
  590. /* */
  591. /* Parameters:                                                          */
  592. /* None */
  593. /*                                                                      */
  594. /* Returns: */
  595. /* FLStatus : 0 on success, otherwise failure */
  596. /*----------------------------------------------------------------------*/
  597. FLStatus flRegisterAMDMTD(void)
  598. {
  599.   if (noOfMTDs >= MTDS)
  600.     return flTooManyComponents;
  601.   mtdTable[noOfMTDs++] = amdMTDIdentify;
  602.   return flOK;
  603. }
  604. #endif /* FALSE */