?? nftllite.c
字號:
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
/*static*/ FLStatus formatNFTL(FLFlash *flash, FormatParams FAR1 *formatParams)
{
Anand vol = &vols[flSocketNoOf(flash->socket)];
long int unitSize;
UnitNo iUnit, noOfBootUnits;
BootRecord bootRecord;
int noOfBadUnits = 0;
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: starting NFTL format.\n");
#endif
vol.flash = *flash;
checkStatus(initNFTL(&vol));
/* Find the medium boot record */
for (vol.orgUnit = 0; vol.orgUnit < vol.noOfUnits; vol.orgUnit++) {
vol.flash.read(&vol.flash,
unitBaseAddress(&vol,vol.orgUnit),
&bootRecord,
sizeof bootRecord,
0);
if (tffscmp(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId) == 0)
break;
}
noOfBootUnits = ((formatParams->bootImageLen - 1) >> vol.unitSizeBits) + 1;
if (vol.orgUnit < vol.noOfUnits) {
if (LE2(bootRecord.bootUnits) > noOfBootUnits )
noOfBootUnits = LE2(bootRecord.bootUnits) ;
}
vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1;
vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);
vol.noOfTransferUnits = formatParams->noOfSpareUnits;
vol.noOfTransferUnits += (long)(vol.noOfUnits - vol.bootUnits) *
(100 - formatParams->percentUse) / 100;
if (vol.noOfUnits <= vol.bootUnits + vol.noOfTransferUnits)
return flVolumeTooSmall;
unitSize = 1L << vol.unitSizeBits;
vol.noOfVirtualUnits = vol.noOfUnits-vol.bootUnits;
checkStatus(initTables(&vol));
for (iUnit = 0; iUnit < (vol.noOfUnits-vol.bootUnits); iUnit++)
vol.virtualUnits[iUnit] = NO_UNIT;
if (vol.orgUnit >= vol.noOfUnits) {
/* no boot record - virgin card, scan it for bad blocks */
/* Find a place for the boot record */
for (vol.orgUnit = vol.bootUnits; vol.orgUnit < vol.noOfUnits; vol.orgUnit++)
if (isErased(&vol,vol.orgUnit))
break;
if (vol.orgUnit >= vol.noOfUnits)
return flVolumeTooSmall;
/* Generate the bad unit table */
/* if a unit is not erased it is marked as bad */
for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++)
vol.physicalUnits[iUnit] = isErased(&vol,iUnit) ? UNIT_FREE : UNIT_BAD_ORIGINAL;
}
else { /* Read bad unit table from boot record */
checkStatus(vol.flash.read(&vol.flash,
unitBaseAddress(&vol,vol.orgUnit) + SECTOR_SIZE,
vol.physicalUnits,
vol.noOfUnits * sizeof(PhysUnit),
EDC));
}
/* count bad units */
vol.noOfTransferUnits += 2; /* include orgUnit & spareOrgUnit */
/* extend bootimage area if there are bad units in it */
for( iUnit = vol.bootUnits = 0;
(vol.bootUnits < noOfBootUnits) && (iUnit < vol.noOfUnits);
iUnit++ )
if( vol.physicalUnits[iUnit] & UNIT_AVAILABLE )
vol.bootUnits++;
if (vol.bootUnits < noOfBootUnits)
return flVolumeTooSmall;
vol.bootUnits = iUnit;
if (vol.noOfUnits <= vol.bootUnits + vol.noOfTransferUnits)
return flVolumeTooSmall;
/* Discount transfer units taken by the boot image */
for (iUnit = 0; iUnit < vol.bootUnits; iUnit++)
if (!(vol.physicalUnits[iUnit] & UNIT_AVAILABLE))
vol.noOfTransferUnits--;
vol.virtualSectors = (vol.noOfUnits - vol.bootUnits - vol.noOfTransferUnits) *
(unitSize / SECTOR_SIZE);
vol.noOfVirtualUnits = (unsigned short)((vol.virtualSectors + vol.sectorsPerUnit - 1) / vol.sectorsPerUnit);
/* Find a place for the boot records and protect them */
/* NOTE : We don't erase the old orgUnits, this might cause a problem
when formatting with bootImageLen = 0 and then formatting with
bootImageLen = 44Kbyte */
for (vol.orgUnit = vol.bootUnits; vol.orgUnit < vol.noOfUnits; vol.orgUnit++)
if (vol.physicalUnits[vol.orgUnit] == UNIT_FREE)
break;
vol.physicalUnits[vol.orgUnit] &= ~UNIT_AVAILABLE;
for (vol.spareOrgUnit = vol.orgUnit + 1;
vol.spareOrgUnit < vol.noOfUnits;
vol.spareOrgUnit++)
if (vol.physicalUnits[vol.spareOrgUnit] == UNIT_FREE)
break;
vol.physicalUnits[vol.spareOrgUnit] &= ~UNIT_AVAILABLE;
for (iUnit = vol.bootUnits; iUnit < vol.noOfUnits; iUnit++) {
FLStatus status = formatUnit(&vol,iUnit);
if(status == flWriteFault) {
if ((iUnit != vol.orgUnit) && (iUnit != vol.spareOrgUnit)) {
noOfBadUnits++;
if (vol.physicalUnits[iUnit] != UNIT_BAD_ORIGINAL)
vol.physicalUnits[iUnit] = UNIT_BAD_ORIGINAL; /* Mark it bad in table */
if (noOfBadUnits >= vol.noOfTransferUnits)
return status;
}
}
else if (status != flOK)
return status;
if (formatParams->progressCallback)
checkStatus((*formatParams->progressCallback)
(vol.noOfUnits - vol.bootUnits,
(iUnit + 1) - vol.bootUnits));
}
/* Prepare the boot record header */
tffsset(&bootRecord,0xff,sizeof bootRecord);
toLE2(bootRecord.noOfUnits,vol.noOfUnits - vol.bootUnits);
toLE2(bootRecord.bootUnits,vol.bootUnits);
tffscpy(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId);
toUNAL4(bootRecord.virtualMediumSize,(CardAddress) vol.virtualSectors * SECTOR_SIZE);
/* Write boot records, spare unit first */
vol.physicalUnits[vol.orgUnit] = UNIT_FREE; /* Unprotect it */
vol.physicalUnits[vol.spareOrgUnit] = UNIT_FREE; /* Unprotect it */
checkStatus(formatUnit(&vol,vol.spareOrgUnit));
checkStatus(vol.flash.write(&vol.flash,
unitBaseAddress(&vol,vol.spareOrgUnit) + SECTOR_SIZE,
vol.physicalUnits,
vol.noOfUnits * sizeof(PhysUnit),
EDC));
checkStatus(vol.flash.write(&vol.flash,
unitBaseAddress(&vol,vol.spareOrgUnit),
&bootRecord,
sizeof bootRecord,
0));
checkStatus(formatUnit(&vol,vol.orgUnit));
checkStatus(vol.flash.write(&vol.flash,
unitBaseAddress(&vol,vol.orgUnit) + SECTOR_SIZE,
vol.physicalUnits,
vol.noOfUnits * sizeof(PhysUnit),
EDC));
checkStatus(vol.flash.write(&vol.flash,
unitBaseAddress(&vol,vol.orgUnit),
&bootRecord,
sizeof bootRecord,
0));
/* Protect the units we mustn't access */
for (iUnit = 0; iUnit < vol.bootUnits; iUnit++)
vol.physicalUnits[iUnit] &= ~UNIT_AVAILABLE;
vol.physicalUnits[vol.orgUnit] &= ~UNIT_AVAILABLE;
vol.physicalUnits[vol.spareOrgUnit] &= ~UNIT_AVAILABLE;
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: finished NFTL format.\n");
#endif
return flOK;
}
#endif
/*----------------------------------------------------------------------*/
/* d i s m o u n t N F T L */
/* */
/* Dismount NFTL volume */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/*----------------------------------------------------------------------*/
static void dismountNFTL(Anand vol)
{
#ifdef MALLOC_TFFS
FREE_TFFS(vol.physicalUnits);
FREE_TFFS(vol.virtualUnits);
#endif
}
/*----------------------------------------------------------------------*/
/* m o u n t N F T L */
/* */
/* Mount the volume. Initialize data structures and conversion tables */
/* */
/* Parameters: */
/* flash : Flash media to mount */
/* tl : Mounted translation layer on exit */
/* volForCallback : Pointer to FLFlash structure for power on */
/* callback routine. */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
/*static*/ FLStatus mountNFTL(FLFlash *flash, TL *tl, FLFlash **volForCallback)
{
Anand vol = &vols[flSocketNoOf(flash->socket)];
UnitNo iUnit;
BootRecord bootRecord;
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: starting NFTL mount.\n");
#endif
vol.flash = *flash;
*volForCallback = &vol.flash;
checkStatus(initNFTL(&vol));
/* Find the medium boot record */
for (vol.orgUnit = 0; vol.orgUnit < vol.noOfUnits; vol.orgUnit++) {
vol.flash.read(&vol.flash,
unitBaseAddress(&vol,vol.orgUnit),
&bootRecord,
sizeof bootRecord,
0);
if (tffscmp(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId) == 0)
break;
}
if (vol.orgUnit >= vol.noOfUnits) {
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: not NFTL format.\n");
#endif
return flUnknownMedia;
}
for (vol.spareOrgUnit = vol.orgUnit + 1;
vol.spareOrgUnit < vol.noOfUnits;
vol.spareOrgUnit++) {
BootRecord bootRecord;
vol.flash.read(&vol.flash,
unitBaseAddress(&vol,vol.spareOrgUnit),
&bootRecord,
sizeof bootRecord,
0);
if (tffscmp(bootRecord.bootRecordId,"ANAND",sizeof bootRecord.bootRecordId) == 0)
break;
}
if (vol.spareOrgUnit >= vol.noOfUnits)
vol.spareOrgUnit = NO_UNIT; /* Get media information from unit header */
vol.noOfUnits = LE2(bootRecord.noOfUnits);
vol.bootUnits = LE2(bootRecord.bootUnits);
vol.virtualSectors = UNAL4(bootRecord.virtualMediumSize) >> SECTOR_SIZE_BITS;
vol.noOfUnits += vol.bootUnits;
vol.unitOffsetMask = (1L << vol.unitSizeBits) - 1;
vol.sectorsPerUnit = 1 << (vol.unitSizeBits - SECTOR_SIZE_BITS);
vol.noOfVirtualUnits = (UnitNo)((vol.virtualSectors + vol.sectorsPerUnit - 1) / vol.sectorsPerUnit);
if ((vol.virtualSectors >> (vol.unitSizeBits - SECTOR_SIZE_BITS)) >
(unsigned long)(vol.noOfUnits - vol.bootUnits))
return flBadFormat;
checkStatus(initTables(&vol));
vol.badFormat = FALSE;
/* Read bad unit table from boot record */
checkStatus(vol.flash.read(&vol.flash,
unitBaseAddress(&vol,vol.orgUnit) + SECTOR_SIZE,
vol.physicalUnits,
vol.noOfUnits * sizeof(PhysUnit),
EDC));
/* Exclude boot-image units */
for (iUnit = 0; iUnit < vol.noOfVirtualUnits; iUnit++)
vol.virtualUnits[iUnit] = NO_UNIT;
/* Mount all units */
for (iUnit = 0 ; iUnit < vol.noOfUnits; iUnit++) {
/* Exclude protected units */
if (iUnit < vol.bootUnits || iUnit == vol.orgUnit || iUnit == vol.spareOrgUnit)
vol.physicalUnits[iUnit] &= ~UNIT_AVAILABLE;
if (vol.physicalUnits[iUnit] & UNIT_AVAILABLE)
checkStatus(mountUnit(&vol,iUnit));
}
/* Scan for orphan units, and count free units */
vol.freeUnits = 0;
for (iUnit = vol.bootUnits; iUnit < vol.noOfUnits; iUnit++) {
PhysUnit *pU = &vol.physicalUnits[iUnit];
if (*pU == (UNIT_AVAILABLE | UNIT_ORPHAN) ||
*pU == (UNIT_AVAILABLE | UNIT_REPLACED | UNIT_ORPHAN)) {
if (formatUnit(&vol,iUnit) == flOK) /* Get rid of orphan */
vol.freeUnits--; /* will count it later */
}
else if (*pU == (UNIT_FREE & ~UNIT_ORPHAN))
*pU = UNIT_FREE; /* Reference to free unit. That's OK */
if (*pU == UNIT_FREE)
vol.freeUnits++;
}
/* Initialize allocation rover */
vol.roverUnit = vol.bootUnits;
/* Initialize statistics */
vol.sectorsRead = vol.sectorsWritten = vol.sectorsDeleted = 0;
vol.parasiteWrites = vol.unitsFolded = 0;
tl->rec = &vol;
tl->mapSector = mapSector;
tl->writeSector = writeSector;
tl->deleteSector = deleteSector;
#if defined(DEFRAGMENT_VOLUME) || defined(SINGLE_BUFFER)
tl->defragment = defragment;
#endif
#ifdef FORMAT_VOLUME
tl->sectorsInVolume = sectorsInVolume;
#endif
tl->tlSetBusy = tlSetBusy;
tl->dismount = dismountNFTL;
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: finished NFTL mount.\n");
#endif
return flOK;
}
#if FLASE
/*----------------------------------------------------------------------*/
/* f l R e g i s t e r N F T L */
/* */
/* Register this translation layer */
/* */
/* Parameters: */
/* None */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failure */
/*----------------------------------------------------------------------*/
FLStatus flRegisterNFTL(void)
{
if (noOfTLs >= TLS)
return flTooManyComponents;
tlTable[noOfTLs].mountRoutine = mountNFTL;
#ifdef FORMAT_VOLUME
tlTable[noOfTLs].formatRoutine = formatNFTL;
#endif
noOfTLs++;
return flOK;
}
#endif /* FLASE */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -