⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nftllite.c

📁 DOC文件系统驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * $Log:   V:/Flite/archives/TrueFFS5/Src/NFTLLITE.C_V  $
 * 
 *    Rev 1.31   Jul 17 2002 17:41:38   oris
 * Bug fix - TL_LEAVE_SOME_BINARY_AREA did not function correctly.
 * 
 *    Rev 1.30   Jul 07 2002 09:09:30   oris
 * Bug fix - bad folding when both VERIFY_WRITE and VERIFY_SECTOR_ERASED were not defined.
 * Bug fix - bad handling of erase mark in the mount process.
 * Bug fix - bad unit on the last block of the media, and no progress call back , sometimes causes flWriteFault to be returned by the format routine.
 * Added support for FL_LEAVE_SOME_BINARY_AREA.
 * Added support for FL_REPORT_MOUNT_PROGRESS compilation flag.
 * 
 *    Rev 1.29   06 May 2002 19:12:30   andreyk
 * added 'static' to definition of routine verifySectors() 
 * 
 *    Rev 1.28   May 01 2002 19:04:14   oris
 * Removed warnings
 * 
 *    Rev 1.27   Apr 15 2002 07:38:22   oris
 * Added support for RAM based MTD power failure tests.
 * Remove cache allocation checks - They are not needed since the cache routine itself check for proper allocation.
 * Improved power failure resistant:
 *  - Added support for VERIFY_ERASED_SECTOR compilation flag - make sure a sector is free before writing it.
 *  - writeAndCheck() - 
 *    1) Added an option to verify that the sector is erased before writing. 
 *    It subject to the FL_UPS/FL_OFF/FL_ON modes of the flVerifyWrite environment variable.
 *    2) Added support for partition > 0.
 *  - getUnitData() - Bug fix - in case of invalid replacement unit if we are mounting or formatting store physical unit number in
 *    invalidReplacement field of the Anand record otherwise mark head of chain as frozen and not the unit itself.
 *  - Bug fix - Added logic to find end of endless loops - findEndOfEndlessLoop()
 *  - virtual2Physical() - Added call to findEndOfEndlessLoop() if needed and return address of next free sector (used verifySector()).
 *  - initNFTL() - Added initialization of TL verifyBuffer buffer and invalidReplacement fields.
 *  - Separated the search for a free unit in physical table from allocateUnit() into dedicated routine findFreeUnit().
 *  - foldUnit()
 *    1) Added support for partition > 0.
 *    2) Prevent a recursive call to foldUnit by changing allocateUnit() with findFreeUnit().
 *    3) Added logic for endless loops.
 *    4) Added check that last sector of chain can be used.
 *  - foldBestChain() - revised the entire routine
 *    1) If folding not in place was forced free all frozen units.
 *    2) Validate that a unit was actually freed.
 *  - mountUnit() -
 *    1) In case of bad virtual unit number format the unit . An invalid virtual unit might be a result of power failures.
 *  - allocateAndWrite() - Bug fix - sector count might be incorrectly updated in case folding found a sector with bad EDC.
 *  - mountNFTL -
 *    1) Moved badFormat initialization to the end of the routine so that getUnitData() might know if it was called by mount routine.
 *    2) Made sure there is at least 1 free unit.
 *    3) Fold chains with invalid pointer in their end of chain - caused by power failures.
 *  - Added MAKE_SURE_IGNORE_HAS_BAD_EDC compilation flag - make sure that the sector is really marked
 *  - verifySector() - was completely revised.
 * 
 *    Rev 1.26   Feb 19 2002 21:00:56   oris
 * Compilation errors - NO_READ_BBT_CODE
 * Removed warnings.
 * Replaced TL_LEAVE_BINARY_AREA with FL_LEAVE_BINARY_AREA
 * 
 *    Rev 1.25   Jan 29 2002 20:09:58   oris
 * Bug fix - if an invalid sector flag is found in getSectorFlags routine and read operation failed, SECTOR_IGNORED should have been returned.
 * 
 *    Rev 1.24   Jan 23 2002 23:33:56   oris
 * Improved markAsIgnored routine.
 * Changed DFORMAT_PRINT syntax.
 * 
 *    Rev 1.23   Jan 20 2002 20:29:26   oris
 * Remove warnings
 * Bug fix - Missing cache buffers allocation check in formatUnit.
 * 
 *    Rev 1.22   Jan 17 2002 23:04:22   oris
 * Added onesCount routine - number of bits in a byte.
 * Improved FL_READ_ONLY compilation mode.
 * Flash field of the TL was changed to a pointer.
 * Added check verifyVolume routine to issue a longer, but safer mount.
 * Moved RAM tables to far heap to allow BIOS driver to allocate far  memory heap even when compiled as tiny model:
 *  - InitTables : allocation was change from FL_MALLOC to FL_FAR_MALLOC.
 *  - mountUnit : changes pointer to virtual table to be FAR. 
 *  - mountNFTL : 
 *    - changes pointer to virtual table to be FAR.
 *    - allocation of cache tables was change from FL_MALLOC to  FL_FAR_MALLOC.
 *  - dismount : use FL_FAR_FREE instead of FL_FREE
 * formatUnit routine improved re-initialization of sector cache.
 * Changed flPolicy to be socket specific.
 * Added \r to all DEBUG_PRINT.
 * writeSector routine if this sector is the cached sector then force  re-mapping.
 * Bug fix in formatNFTL :
 *  - Add binary length to percentage of bad blocks.
 *  - Report error if there is not enough good blocks.
 *  - Report error if block 0 is bad.
 * New power failures protection algorithm
 *  - setUnitData : When verify write is on , no need to reread unit data
 *  - getSectorFlags : if flags is not valid (including SECTOR_IGNORE)  check EDC and bit distance instead of simple or.
 *  - virtual2Physical : Added endAddress parameter to allow retrieval of  not the newest sector.
 *  - writeAndCheck : 
 *    - Toggle socket verify write mode according to global verify write  mode.
 *    - Moved the marking of the sector as bad into a dedicated routine  (markAsIgnored)
 *  - initNftl : 
 *    - Init FLFlash pointer (and not structure) 
 *    - Init socket number of the TL
 *    - Init verifiedSectorNo for FL_OFF verify write mode
 *  - swapUnits : Catch failed folding operation
 *  - Moved copySector routine into foldUnit.
 *  - Changed chain bound for all chains "for loops" to the constant  DOUBLE_MAX_UNIT_CHAIN (support MAX_UNIT_CHAIN of 1 in case of folding  not in place).
 *  - foldUnit : 
 *    - When verify write is set to FL_OFF call verifySectors routine to  gradually scan the entire media
 *    - Force re-mapping of cached sector
 *    - Add force folding parameter
 *    - Toggle socket verify write mode according to verify write mode and  currently scanned sector number
 *    - Verify copied sector EDC even for last sector of chain (no need to  copy it) and if bad freeze chain and return flCanNotFold (unless forced  folding is issued)
 *    - In case of bad EDC use older sector.
 *    - In case write operation failed (could be partially written sector  that was discovered by verify write mode) freeze chain and return  flCanNotFold (unless forced folding is issued)
 *  - foldBestChain : if folding of the chosen unit failed, freeze and try  another unit MAX_FOLDING_TRIES times.
 *  - allocateUnit : free media space even if there is  a free unit  available 
 *  - mapSector : if sector has bad EDC read older sector until no sectors  were found or chain bound has been reached
 *  - allocateAndWriteSector : 
 *    - Catch failed folding operation.
 *    - Set curSectorWrite to current sector so that writeAndCheck routine  will be able to decide whether to verify this sector or not while in  FL_OFF verify mode.
 *  - deleteSectors : Catch failed folding operation.
 *  - mountNFTL : 
 *    - Set default verify write policy to FL_UPS.
 *    - Set checkVolme routine pointer.
 *  - Added checkVolume / checkFolding / verifySectors and markAsIgnored  routines. 
 *
 *    Rev 1.21   Nov 21 2001 11:38:04   oris
 * Changed FL_MARK_DELETE to FL_ON.
 *
 *    Rev 1.20   15 Nov 2001 16:28:24   dimitrys
 * Fix Big BDK partition with Bad Units problem in formatNFTL()
 *
 *    Rev 1.19   Sep 25 2001 15:39:58   oris
 * Removed warnings.
 *
 *    Rev 1.18   Jul 29 2001 18:48:50   oris
 * Bug fix - unit 0 of floors > 0 were not marked as bad blocks therefore future write operation might force the device into external eprom mode.
 *
 *    Rev 1.17   Jul 15 2001 20:45:26   oris
 * Changed DFORMAT_PRINT syntax to be similar to DEBUG_PRINT.
 *
 *    Rev 1.16   Jul 13 2001 01:08:38   oris
 * Removed EDC for media header.
 * Added dformat debug print for virgin media.
 *
 *    Rev 1.15   Jun 17 2001 16:39:12   oris
 * Improved documentation and remove warnings.
 *
 *    Rev 1.14   Jun 17 2001 08:17:34   oris
 * Removed warnings.
 * Changed erase routine to formatUnit.
 * Bug fix - original meida header was not written.
 * Added NO_READ_BBT_CODE compilation flag to reduce code size.
 *
 *    Rev 1.13   May 29 2001 23:12:28   oris
 * Added EDC check of the media header both in the mount and format routines.
 *
 *    Rev 1.12   May 16 2001 21:21:26   oris
 * Added EDC check for media header.
 * Added the FL_ prefix to the following defines: ON , OFF, MALLOC and FREE.
 * Changed wear level counter from 0xFF to 0xFFF0
 *
 *    Rev 1.11   May 06 2001 22:42:26   oris
 * Removed warnings.
 *
 *    Rev 1.10   May 01 2001 16:33:46   oris
 * Bug fix - readBBT routine returned used blocks as bad.
 *
 *    Rev 1.9   Apr 30 2001 18:03:30   oris
 * Bug fix - marking binary partition blocks of devices that use artifitial large erase blocks (units).
 * Added support for the flMarkDeleteOnFlash environment variable.
 *
 *    Rev 1.8   Apr 24 2001 17:10:14   oris
 * Bug fix - readBBT routine missing casting.
 *
 *    Rev 1.7   Apr 16 2001 13:56:46   oris
 * Removed warrnings.
 *
 *    Rev 1.6   Apr 09 2001 15:04:42   oris
 * End with an empty line.
 *
 *    Rev 1.5   Apr 01 2001 07:55:42   oris
 * copywrite notice.
 * changed SEPERATED to SEPARATED.
 * Changed SEPARATED_CASCADED ifdef to a runtime if.
 *
 *    Rev 1.3   Feb 14 2001 02:03:38   oris
 * Changed readBBT to return media size.
 *
 *    Rev 1.2   Feb 12 2001 12:10:56   oris
 * Moved SEPARATED cascaded to include more uneeded code.
 * Rewritten readBBT to support far pointers.
 *
 *    Rev 1.1   Feb 07 2001 17:46:26   oris
 * Added SEPARATED_CASCADED compilation flag
 *
 *    Rev 1.0   Feb 05 2001 12:24:18   oris
 * Initial revision.
 *
 */

/***********************************************************************************/
/*                        M-Systems Confidential                                   */
/*           Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001            */
/*                         All Rights Reserved                                     */
/***********************************************************************************/
/*                            NOTICE OF M-SYSTEMS OEM                              */
/*                           SOFTWARE LICENSE AGREEMENT                            */
/*                                                                                 */
/*      THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE                 */
/*      AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT           */
/*      FOR THE SPECIFIC TERMS AND CONDITIONS OF USE,                              */
/*      OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE:                               */
/*      E-MAIL = info@m-sys.com                                                    */
/***********************************************************************************/

#include "nftllite.h"
#include "nanddefs.h"

#ifndef FL_READ_ONLY
#if (defined(VERIFY_WRITE) || defined (VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
static FLStatus checkVolume(Anand vol);
static FLStatus verifySectors(Anand vol, dword sectorCount);
#endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
static void markAsIgnored(Anand vol,CardAddress addr);
static FLStatus foldBestChain(Anand vol, ANANDUnitNo *unitNo);
static FLStatus foldUnit(Anand vol, ANANDUnitNo virtualUnitNo, FLBoolean);
static FLStatus checkFolding(Anand vol, ANANDUnitNo virtualUnitNo);
static FLStatus allocateUnit(Anand vol, ANANDUnitNo *);
#endif /* FL_READ_ONLY */
static Anand vols[VOLUMES];

#ifdef NFTL_CACHE
/* translation table for Sector Flags cache */
static unsigned char scacheTable[4] = { SECTOR_DELETED, /* 0 */
                    SECTOR_IGNORE,  /* 1 */
                    SECTOR_USED,    /* 2 */
                    SECTOR_FREE };  /* 3 */
#endif /* NFTL_CACHE */
#ifdef FORMAT_VOLUME
byte ff[ANAND_SPARE_SIZE];
#endif /* FORMAT_VOLUME */

/*------------------------------------------------------*/
/*                o n e s C o u n t                     */
/*                                                      */
/*  counts number of bits that valued 1 in a given byte */
/*------------------------------------------------------*/

static byte onesCount(byte flag)
{
   byte counter;

   for (counter = 0; flag; flag >>= 1)
          if (flag & 1)
           counter++;

   return counter;
}


/*----------------------------------------------------------------------*/
/*                 u n i t B a s e A d d r e s s                        */
/*                                                                      */
/* Returns the physical address of a unit.                              */
/*                                                                      */
/* Parameters:                                                          */
/*    vol        : Pointer identifying drive                            */
/*    unitNo        : Physical unit number                              */
/*                                                                      */
/* Returns:                                                             */
/*    physical address of unitNo                                        */
/*----------------------------------------------------------------------*/

static CardAddress unitBaseAddress(Anand vol, ANANDUnitNo unitNo)
{
  return (CardAddress)unitNo << vol.unitSizeBits;
}


/*----------------------------------------------------------------------*/
/*                 g e t U n i t D a t a                                */
/*                                                                      */
/* Get virtual unit No. and replacement unit no. of a unit.             */
/*                                                                      */
/* Parameters:                                                          */
/*    vol               : Pointer identifying drive                     */
/*    unitNo            : Physical unit number                          */
/*    virtualUnitNo     : Receives the virtual unit no.                 */
/*    replacementUnitNo : Receives the replacement unit no.             */
/*                                                                      */
/*----------------------------------------------------------------------*/

static void getUnitData(Anand vol,
            ANANDUnitNo unitNo,
            ANANDUnitNo *virtualUnitNo,
            ANANDUnitNo *replacementUnitNo)
{
  ANANDUnitHeader unitData;

#ifdef NFTL_CACHE
  /* check ANANDUnitHeader cache first */
  if (vol.ucache != NULL) {
      /* on cache miss read ANANDUnitHeader from flash and re-fill cache */
      if((vol.ucache[unitNo].virtualUnitNo == 0xDEAD) &&
      (vol.ucache[unitNo].replacementUnitNo == 0xDEAD)) {
          vol.flash->read(vol.flash,
                     unitBaseAddress(&vol,unitNo) + UNIT_DATA_OFFSET,
                 &unitData,
                 sizeof(ANANDUnitHeader),
                 EXTRA);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -