?? nftllite.c
字號:
unsigned char sectorFlags = getSectorFlags(&vol,sectorAddress);
if (sectorFlags == SECTOR_FREE)
break;
if (sectorFlags != SECTOR_IGNORE)
prevSectorAddress = sectorFlags != SECTOR_DELETED ? sectorAddress :
UNASSIGNED_ADDRESS;
}
return prevSectorAddress;
}
/*----------------------------------------------------------------------*/
/* g e t F o l d M a r k */
/* */
/* Get the fold mark a unit. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Physical unit number */
/* */
/* Returns: */
/* Return the OR of the two words in the fold mark area (the words */
/* should be identical) */
/*----------------------------------------------------------------------*/
static unsigned short getFoldMark(Anand vol, UnitNo unitNo)
{
unsigned short foldMark[2];
vol.flash.read(&vol.flash,
unitBaseAddress(&vol,unitNo) + FOLD_MARK_OFFSET,
&foldMark, sizeof foldMark,
EXTRA);
return foldMark[0] | foldMark[1];
}
/*----------------------------------------------------------------------*/
/* g e t U n i t T a i l e r */
/* */
/* Get the erase record of a unit. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Physical unit number */
/* eraseMark : Receives the erase mark of the unit */
/* eraseCount : Receives the erase count of the unit */
/* */
/*----------------------------------------------------------------------*/
static void getUnitTailer(Anand vol,
UnitNo unitNo,
unsigned short *eraseMark,
unsigned long *eraseCount)
{
UnitTailer unitTailer;
vol.flash.read(&vol.flash,
unitBaseAddress(&vol,unitNo) + UNIT_TAILER_OFFSET,
&unitTailer,
sizeof(UnitTailer),
EXTRA);
/* Mask out any 1 -> 0 bit faults by or'ing with spare data */
*eraseMark = LE2(unitTailer.eraseMark) | LE2(unitTailer.eraseMark1);
*eraseCount = LE4(unitTailer.eraseCount);
}
/*----------------------------------------------------------------------*/
/* s e t U n i t T a i l e r */
/* */
/* Set the erase record of a unit. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Physical unit number */
/* eraseMark : Erase mark to set */
/* eraseCount : Erase count to set */
/* */
/*----------------------------------------------------------------------*/
static FLStatus setUnitTailer(Anand vol,
UnitNo unitNo,
unsigned short eraseMark,
unsigned long eraseCount)
{
UnitTailer unitTailer;
toLE2(unitTailer.eraseMark,eraseMark);
toLE2(unitTailer.eraseMark1,eraseMark);
toLE4(unitTailer.eraseCount,eraseCount);
return vol.flash.write(&vol.flash,
unitBaseAddress(&vol,unitNo) + UNIT_TAILER_OFFSET,
&unitTailer,
sizeof(UnitTailer),
EXTRA);
}
/*----------------------------------------------------------------------*/
/* i n i t N F T L */
/* */
/* Initializes essential volume data as a preparation for mount or */
/* format. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus initNFTL(Anand vol)
{
long int size = 1;
if (!(vol.flash.flags & NFTL_ENABLED)) {
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: media is not fit for NFTL format.\n");
#endif
return flUnknownMedia;
}
vol.physicalUnits = NULL;
vol.virtualUnits = NULL;
for (vol.erasableBlockSizeBits = 0; size < vol.flash.erasableBlockSize;
vol.erasableBlockSizeBits++, size <<= 1);
vol.unitSizeBits = vol.erasableBlockSizeBits;
vol.noOfUnits = (unsigned short)((vol.flash.noOfChips * vol.flash.chipSize) >> vol.unitSizeBits);
/* Adjust unit size so header unit fits in one unit */
while (vol.noOfUnits * sizeof(PhysUnit) + SECTOR_SIZE > (1UL << vol.unitSizeBits)) {
vol.unitSizeBits++;
vol.noOfUnits >>= 1;
}
vol.badFormat = TRUE; /* until mount completes*/
vol.mappedSectorNo = UNASSIGNED_SECTOR;
/*get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
vol.buffer = flBufferOf(flSocketNoOf(vol.flash.socket));
vol.countsValid = 0; /* No units have a valid count yet */
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 */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus initTables(Anand vol)
{
/* Allocate the conversion tables */
#ifdef MALLOC_TFFS
vol.physicalUnits = (PhysUnit *) MALLOC_TFFS(vol.noOfUnits * sizeof(PhysUnit));
vol.virtualUnits = (UnitNo *) MALLOC_TFFS(vol.noOfVirtualUnits * sizeof(UnitNo));
if (vol.physicalUnits == NULL ||
vol.virtualUnits == NULL) {
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: failed allocating conversion tables for NFTL.\n");
#endif
return flNotEnoughMemory;
}
#else
char *heapPtr;
heapPtr = vol.heap;
vol.physicalUnits = (PhysUnit *) heapPtr;
heapPtr += vol.noOfUnits * sizeof(PhysUnit);
vol.virtualUnits = (UnitNo *) heapPtr;
heapPtr += vol.noOfVirtualUnits * sizeof(UnitNo);
if (heapPtr > vol.heap + sizeof vol.heap) {
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: not enough memory for NFTL conversion tables.\n");
#endif
return flNotEnoughMemory;
}
#endif
return flOK;
}
/*----------------------------------------------------------------------*/
/* m a r k U n i t B a d */
/* */
/* Mark a unit as bad in the conversion table and the bad units table. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Physical number of bad unit */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus markUnitBad(Anand vol, UnitNo unitNo)
{
unsigned short eraseMark;
unsigned long eraseCount;
vol.physicalUnits[unitNo] = UNIT_BAD_MARKED;
getUnitTailer(&vol,unitNo,&eraseMark,&eraseCount);
return setUnitTailer(&vol,unitNo,0,eraseCount);
}
/*----------------------------------------------------------------------*/
/* f o r m a t U n i t */
/* */
/* Format one unit. Erase the unit, and mark the physical units table. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Unit to format */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus formatUnit(Anand vol, UnitNo unitNo)
{
unsigned short eraseMark;
unsigned long eraseCount;
FLStatus status;
if (!(vol.physicalUnits[unitNo] & UNIT_AVAILABLE))
return flWriteFault;
if (vol.physicalUnits[unitNo] == UNIT_FREE)
vol.freeUnits--;
vol.physicalUnits[unitNo] &= ~UNIT_AVAILABLE;
getUnitTailer(&vol,unitNo,&eraseMark,&eraseCount);
status = vol.flash.erase(&vol.flash,
unitNo << (vol.unitSizeBits - vol.erasableBlockSizeBits),
1 << (vol.unitSizeBits - vol.erasableBlockSizeBits));
if (status != flOK) {
markUnitBad(&vol,unitNo); /* make sure unit format is not valid */
return status;
}
eraseCount++;
if (eraseCount == 0) /* was hex FF's */
eraseCount++;
checkStatus(setUnitTailer(&vol,unitNo,ERASE_MARK,eraseCount));
vol.physicalUnits[unitNo] = UNIT_FREE;
vol.freeUnits++;
return flOK;
}
/*----------------------------------------------------------------------*/
/* w r i t e A n d C h e c k */
/* */
/* Write one sector. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Physical address of the sector to write to */
/* fromAddress : Buffer of data to write */
/* flags : Write flags (ECC, overwrite etc.) */
/* */
/* Returns: */
/* Status : 0 on success, failed otherwise. */
/*----------------------------------------------------------------------*/
static FLStatus writeAndCheck(Anand vol,
CardAddress address,
void FAR1 *fromAddress,
unsigned flags)
{
FLStatus status = vol.flash.write(&vol.flash,address,fromAddress,SECTOR_SIZE,flags);
if (status == flWriteFault) { /* write failed, ignore this sector */
unsigned char sectorFlags[2];
sectorFlags[0] = sectorFlags[1] = SECTOR_IGNORE;
vol.flash.write(&vol.flash,address + SECTOR_DATA_OFFSET,sectorFlags,sizeof sectorFlags,EXTRA);
}
return status;
}
/*----------------------------------------------------------------------*/
/* c o p y S e c t o r */
/* */
/* Copy one sector to another. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sourceSectorAddress : Physical address of Sector to copy */
/* from. */
/* targetSectorAddress : Physical address of sector to copy */
/* to. */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise. */
/*----------------------------------------------------------------------*/
static FLStatus copySector(Anand vol,
CardAddress sourceSectorAddress,
CardAddress targetSectorAddress)
{
unsigned flags = EDC;
vol.flash.socket->remapped = TRUE;
if (vol.flash.read(&vol.flash,
sourceSectorAddress,
nftlBuffer,
SECTOR_SIZE,
EDC) == flDataError) {
/* If there is an uncorrectable ECC error, copy the data as is */
unsigned short sectorDataInfo[4];
vol.flash.read(&vol.flash,
sourceSectorAddress,
sectorDataInfo,
sizeof sectorDataInfo,
EXTRA);
checkStatus(vol.flash.write(&vol.flash,
sourceSectorAddress,
sectorDataInfo,
sizeof sectorDataInfo,
EXTRA));
flags &= ~EDC;
}
return writeAndCheck(&vol,targetSectorAddress,nftlBuffer,flags);
}
/*----------------------------------------------------------------------*/
/* l a s t I n C h a i n */
/* */
/* Find last unit in chain. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Start the search from this unit */
/* */
/* Returns: */
/* Physical unit number of the last unit in chain. */
/*----------------------------------------------------------------------*/
static UnitNo lastInChain(Anand vol, UnitNo unitNo)
{
UnitNo firstVirtualUnitNo, firstReplacementUnitNo;
UnitNo lastUnit = unitNo, nextUnitNo;;
getUnitData(&vol,unitNo,&firstVirtualUnitNo,&firstReplacementUnitNo);
nextUnitNo = firstReplacementUnitNo;
while (nextUnitNo < vol.noOfUnits) { /* Validate replacement unit no. */
UnitNo nextVirtualUnitNo, nextReplacementUnitNo;
getUnitData(&vol,nextUnitNo,&nextVirtualUnitNo,&nextReplacementUnitNo);
if (nextVirtualUnitNo !=
(firstVirtualUnitNo | REPLACING_UNIT))
break; /* Virtual unit no. not validated */
lastUnit = nextUnitNo;
nextUnitNo = nextReplacementUnitNo;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -