📄 inftl.c
字号:
discardQuickMountInfo(&vol);
#ifdef NFTL_CACHE
setSectorFlagsCache(&vol, addr, SECTOR_IGNORE);
#endif /* NFTL_CACHE */
vol.flash->write(vol.flash,addr+SECTOR_DATA_OFFSET,sectorFlags,sizeof(sectorFlags),EXTRA);
#ifdef MAKE_SURE_IGNORE_HAS_BAD_EDC
/* Force remapping of internal catched sector */
vol.flash->socket->remapped = TRUE;
/* Make sure EDC is wrong - a slite problem with PPP */
if(vol.flash->read(vol.flash,addr,inftlBuffer,sizeof(inftlBuffer),EDC)==flOK)
{
tffsset(inftlBuffer,0,sizeof(inftlBuffer));
vol.flash->write(vol.flash,addr,inftlBuffer,sizeof(inftlBuffer),0);
}
#if (defined(VERIFY_WRITE) || defined (VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
/* Now restore the ff's for the verifySectors routine */
tffsset(inftlBuffer,0xff,sizeof(inftlBuffer));
#endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
#endif /* MAKE_SURE_IGNORE_HAS_BAD_EDC */
}
#endif /* FL_READ_ONLY */
/*----------------------------------------------------------------------*/
/* v i r t u a l 2 P h y s i c a l */
/* */
/* Translate virtual sector number to physical address. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorNo : Virtual sector number */
/* startAddress : Physical address to start from */
/* lastOK : TRUE - the current sector in the last unit of */
/* virtual unit chain is free (not marked as */
/* deleted / ignored or used). */
/* */
/* Note: The first unit of the search is assumed to be valid. */
/* */
/* Returns: */
/* physical address of sectorNo */
/*----------------------------------------------------------------------*/
static CardAddress virtual2Physical(Bnand vol, SectorNo sectorNo,
CardAddress startAddress,FLBoolean* lastOK)
{
word unitOffset = (word)((sectorNo & vol.sectorsPerUnitMask) << SECTOR_SIZE_BITS);
ANANDUnitNo unitNo, virUnitNo;
ANANDUnitNo chainBound = 0;
CardAddress sectorAddress = ANAND_UNASSIGNED_ADDRESS;
byte sectorFlags = SECTOR_FREE;
/* follow the chain */
virUnitNo = (ANANDUnitNo)(sectorNo >> vol.sectorsPerUnitBits);
if (startAddress == ANAND_UNASSIGNED_ADDRESS)
{
/* Start from last unit in chain */
unitNo = vol.virtualUnits[virUnitNo];
}
else
{
/* Start from the unit that follows the given unit */
TL_DEBUG_PRINT(tl_out,"virtual2Physical : Virtual to physical started from middle of chain on unit %d\n",virUnitNo);
SET_EXIT(INFTL_FAILED_MOUNT);
unitNo = getPrevUnit(&vol,(ANANDUnitNo)((startAddress >> vol.unitSizeBits) - vol.firstUnit),virUnitNo);
if(unitNo == ANAND_BAD_CHAIN_UNIT)
return ANAND_BAD_CHAIN_ADDRESS;
}
for (;unitNo != ANAND_NO_UNIT;unitNo = getPrevUnit(&vol,unitNo,virUnitNo))
{
if((unitNo == ANAND_BAD_CHAIN_UNIT ) ||
(chainBound >= DOUBLE_MAX_UNIT_CHAIN) )
return ANAND_BAD_CHAIN_ADDRESS;
sectorAddress = unitBaseAddress(vol,unitNo) + unitOffset;
sectorFlags = getSectorFlags(&vol,sectorAddress);
/* Report if the last unit of the chain is used */
if ((unitNo == vol.virtualUnits[virUnitNo]) &&
(sectorFlags != SECTOR_FREE))
*lastOK = FALSE;
if((sectorFlags==SECTOR_FREE) || (sectorFlags==SECTOR_IGNORE))
{
chainBound++;
continue;
}
break;
}
if((sectorFlags==SECTOR_IGNORE)||(sectorFlags==SECTOR_FREE)||(sectorFlags==SECTOR_DELETED)) /* Sector was never written*/
return ANAND_UNASSIGNED_ADDRESS;
return sectorAddress;
}
/*----------------------------------------------------------------------*/
/* i n i t I N F T L b a s i c */
/* */
/* Initializes essential volume data */
/* */
/* Note : This routine is called both by the mount and format initINFTL */
/* and as a preparation for counting the number of partitions function. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* flash : Flash media mounted on this socket */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus initINFTLbasic(Bnand vol, FLFlash *flash)
{
dword noOfUnits; /* Keep this variable dword , for large DiskOnChips */
if (flash == NULL || !(flash->flags & INFTL_ENABLED))
{
DEBUG_PRINT(("\nDebug: media is not fit for INFTL format.\r\n"));
return flUnknownMedia;
}
if(flash->readBBT == NULL)
{
DEBUG_PRINT(("\nDEBUG : MTD read BBT routine was not initialized\r\n"));
return flFeatureNotSupported;
}
vol.flash = flash;
vol.erasableBlockSizeBits = flash->erasableBlockSizeBits;
vol.unitSizeBits = vol.erasableBlockSizeBits;
noOfUnits = (dword)((vol.flash->noOfChips * vol.flash->chipSize) >> vol.unitSizeBits);
/* Bound number of units to find room in 64 Kbytes Segment */
if((noOfUnits > MAX_UNIT_NUM) && (vol.unitSizeBits < MAX_UNIT_SIZE_BITS))
{
vol.unitSizeBits++;
noOfUnits >>= 1;
}
vol.blockMultiplierBits = vol.unitSizeBits - vol.erasableBlockSizeBits;
/* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
vol.buffer = flBufferOf(flSocketNoOf(vol.flash->socket));
#ifdef VERIFY_ERASED_SECTOR
vol.verifyBuffer = (dword *)flReadBackBufferOf(flSocketNoOf(flash->socket));
#endif /* VERIFY_ERASED_SECTOR */
flash->socket->remapped = TRUE;
return flOK;
}
/*----------------------------------------------------------------------*/
/* i n i t N F T L */
/* */
/* Initializes essential volume data as a preparation for mount or */
/* format. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* flash : Flash media mounted on this socket */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus initINFTL(Bnand vol, FLFlash *flash)
{
dword chipSize; /* Keep this variable dword , for large DiskOnChips */
FLStatus status;
if(flash!=NULL)
{
tffsset(&vol,0,sizeof(Bnand)); /* Clear Bnand volume */
vol.socketNo = (byte)flSocketNoOf(flash->socket); /* socket No */
}
status = initINFTLbasic(&vol, flash);
if(status != flOK)
return status;
chipSize = (dword)(flash->chipSize * flash->noOfChips);
#ifndef FL_MALLOC
if (chipSize > (dword)MAX_VOLUME_MBYTES << 20)
{
DEBUG_PRINT(("\nDebug: TrueFFS is customized for smaller media capacities.\r\n"));
return flGeneralFailure;
}
if (ASSUMED_NFTL_UNIT_SIZE > (1L<<vol.unitSizeBits))
{
DEBUG_PRINT(("\nDebug: TrueFFS is customized for smaller unit sizes.\r\n"));
return flGeneralFailure;
}
#endif /* FL_MALLOC */
vol.physicalUnits = NULL;
vol.virtualUnits = NULL;
#ifdef NFTL_CACHE
vol.ucache = NULL;
vol.scache = NULL;
#endif /* NFTL_CACHE */
vol.mappedSectorNo = UNASSIGNED_SECTOR;
vol.countsValid = 0; /* No units have a valid count yet */
vol.firstUnit = 0;
vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);
vol.sectorsPerUnitBits = vol.unitSizeBits - SECTOR_SIZE_BITS;
vol.sectorsPerUnitMask = vol.sectorsPerUnit - 1;
vol.noOfUnits = (ANANDUnitNo)(chipSize >> vol.unitSizeBits);
vol.firstMediaWrite = FALSE;
#if (defined(VERIFY_WRITE) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
vol.verifiedSectorNo = 0; /* Largest sector verified so far */
#endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
#ifdef CHECK_MOUNT
vol.debugState = 0;
#endif /* CHECK_MOUNT */
return flOK;
}
/*----------------------------------------------------------------------*/
/* i n i t T a b l e s */
/* */
/* Allocates and initializes the dynamic volume table, including the */
/* unit tables and secondary virtual map. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* ramForUnits : Number of bytes allocated to previous volumes */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
#ifdef FL_MALLOC
static FLStatus initTables(Bnand vol)
{
/* Allocate the conversion tables */
vol.physicalUnits = (ANANDPhysUnit FAR1*) FL_FAR_MALLOC(vol.noOfUnits * sizeof(ANANDPhysUnit));
if (vol.noOfVirtualUnits > 0)
vol.virtualUnits = (ANANDUnitNo FAR1*) FL_FAR_MALLOC(vol.noOfVirtualUnits * sizeof(ANANDUnitNo));
if ((vol.physicalUnits == NULL) ||
((vol.virtualUnits == NULL) && (vol.noOfVirtualUnits > 0)))
{
DEBUG_PRINT(("\nDebug: failed allocating conversion tables for INFTL.\r\n"));
return flNotEnoughMemory;
}
/* Allocate the multi-sector buffer (one per socket) */
if (++(multiSectorBufCounter[vol.socketNo]) == 0)
{
multiSectorBuf[vol.socketNo] = (byte *)FL_MALLOC(SECTOR_SIZE<<1);
if (multiSectorBuf[vol.socketNo] == NULL)
{
DEBUG_PRINT(("\nDebug: failed allocating multi-sector buffers for INFTL.\r\n"));
return flNotEnoughMemory;
}
}
return flOK;
}
#else
static FLStatus initTables(Bnand vol,dword ramForUnits)
{
char *heapPtr;
vol.heap = (char *)&socketHeap[flSocketNoOf(vol.flash->socket)][ramForUnits];
heapPtr = vol.heap;
vol.physicalUnits = (ANANDPhysUnit FAR1*) heapPtr;
heapPtr += vol.noOfUnits * sizeof(ANANDPhysUnit);
vol.virtualUnits = (ANANDUnitNo FAR1*) heapPtr;
heapPtr += vol.noOfVirtualUnits * sizeof(ANANDUnitNo);
if (( ((byte *)vol.heap + ANAND_HEAP_SIZE) < (byte *)heapPtr) ||
( ASSUMED_NFTL_UNIT_SIZE > (1L << vol.unitSizeBits) ) )
{
DEBUG_PRINT(("\nDebug: not enough memory for INFTL conversion tables.\r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -