📄 saftl.c
字号:
info->singleUnitListHead = (FLDword) volPrmPtr->singleUnitListHead;
info->singleUnitListTail = (FLDword) volPrmPtr->singleUnitListTail;
info->freeCacheUnitList = (FLDword) volPrmPtr->freeCacheUnitList;
info->alarm = (FLDword) volPrmPtr->wearLevel.alarm;
info->currUnit = (FLDword) volPrmPtr->wearLevel.currUnit;
info->eraseSum = (FLDword) volPrmPtr->eraseSum;
#ifndef TL_NO_STATISTICS
info->sectorsRead = volPrmPtr->sectorsRead;
info->sectorsWritten = volPrmPtr->sectorsWritten;
info->sectorsDeleted = volPrmPtr->sectorsDeleted;
info->parasiteWritesFromOldest = volPrmPtr->parasiteWritesFromOldest;
info->parasiteWritesFromNewest = volPrmPtr->parasiteWritesFromNewest;
info->unitsFoldedFromOldest = volPrmPtr->unitsFoldedFromOldest;
info->unitsFoldedFromNewest = volPrmPtr->unitsFoldedFromNewest;
#endif /* FL_NO_STATISTICS */
info->noOfUsedUnits = volPrmPtr->noOfUsedUnits;
/* Store unit cache */
status = storeQuickMountBuffer(volPrmPtr, (FLByte FAR1 *)volPrmPtr->CT ,endBufPtr,
wCachedUnits * sizeof(CNANDCache));
/* Store sector cache */
if(status == flOK)
status = storeQuickMountBuffer(volPrmPtr, (FLByte FAR1 *)volPrmPtr->sectors , endBufPtr,
(wCachedUnits << volPrmPtr->sectorsInUnitBits) *
sizeof(FLWord));
/* Store VUT table */
if(status == flOK)
status = storeQuickMountBuffer(volPrmPtr, (FLByte FAR1 *)volPrmPtr->VUT , endBufPtr,
volPrmPtr->noOfVirtualUnits * sizeof(FLWord));
/* Store CLT table */
if(status == flOK)
status = storeQuickMountBuffer(volPrmPtr, (FLByte FAR1 *)volPrmPtr->CLT , endBufPtr,
volPrmPtr->noOfUnits * sizeof(FLByte));
/* Store LUT table */
if(status == flOK)
status = storeQuickMountBuffer(volPrmPtr, (FLByte FAR1 *)volPrmPtr->LUT , endBufPtr,
volPrmPtr->noOfUnits * sizeof(FLWord));
/* Flush the last buffer to the flash */
if((status == flOK) && (flashPtr->args.writeMainBuf != volPrmPtr->foldingBuffer))
{
status = storeQuickMountBuffer(volPrmPtr, volPrmPtr->foldingBuffer , endBufPtr ,
volPrmPtr->minSectorsForFolding << FL_SECTOR_SIZE_BITS);
}
volPrmPtr->fIsQuickMountValid = TRUE;
return status;
}
#endif /* FL_READ_ONLY */
#endif /* FL_NO_QUICK_MOUNT_FEATURE */
/*********************************************************************/
/*********************************************************************/
/*** ***/
/*** C a c h e R e l a t e d R o u t i n e s ***/
/*** ***/
/*********************************************************************/
/*********************************************************************/
/*----------------------------------------------------------------------*/
/* a l l o c a t e C a c h e */
/* */
/* Allocate the unit and sector cache RAM table. */
/* */
/* Note : The number of units to cache is supplied by either of 2 ways: */
/* 1) FL_NUMBER_OF_CACHED_UNITS definition found in saftl.h */
/* 2) In case ENVIRONMENT_VARS is set the flCacheSize global */
/* may set the maximum size. The variable is an 2-D array */
/* [SOCKETS][PARTITION] */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* partitionNo : Current partition number */
/* */
/* Returns: */
/* FLStatus : */
/* flOK on success. */
/* flNotEnoughMemory if RAM tables can not be allocated. */
/* */
/* volPrmPtr->CT : Pointer to initialized unit cache table */
/* volPrmPtr->sectors : Pointer to main sector cache table */
/*----------------------------------------------------------------------*/
static FLStatus allocateCache(Cnand *volPrmPtr , FLByte partitionNo)
{
FLWord wUnitsToBeCached;
FLDword dwBytesForUnitSectors;
FLWord wRequeuestedUnits = (FLWord)FL_NUMBER_OF_CACHED_UNITS;
/******************************************/
/* Calculate the number of units to cache */
/******************************************/
wUnitsToBeCached = volPrmPtr->noOfVirtualUnits;
dwBytesForUnitSectors = volPrmPtr->sectorsInUnit * sizeof(FLWord);
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Enter allocateCache routine.\r\n");
/* Make sure the given number of cache units is not greater then required */
if(wRequeuestedUnits < wUnitsToBeCached)
{
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Not all units will be cached - (user defined a smaller value).\r\n");
wUnitsToBeCached = wRequeuestedUnits;
}
/* Make sure SAFTL can support that many cached units */
if(wUnitsToBeCached > MAX_CACHED_UNITS)
{
DBG_PRINT_WRN(FLZONE_TL,"Flow debug SAFTL : Not all units will be cached - (media too big).\r\n");
wUnitsToBeCached = MAX_CACHED_UNITS;
}
/* Make sure there are enough cache units */
if((wUnitsToBeCached < 1) && (volPrmPtr->noOfVirtualUnits != wUnitsToBeCached))
{
DBG_PRINT_ERR(FLZONE_TL,"ERROR - There must be at least 1 unit cached.\r\n");
return flNotEnoughMemory;
}
/* Store the number of cached units */
volPrmPtr->noOfCachedUnits = wUnitsToBeCached;
/*************************/
/* Allocate cache tables */
/*************************/
/* Unit cache table */
#ifdef FL_MALLOC
volPrmPtr->CT = (CNANDCache FAR1 *) FL_FAR_MALLOC((FLDword)wUnitsToBeCached * sizeof(CNANDCache));
if(volPrmPtr->CT == NULL)
{
DBG_PRINT_ERR(FLZONE_TL,"ERROR - Failed allocating unit cache tables for SAFTL.\r\n");
return flNotEnoughMemory;
}
#else
volPrmPtr->CT = &(flSAFTLUnitCache[volPrmPtr-vols][0]);
#endif /* FL_MALLOC */
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Unit cache was allocaed successfully.\r\n");
DBG_PRINT_FLOW_PRM(FLZONE_TL,(FLTXT("%lu bytes were allocated for %u units.\r\n"),(FLDword)((FLDword)wUnitsToBeCached * sizeof(CNANDCache)),wUnitsToBeCached));
/* Sector cache table */
#ifdef FL_MALLOC
volPrmPtr->sectors = (FLWord FAR1 *) FL_FAR_MALLOC(dwBytesForUnitSectors *
(FLDword)wUnitsToBeCached);
if(volPrmPtr->sectors == NULL)
{
DBG_PRINT_ERR(FLZONE_TL,"ERROR - Failed allocating sector cache tables for SAFTL.\r\n");
return flNotEnoughMemory;
}
#else
volPrmPtr->sectors = &flSAFTLSectorsTableSAFTL[volPrmPtr-vols][0];
#endif /* FL_MALLOC */
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Sector cache was allocaed successfully.\r\n");
DBG_PRINT_FLOW_PRM(FLZONE_TL,(FLTXT("%lu bytes were allocated for %u sectors per unit.\r\n"),(FLDword)(dwBytesForUnitSectors * (FLDword)wUnitsToBeCached),volPrmPtr->sectorsInUnit));
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Exit allocateCache routine.\r\n");
return flOK;
}
/*----------------------------------------------------------------------*/
/* i n i t C a c h e */
/* */
/* Initialize the unit and sector cache RAM table. */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* volPrmPtr->CT : Pointer to initialized unit cache table */
/* volPrmPtr->sectors : Pointer to main sector cache table */
/*----------------------------------------------------------------------*/
static void initCache(Cnand * volPrmPtr)
{
CNANDCache FAR1 * curCachePtr;
FLWord wIdx;
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Enter initCache routine.\r\n");
volPrmPtr->multiUnitListHead = SAFTL_UNUSED_UNIT;
volPrmPtr->singleUnitListHead = SAFTL_UNUSED_UNIT;
volPrmPtr->multiUnitListTail = SAFTL_UNUSED_UNIT;
volPrmPtr->singleUnitListTail = SAFTL_UNUSED_UNIT;
/* Initialize free cache entry queue - queues head and its links */
volPrmPtr->freeCacheUnitList = 0;
for(curCachePtr = volPrmPtr->CT , wIdx = 1 ;
wIdx < volPrmPtr->noOfCachedUnits ; curCachePtr++ , wIdx++)
{
curCachePtr->newerUnit = wIdx;
}
curCachePtr->newerUnit = SAFTL_UNUSED_UNIT;
DBG_PRINT_FLOW(FLZONE_TL,"Flow debug SAFTL : Exit initCache routine.\r\n");
}
/*----------------------------------------------------------------------*/
/* r e m o v e F r o m C a c h e */
/* */
/* Free a cache entry, while updating the cache queues. */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* cachePtr : Pointer to cache entry */
/* */
/*----------------------------------------------------------------------*/
static void removeFromCache(Cnand * volPrmPtr,CNANDCache FAR1 *cachePtr)
{
FLWord wCacheIndex = (FLWord)(cachePtr - volPrmPtr->CT);
/* No need to remove a unit twice */
if(cachePtr->VUN == SAFTL_UNUSED_UNIT)
return;
/* Replace pointer to cache with newest logical unit of the chain */
volPrmPtr->VUT[cachePtr->VUN] = cachePtr->LUN;
/* Update chain pointers */
if(cachePtr->newerUnit != SAFTL_UNUSED_UNIT)
volPrmPtr->CT[cachePtr->newerUnit].olderUnit = cachePtr->olderUnit;
if(cachePtr->olderUnit != SAFTL_UNUSED_UNIT)
volPrmPtr->CT[cachePtr->olderUnit].newerUnit = cachePtr->newerUnit;
/* Update chains head\tail */
if(volPrmPtr->multiUnitListHead == wCacheIndex)
volPrmPtr->multiUnitListHead = cachePtr->olderUnit;
if(volPrmPtr->multiUnitListTail == wCacheIndex)
volPrmPtr->multiUnitListTail = cachePtr->newerUnit;
if(volPrmPtr->singleUnitListHead == wCacheIndex)
volPrmPtr->singleUnitListHead = cachePtr->olderUnit;
if(volPrmPtr->singleUnitListTail == wCacheIndex)
volPrmPtr->singleUnitListTail = cachePtr->newerUnit;
/* Add cache entry to free cache entries queue */
cachePtr->newerUnit = volPrmPtr->freeCacheUnitList;
volPrmPtr->freeCacheUnitList = wCacheIndex;
/* Clear current cache entry */
cachePtr->LUN = SAFTL_UNUSED_UNIT;
cachePtr->VUN = SAFTL_UNUSED_UNIT;
}
/*----------------------------------------------------------------------*/
/* m o v e T o H e a d O f Q u e */
/* */
/* Return pointer to virtual unit cache entry while moving it to the */
/* head of the queue. */
/* */
/* Parameters: */
/* volPrmPtr : Pointer identifying drive */
/* wChainsLength : Chains Lengh */
/* wVirtualUnit : Virtual unit number */
/* */
/*----------------------------------------------------------------------*/
static CNANDCache FAR1 * moveToHeadOfqueue(Cnand * volPrmPtr,
FLWord wChainsLength,
FLWord wVirtualUnit)
{
FLWord wCacheIndex;
CNANDCache FAR1 * cachePtr;
/* Unit is already cached - get pointer to its cache entry */
wCacheIndex = GetCacheIndex(volPrmPtr,wVirtualUnit);
cachePtr = GetCachePtr(volPrmPtr,wCacheIndex);
/* Move cache entry to the head of the cache queue (LRU) */
if((wCacheIndex != volPrmPtr->multiUnitListHead) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -