?? nftllite.c
字號:
else
vol.mappedSector = vol.flash.map(&vol.flash,vol.mappedSectorAddress,SECTOR_SIZE);
}
vol.mappedSectorNo = sectorNo;
vol.flash.socket->remapped = FALSE;
}
if (physAddress)
*physAddress = vol.mappedSectorAddress;
return vol.mappedSector;
}
/* Mounting and formatting */
#define UNIT_ORPHAN 0x10
/*----------------------------------------------------------------------*/
/* m o u n t U n i t */
/* */
/* Mount one unit. Read the relevant data from the unit header and */
/* update the conversion tables. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : Unit to mount */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus mountUnit(Anand vol, UnitNo unitNo)
{
UnitNo virtualUnitNo, replacementUnitNo;
unsigned short eraseMark;
unsigned long eraseCount;
PhysUnit *pU = &vol.physicalUnits[unitNo];
getUnitData(&vol,unitNo,&virtualUnitNo,&replacementUnitNo);
getUnitTailer(&vol,unitNo,&eraseMark,&eraseCount);
if (virtualUnitNo == NO_UNIT ||
eraseMark != ERASE_MARK) { /* this unit is not assigned */
*pU = UNIT_FREE;
}
else { /* this unit is assigned */
*pU &= UNIT_AVAILABLE | UNIT_ORPHAN;
if (replacementUnitNo < vol.noOfUnits) {
*pU |= UNIT_REPLACED;
if (vol.physicalUnits[replacementUnitNo] & (UNIT_AVAILABLE | UNIT_REPLACED))
/* Mark replacement unit as non-orphan */
vol.physicalUnits[replacementUnitNo] &= ~UNIT_ORPHAN;
}
if (!(virtualUnitNo & REPLACING_UNIT)) {
unsigned short foldMark;
UnitNo physUnitNo;
if (virtualUnitNo >= vol.noOfVirtualUnits)
return flBadFormat;
foldMark = getFoldMark(&vol,unitNo);
physUnitNo = vol.virtualUnits[virtualUnitNo];
if (foldMark == FOLDING_COMPLETE)
formatChain(&vol,unitNo);
else if (physUnitNo == NO_UNIT || !(vol.physicalUnits[physUnitNo] & UNIT_AVAILABLE)) {
/* If we have duplicates, it's OK if one of them is currently folded */
vol.virtualUnits[virtualUnitNo] = unitNo;
*pU &= ~UNIT_ORPHAN;
if (foldMark == FOLDING_IN_PROGRESS)
*pU &= ~UNIT_AVAILABLE;
if (physUnitNo != NO_UNIT)
formatChain(&vol,physUnitNo); /* Get rid of old chain */
}
else if (foldMark == FOLDING_IN_PROGRESS)
formatChain(&vol,unitNo);
else
return flBadFormat; /* We have a duplicate to a unit that */
/* is not currently folded. That's bad. */
}
}
return flOK;
}
/*----------------------------------------------------------------------*/
/* a l l o c a t e A n d W r i t e S e c t o r */
/* */
/* Write to sectorNo. if necessary, allocate a free sector first. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorNo : Virtual sector no. to write */
/* fromAddress : Address of sector data. */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus allocateAndWriteSector(Anand vol,
SectorNo sectorNo,
void FAR1 *fromAddress)
{
UnitNo virtualUnitNo = (UnitNo)(sectorNo / vol.sectorsPerUnit);
UnitNo firstUnitNo = vol.virtualUnits[virtualUnitNo];
UnitNo unitNo;
unsigned unitOffset = (sectorNo % vol.sectorsPerUnit) << SECTOR_SIZE_BITS;
unsigned unitChainLength = 1;
FLBoolean sectorExists = FALSE;
/* If we can't write to this unit, must fold it first */
if (firstUnitNo != NO_UNIT && !(vol.physicalUnits[firstUnitNo] & UNIT_AVAILABLE)) {
checkStatus(foldUnit(&vol,virtualUnitNo));
firstUnitNo = vol.virtualUnits[virtualUnitNo];
}
/* Find a unit to write this sector */
unitNo = firstUnitNo;
while (unitNo != NO_UNIT) {
unsigned char sectorFlags = getSectorFlags(&vol,unitBaseAddress(&vol,unitNo) + unitOffset);
if (sectorFlags == SECTOR_FREE)
break;
if (sectorFlags != SECTOR_IGNORE)
sectorExists = sectorFlags == SECTOR_USED;
unitNo = getNextUnit(&vol,unitNo);
unitChainLength++;
}
if (unitNo == NO_UNIT) {
if (unitChainLength >= MAX_UNIT_CHAIN)
checkStatus(foldUnit(&vol,virtualUnitNo));
checkStatus(allocateUnit(&vol,&unitNo));
checkStatus(assignUnit(&vol,unitNo,virtualUnitNo));
firstUnitNo = vol.virtualUnits[virtualUnitNo];
}
if (!(vol.physicalUnits[unitNo] & UNIT_AVAILABLE))
return flGeneralFailure;
checkStatus(writeAndCheck(&vol,unitBaseAddress(&vol,unitNo) + unitOffset,fromAddress,EDC));
if (vol.countsValid > virtualUnitNo) {
if (unitNo != firstUnitNo && !(vol.physicalUnits[unitNo] & UNIT_REPLACED)) {
if (~vol.physicalUnits[unitNo] & UNIT_COUNT) /* Increment block count */
vol.physicalUnits[unitNo]++;
else
return flGeneralFailure;
if (sectorExists) /* Decrement block count */
if (vol.physicalUnits[firstUnitNo] & UNIT_COUNT)
vol.physicalUnits[firstUnitNo]--;
else
return flGeneralFailure;
}
else if (!sectorExists) {
if (~vol.physicalUnits[firstUnitNo] & UNIT_COUNT) /* Increment block count */
vol.physicalUnits[firstUnitNo]++;
else
return flGeneralFailure;
}
}
return flOK;
}
/*----------------------------------------------------------------------*/
/* w r i t e S e c t o r */
/* */
/* Writes a sector. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorNo : Virtual sector no. to write */
/* fromAddress : Data to write */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus writeSector(Anand vol, SectorNo sectorNo, void FAR1 *fromAddress)
{
FLStatus status = flWriteFault;
int i;
if (vol.badFormat)
return flBadFormat;
if (sectorNo > vol.virtualSectors)
return flSectorNotFound;
vol.sectorsWritten++;
for (i = 0; i < 4 && status == flWriteFault; i++) {
if (vol.mappedSectorNo == sectorNo)
vol.mappedSectorNo = UNASSIGNED_SECTOR;
status = allocateAndWriteSector(&vol,sectorNo,fromAddress);
}
return status;
}
/*----------------------------------------------------------------------*/
/* d e l e t e S e c t o r */
/* */
/* Marks contiguous sectors as deleted. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorNo : First sector no. to delete */
/* noOfSectors : No. of sectors to delete */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus deleteSector(Anand vol, SectorNo sectorNo, int noOfSectors)
{
int iSector;
if (vol.badFormat)
return flBadFormat;
if (sectorNo + noOfSectors > vol.virtualSectors)
return flSectorNotFound;
for (iSector = 0; iSector < noOfSectors; iSector++, sectorNo++,
vol.sectorsDeleted++) {
CardAddress sectorAddress = virtual2Physical(&vol,sectorNo);
if (sectorAddress != UNASSIGNED_ADDRESS) {
unsigned char sectorFlags[2];
UnitNo currUnitNo;
/* Check that the unit is writable, and if not, fold it first */
UnitNo virtualUnitNo = (UnitNo)(sectorNo / vol.sectorsPerUnit);
UnitNo unitNo = vol.virtualUnits[virtualUnitNo];
if (!(vol.physicalUnits[unitNo] & UNIT_AVAILABLE)){
checkStatus(foldUnit(&vol,virtualUnitNo));
sectorAddress = virtual2Physical(&vol,sectorNo);
}
/* Mark sector deleted */
sectorFlags[0] = sectorFlags[1] = SECTOR_DELETED;
vol.flash.write(&vol.flash,
sectorAddress + SECTOR_DATA_OFFSET,
§orFlags,
sizeof sectorFlags,
EXTRA);
currUnitNo = (UnitNo)(sectorAddress >> vol.unitSizeBits);
if (vol.physicalUnits[currUnitNo] & UNIT_REPLACED)
currUnitNo = vol.virtualUnits[virtualUnitNo];
if (vol.countsValid > virtualUnitNo)
if (vol.physicalUnits[currUnitNo] & UNIT_COUNT)
vol.physicalUnits[currUnitNo]--; /* Decrement block count */
else
return flGeneralFailure;
}
}
return flOK;
}
/*----------------------------------------------------------------------*/
/* t l S e t B u s y */
/* */
/* Notifies the start and end of a file-system operation. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* state : ON (1) = operation entry */
/* OFF(0) = operation exit */
/* */
/*----------------------------------------------------------------------*/
static void tlSetBusy(Anand vol, FLBoolean state)
{
}
#if defined(DEFRAGMENT_VOLUME) || defined(SINGLE_BUFFER)
/*----------------------------------------------------------------------*/
/* d e f r a g m e n t */
/* */
/* Performs unit allocations to arrange a minimum number of writable */
/* sectors. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* sectorsNeeded : Minimum required sectors */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus defragment(Anand vol, long FAR2 *sectorsNeeded)
{
UnitNo dummyUnitNo, firstFreeUnit;
FLBoolean firstRound = TRUE;
while (vol.freeUnits * vol.sectorsPerUnit < *sectorsNeeded) {
if (vol.badFormat)
return flBadFormat;
checkStatus(allocateUnit(&vol,&dummyUnitNo));
if (firstRound) { /* remember the first free unit */
firstFreeUnit = dummyUnitNo;
firstRound = FALSE;
}
else if (firstFreeUnit == dummyUnitNo)
/* We have wrapped around, all the units that were marked as free
are now erased, and we still don't have enough space. */
checkStatus(foldBestChain(&vol,&dummyUnitNo)); /* make more free units */
}
*sectorsNeeded = vol.freeUnits * vol.sectorsPerUnit;
return flOK;
}
#endif
#ifdef FORMAT_VOLUME
/*----------------------------------------------------------------------*/
/* s e c t o r s I n V o l u m e */
/* */
/* Gets the total number of sectors in the volume */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* Number of sectors in the volume */
/*----------------------------------------------------------------------*/
static SectorNo sectorsInVolume(Anand vol)
{
return vol.virtualSectors;
}
/*----------------------------------------------------------------------*/
/* i s E r a s e d U n i t */
/* */
/* Check if a unit is erased. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* unitNo : unit to check */
/* */
/* Returns: */
/* TRUE if unit is erased, FALSE otherwise */
/*----------------------------------------------------------------------*/
static FLBoolean isErased(Anand vol, UnitNo unitNo)
{
CardAddress offset;
char ff[SECTOR_SIZE];
tffsset(ff,0xff,sizeof ff);
for (offset = 0; offset < (1UL << vol.unitSizeBits); offset += SECTOR_SIZE)
if (tffscmp(vol.flash.map(&vol.flash,
unitBaseAddress(&vol,unitNo) + offset,
SECTOR_SIZE),
ff,sizeof ff))
return FALSE;
return TRUE;
}
/*----------------------------------------------------------------------*/
/* f o r m a t N F T L */
/* */
/* Perform NFTL Format. */
/* */
/* Parameters: */
/* flash : Flash media to format */
/* formatParams : Address of FormatParams structure to use */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -