📄 nftllite.c
字号:
/*
* $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 + -