📄 saftl.c
字号:
/* Dismount without saving quick mount information */
static void cleanUnmount(Cnand * volPrmPtr)
{
volPrmPtr->fIsQuickMountValid = TRUE; /* Prevent quick mount from being stored */
dismountSAFTL(volPrmPtr);
}
/*********************************************************************/
/*********************************************************************/
/*** ***/
/*** Q u i c k M o u n t R e l a t e d R o u t i n e s ***/
/*** ***/
/*********************************************************************/
/*********************************************************************/
#ifndef FL_READ_ONLY
/*----------------------------------------------------------------------*/
/* p r i v a t e D i s c a r d Q u i c k M o u n t I n f o */
/* */
/* Mark quick mount information as none valid. */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* wFirstUnit : First unit of the partition */
/* wFirstQuickMountUnit : First quick mount unit of the partition */
/* MTDFlags : MTD flags to use */
/* */
/* Returns: */
/* FLStatus : flOK on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus privateDiscardQuickMountInfo(Cnand *volPrmPtr,
FLWord wFirstUnit,
FLWord wFirstQuickMountUnit,
FLWord wNoOfQuickMountUnits,
FLDword dwMTDFlags)
{
FLFlash * flashPtr = volPrmPtr->flash;
FLWord wIdx;
FLWord wLimit = wFirstUnit - wFirstQuickMountUnit;
FLStatus status;
FLByte bNoOfSkippedUnits = 0;
if((volPrmPtr->volumeFlags & SAFTL_QUICK_MOUNT) == 0)
return flOK;
/* Find the first good unit of the partition */
volPrmPtr->remapped = TRUE;
flashPtr->args.startUnit = wFirstQuickMountUnit;
flashPtr->args.noOfUnits = wLimit; /* Ori - Assuming this is bigger then the quick mount */
flashPtr->args.readMainBuf = (FLByte FAR1 *)saftlBuffer;
if(wLimit > FL_SECTOR_SIZE)
{
DBG_PRINT_ERR(FLZONE_TL,"ERROR: Quick mount area is too big.\r\n");
return flGeneralFailure;
}
status = flashPtr->readBBT(flashPtr);
if(status != flOK)
{
DBG_PRINT_ERR(FLZONE_TL,"ERROR: Failed reading Bad Blocks Table for quick mount.\r\n");
return status;
}
for(wIdx = 0 ; (wIdx < wLimit) && (wNoOfQuickMountUnits > 0);
wIdx++)
{
switch(saftlBuffer[wIdx])
{
case BBT_GOOD_UNIT :
if(bNoOfSkippedUnits!=0) /* Skip media header */
{
bNoOfSkippedUnits--;
break;
}
wNoOfQuickMountUnits--;
flashPtr->args.startUnit = wFirstQuickMountUnit + wIdx;
flashPtr->args.noOfUnits = 1;
flashPtr->args.opFlags = (dwMTDFlags & ~ MTD_NO_MATCHING) | MTD_ADD_ERASE_COUNT;
status = flashPtr->flashErase(flashPtr);
if(status != flOK)
{
DBG_PRINT_ERR(FLZONE_TL,"ERROR: Failed erasing quick mount block.\r\n");
return status;
}
case BBT_BAD_UNIT :
break;
default : /* BBT_UNAVAIL_UNIT */
bNoOfSkippedUnits = flashPtr->args.noOfSkippedUnits;
break;
} /* End switch of block type */
} /* End - loop over quick mount units */
return status;
}
/*----------------------------------------------------------------------*/
/* d i s c a r d Q u i c k M o u n t I n f o */
/* */
/* Mark quick mount information as none valid. */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : flOK on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus discardQuickMountInfo(Cnand *volPrmPtr)
{
FLStatus status;
if((volPrmPtr->volumeFlags & SAFTL_QUICK_MOUNT) == 0)
return flOK;
status = privateDiscardQuickMountInfo(volPrmPtr,volPrmPtr->firstUnit,
volPrmPtr->firstQuickMountUnit,
volPrmPtr->noOfQuickMountUnits,
volPrmPtr->MTDFlags);
if(status == flOK)
volPrmPtr->fIsQuickMountValid = FALSE;
return status;
}
#endif /* FL_READ_ONLY */
#ifndef FL_NO_QUICK_MOUNT_FEATURE
/*----------------------------------------------------------------------*/
/* l o a d Q u i c k M o u n t T o B u f f e r */
/* */
/* Load the quick mount information from the flash to a RAM table. */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* volPrmPtr->flash->args.startSector : flash address to read from */
/* bufPtr : Pointer to read the data to */
/* dwSize : Size to read in bytes */
/* */
/* Returns: */
/* flOK if the data was successfully loaded. */
/* Any other value for failure. */
/*----------------------------------------------------------------------*/
static FLStatus loadQuickMountToBuffer(Cnand * volPrmPtr,
FLByte FAR1 * bufPtr,
FLDword dwSize)
{
FLFlash * flashPtr = volPrmPtr->flash;
FLDword dwEndAddress = flashPtr->args.startSector +
((dwSize+FL_SECTOR_MASK)>>FL_SECTOR_SIZE_BITS);
FLDword dwUnitSectorMask = (1L << volPrmPtr->sectorsInUnitBits) - 1;
FLDword dwUnitOffset;
FLDword dwNoneFullSector = (dwSize & FL_SECTOR_MASK) ? dwEndAddress - 1 :
SAFTL_INVALID_SECTOR_NO;
FLByte bNoOfSkippedUnits = 0;
flashPtr->args.readMainBuf = bufPtr;
while(flashPtr->args.startSector < dwEndAddress)
{
if((flashPtr->args.startSector & dwUnitSectorMask) == 0)
{
/* Find next good block */
dwUnitOffset = (flashPtr->args.startSector >> volPrmPtr->sectorsInUnitBits) -
volPrmPtr->firstQuickMountUnit;
while ((saftlBuffer[dwUnitOffset] != BBT_GOOD_UNIT) ||
(bNoOfSkippedUnits != 0 ) )
{
switch(saftlBuffer[dwUnitOffset])
{
case BBT_UNAVAIL_UNIT:
bNoOfSkippedUnits = flashPtr->args.noOfSkippedUnits;
/* No break */
case BBT_BAD_UNIT:
break;
default: /* BBT_GOOD_UNIT */
bNoOfSkippedUnits--;
break;
}
if(dwUnitOffset >= FL_SECTOR_SIZE)
return flGeneralFailure;
dwEndAddress += volPrmPtr->sectorsInUnit;
dwNoneFullSector += volPrmPtr->sectorsInUnit;
dwUnitOffset++;
}
flashPtr->args.startSector = (dwUnitOffset + (FLDword)volPrmPtr->firstQuickMountUnit)
<< volPrmPtr->sectorsInUnitBits;
}
/* Read the data */
if(flashPtr->args.startSector == dwNoneFullSector)
{
/* Last 512 bytes might not fit into the buffer */
bufPtr = flashPtr->args.readMainBuf;
flashPtr->args.readMainBuf = volPrmPtr->foldingBuffer;
checkStatus(flashPtr->flashRead(flashPtr));
tffscpy(bufPtr,volPrmPtr->foldingBuffer,(dwSize & FL_SECTOR_MASK));
}
else /* A full 512 bytes of data - can be read directly to the buffer */
{
checkStatus(flashPtr->flashRead(flashPtr));
flashPtr->args.readMainBuf = BYTE_ADD_FAR(flashPtr->args.readMainBuf,FL_SECTOR_SIZE);
}
flashPtr->args.startSector++;
} /* End loop over give buffer */
return flOK;
}
/*----------------------------------------------------------------------*/
/* c h e c k A n d L o a d Q u i c k M o u n t I n f o */
/* */
/* Check and report the quick mount information validity. The routine */
/* also loads that data in case it is valid into the RAM tables. */
/* */
/* Notes */
/* The routine uses both saftlBuffer + 1KB of volPrmPtr->foldingBuffer */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* */
/* Returns: */
/* TRUE if the data was successfully loaded. */
/* FALSE on failing to load the quick mount information. */
/*----------------------------------------------------------------------*/
static FLBoolean checkAndLoadQuickMountInfo(Cnand *volPrmPtr,FLBoolean fCheckOnly)
{
FLFlash * flashPtr = volPrmPtr->flash;
CNANDQuickMountInfo FAR1 * info;
FLWord wIdx;
FLStatus status;
FLWord wMaxBBT = (FLWord)TFFSMIN(volPrmPtr->noOfUnits,FL_SECTOR_SIZE);
FLByte FAR1 * bSavedCnandPtr =
BYTE_ADD_FAR(volPrmPtr->foldingBuffer, FL_SECTOR_SIZE);
if((volPrmPtr->volumeFlags & SAFTL_QUICK_MOUNT) == 0 )
return FALSE;
/* Find the first good unit of the partition */
volPrmPtr->remapped = TRUE;
flashPtr->args.startUnit = volPrmPtr->firstQuickMountUnit;
flashPtr->args.noOfUnits = wMaxBBT; /* Ori - Assuming this is bigger then the quick mount */
flashPtr->args.readMainBuf = (FLByte FAR1 *)saftlBuffer;
status = flashPtr->readBBT(flashPtr);
if(status != flOK)
{
DBG_PRINT_ERR(FLZONE_TL,"Debug: Failed reading Bad Blocks Table for quick mount.\r\n");
return FALSE;
}
/* Make sure there are not too many blocks in the quick mount area */
for(wIdx = 0 ; saftlBuffer[wIdx] != BBT_GOOD_UNIT ; wIdx++)
{
if(wIdx >= wMaxBBT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -