📄 nandfblk.c
字号:
Description:
flush the cache content
Input:
cacheNum - the cache number
Output:
0 flush ok
-1 flush failed
**************************************************************/
int NAND_FFS_flushCache(int cacheNum)
{
int targetBlock;
/**** added by chilong 01/24/2002 ****/
int i, j;
char bNeed2Erase = 0;
unsigned char *pData;
int offset;
int frameNO;
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_flushCache] cache = %d", cacheNum);
SprintStringLn(NAND_FFS_DebugString);
#endif
// check if the cache number is out of bound
if (cacheNum < 0 || cacheNum >= NAND_FFS_CACHE_BLOCK_NUM)
{
NAND_FFS_Errno = ERROR_INVALID_CACHE;
return -1;
}
targetBlock = NAND_FFS_CacheStatus[cacheNum]->block;
if (targetBlock == -1)
return 0; // unused cache block, no need to flush
if ((NAND_FFS_CacheStatus[cacheNum]->flag & NAND_FFS_DIRTY_BIT_MASK) == 0)
return 0; // block not dirty, no need to flush
if (NAND_FFS_checkBlock(targetBlock) == -1)
{
// errno set by NAND_FFS_checkBlock()
return -1; // invalid block
}
#ifdef NAND_FFS_CACHE_DEBUG
numFlush++;
#endif
/**** added by chilong 01/24/2002 ****/
// check if this block has been erased already
pData = NAND_FlashAccessBuffer2;
offset = (targetBlock + NAND_FFS_START_BLOCK) * NAND_FLASH_BLOCK_SIZE;
for (i = 0; i < NAND_LumpNum; i++)
{
sc_disableInt();
nfshReadFrame(offset, pData);
sc_enableInt();
// because sizeof(struct NAND_diskLump) is less than NFLASH_FRAME_SIZE
// after the first frame has been read, we'll know from the lump header
// whether or not this lump can programmed directly without being erased
if ( ((struct NAND_diskLump*)pData)->type != NAND_LUMP_TYPE_FREE)
{
bNeed2Erase = 1;
break;
}
offset += NAND_LUMP_SIZE;
pData += NAND_LUMP_SIZE;
}
/**** added by chilong 01/24/2002 ****/
// block is dirty, flush the cached block
if (bNeed2Erase)
{
// erase the flash block
if (NAND_FFS_eraseFlashBlock(targetBlock) == -1)
{
// flash erase error
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " erase failed! block = %d", targetBlock);
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_eraseFlashBlock()
return -1;
}
}
/* marked by chilong 01/24/2002
// program the flash block
if (NAND_FFS_programFlashBlock(targetBlock, NAND_FFS_BlockCache[cacheNum]) == -1)
{
// flash program error
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " program failed! block = %d", targetBlock);
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_programFlashBlock()
return -1;
}
marked by chilong 01/24/2002 */
// program the flash block
// pData = NAND_FlashAccessBuffer1;
pData = NAND_FFS_BlockCache[cacheNum];
frameNO = NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
offset = (targetBlock + NAND_FFS_START_BLOCK) * NAND_FLASH_BLOCK_SIZE;
for (i = 0; i < NAND_LumpNum; i++)
{
if ( ((struct NAND_diskLump*)pData)->type == NAND_LUMP_TYPE_FREE)
{
// this is a free lump!
// only the lumps not in cache needs to be programmed
offset += NAND_LUMP_SIZE;
pData += NAND_LUMP_SIZE;
continue;
}
// program the lump back to flash
for (j = 0; j < frameNO; j++)
{
sc_disableInt();
nfshProgramFrame(offset, pData);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
pData += NFLASH_FRAME_SIZE;
}
}
// clear the dirty bit
// this is done after erase & program to make sure that the data are written
// back to flash before we can say the cache block are no longer dirty
NAND_FFS_CacheStatus[cacheNum]->flag &= ~NAND_FFS_DIRTY_BIT_MASK;
return 0;
}
/*************************************************************
Function: NAND_FFS_flushCacheByHandle
Description:
flush the cache blocks belonging to the specified handle
Input:
handle - the file handle
Output:
0 flush ok
-1 flush failed
**************************************************************/
int NAND_FFS_flushCacheByHandle(int handle)
{
int i;
int returnValue;
returnValue = 0;
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
// note that the following line only works when there is only one lump per block
if (NAND_FFS_CacheStatus[i]->handle == handle)
{
// cache block belongs to the specified handle, flush it
if (NAND_FFS_flushCache(i) == -1)
returnValue = -1; // errno set by NAND_FFS_flushCache()
}
}
return returnValue;
}
/*************************************************************
Function: NAND_FFS_flushAllCache
Description:
flush the whole cache
Input:
none
Output:
0 all cache blocks flush ok
-1 some cache blocks failed flushing
**************************************************************/
int NAND_FFS_flushAllCache(void)
{
int i;
int returnValue;
returnValue = 0;
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
if (NAND_FFS_flushCache(i) == -1)
returnValue = -1; // errno set by NAND_FFS_flushCache()
}
return returnValue;
}
/*************************************************************
Function: NAND_FFS_putBlockInCache
Description:
Put a new block into the cache
Input:
newBlock - the block to be cached
readFlag - 1 = read data from flash to cache
0 = does not copy
Output:
the cache number if swap ok
-1 if swap failed
**************************************************************/
#ifdef NAND_FFS_CACHE_DEBUG
int NAND_FFS_putBlockInCache(int newBlock, int readFlag, char bFromReadLump)
#else
int NAND_FFS_putBlockInCache(int newBlock, int readFlag)
#endif
{
int i;
int cacheNum;
unsigned long oldest;
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_CACHE_DEBUG
char bFreeCache = 0;
#endif
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_putBlockInCache] block = %d", newBlock);
SprintStringLn(NAND_FFS_DebugString);
#endif
// find the least recently modified cache block
oldest = 0xFFFFFFFF;
cacheNum = -1;
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
if (NAND_FFS_CacheStatus[i]->block == newBlock)
{
#ifdef NAND_FFS_CACHE_DEBUG
if (bFromReadLump)
numReadHit++;
else
numWriteHit++;
#endif
return i; // already in cache
}
if (NAND_FFS_CacheStatus[i]->block == -1)
{
// this cache block is free, just use it
cacheNum = i;
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_CACHE_DEBUG
bFreeCache = 1;
#endif
/**** added by chilong 01/24/2002 ****/
break;
}
if (NAND_FFS_CacheStatus[i]->lastModTime < oldest)
{
oldest = NAND_FFS_CacheStatus[i]->lastModTime;
cacheNum = i;
}
}
if (cacheNum == -1)
{
// unknown error
NAND_FFS_Errno = ERROR_FILE_SYSTEM;
return -1;
}
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_CACHE_DEBUG
if (bFromReadLump)
numReadMiss++;
else
numWriteMiss++;
#endif
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " new block put in cache %d", cacheNum);
SprintStringLn(NAND_FFS_DebugString);
#endif
// the cache block 'cacheNum' is least recent used, swap it out
// flush the cache
if (NAND_FFS_flushCache(cacheNum) == -1)
{
// flush failed, clear the cache
NAND_FFS_clearCache(cacheNum);
}
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_CACHE_DEBUG
if (bFreeCache != 1)
numSwap++;
#endif
/**** added by chilong 01/24/2002 ****/
if (readFlag == 1)
{
// read specified block to cache
if (NAND_FFS_readFlashBlock(newBlock, NAND_FFS_BlockCache[cacheNum]) == -1)
{
// read failed
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " read failed block = %d", newBlock);
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_readFlashBlock()
return -1;
}
}
// update cache status
NAND_FFS_CacheStatus[cacheNum]->block = newBlock;
NAND_FFS_CacheStatus[cacheNum]->handle = NAND_FFS_CurrentHandle;
// NAND_FFS_CacheStatus[cacheNum]->checksum = calcrc32(NAND_FFS_BlockCache[cacheNum], NAND_FLASH_BLOCK_SIZE);
// modified by chilong 01/24/2002
NAND_FFS_CacheStatus[cacheNum]->checksum = calcrc32(NAND_FFS_BlockCache[cacheNum], NFLASH_FRAME_SIZE);
NAND_FFS_CacheStatus[cacheNum]->lastModTime = sc_getTimeStamp();
NAND_FFS_CacheStatus[cacheNum]->flag = 0;
return cacheNum;
}
/*************************************************************
Function: NAND_FFS_modifyCache
Description:
modify the cache content
Input:
cacheNum - the target cache number
Output:
none
**************************************************************/
void NAND_FFS_modifyCache(int cacheNum)
{
// NAND_FFS_CacheStatus[cacheNum]->checksum = calcrc32(NAND_FFS_BlockCache[cacheNum], NAND_FLASH_BLOCK_SIZE);
// modified by chilong 01/24/2002
NAND_FFS_CacheStatus[cacheNum]->checksum = calcrc32(NAND_FFS_BlockCache[cacheNum], NFLASH_FRAME_SIZE);
NAND_FFS_CacheStatus[cacheNum]->lastModTime = sc_getTimeStamp();
NAND_FFS_CacheStatus[cacheNum]->flag |= NAND_FFS_DIRTY_BIT_MASK;
return;
}
/*************************************************************
Function: NAND_FFS_searchBlockInCache
Description:
search the specified block in cache
Input:
block - the specified block
Output:
the cache number if found
-1 if not found
**************************************************************/
int NAND_FFS_searchBlockInCache(int block)
{
int i;
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
if (NAND_FFS_CacheStatus[i]->block == block)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[SEARCH: block in cache %d]", i);
SprintStringLn(NAND_FFS_DebugString);
#endif
return i;
}
}
// block not in cache
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[SEARCH: block not in cache]");
SprintStringLn(NAND_FFS_DebugString);
#endif
return -1;
}
#endif // #ifdef NAND_FFS_USE_CACHE
#endif // #ifdef FLASH_DISK_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -