📄 nftllite.c.bak
字号:
// for (offset = 0; offset < (1UL << vol.unitSizeBits); offset += 8*SECTOR_SIZE)
// {
// readData=vol.flash.map(&vol.flash,
// unitBaseAddress(&vol,unitNo) + offset,
// 4*SECTOR_SIZE);
// for(iLength=0;iLength<4*SECTOR_SIZE;iLength++)
// {
// if( *(readData+iLength) != 0xff)
// {
// return FALSE;
// }
// }
// }
return TRUE;
}
//2007-7-16 16:22
/*----------------------------------------------------------------------*/
/* 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 */
/* */
/* 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));//初始化硬件参数
//2007-7-16 10:08 全部格式化 因此不需要一开始检查
/* 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;
// }
//2007-7-16 10:12 擦除
for (iUnit = 0; iUnit < vol.noOfUnits; iUnit++) {
vol.flash.erase(&vol.flash,iUnit,1);
}
vol.orgUnit = vol.noOfUnits;//为了满足后面vol.orgUnit >= vol.noOfUnits
//2007-7-16 10:09
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -