📄 nftllite.c.bak
字号:
/*----------------------------------------------------------------------*/
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;
/*2007-7-24 8:34*/
//需要对unitoffset进行一下地址转换,nandflash一个page有4个sector
unitOffset = unitOffset + ( unitOffset / (SECTOR_SIZE*4) )*(SECTOR_SIZE*4);
/*2007-7-24 8:35*/
/* 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;
//2007-7-16 15:14
unsigned int SectorNoInPage = 0;
unsigned int PageBase = 0;
//2007-7-16 15:14
/* 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);
}
//2007-7-16 15:46
SectorNoInPage = ((sectorAddress)>>SECTOR_SIZE_BITS) % 4;
PageBase = sectorAddress&(~((SECTOR_SIZE<<3) - 1));
//2007-7-16 15:46
/* Mark sector deleted */
sectorFlags[0] = sectorFlags[1] = SECTOR_DELETED;
vol.flash.write(&vol.flash,
PageBase + SECTOR_DATA_OFFSET + SectorNoInPage*16,//2007-7-16 15:28 +SectorNoInPage*16
§orFlags,
sizeof sectorFlags,
EXTRA);
currUnitNo = (UnitNo)(sectorAddress >> (vol.unitSizeBits+1));//2007-7-30 10:54 +1
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;
//}
//2007-7-16 16:22
static FLBoolean isErased(Anand vol, UnitNo unitNo)
{
CardAddress offset;
unsigned char *readData;
unsigned int iLength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -