📄 nandlump.c
字号:
/**** added by chilong 01/18/2002 ****/
int NAND_findFreeLump(void)
{
int i;
int result;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_findFreeLump]");
SprintStringLn(NAND_FFS_DebugString);
#endif
for (i = 0; i < NAND_TotalLumpNum; i++)
{
if( ((NAND_FFS_lumpMapTable[NAND_FFS_curFreeLumpNo/8] >> ((NAND_FFS_curFreeLumpNo)%8)) & 0x01) == 0x01)
{
/*
if ( (NAND_FFS_curFreeLumpNo+NAND_LumpNum) < NAND_TotalLumpNum)
NAND_FFS_curFreeLumpNo += NAND_LumpNum;
else
NAND_FFS_curFreeLumpNo = (NAND_FFS_curFreeLumpNo+1) % NAND_LumpNum;
*/
if ( (NAND_FFS_curFreeLumpNo+1) < NAND_TotalLumpNum)
NAND_FFS_curFreeLumpNo += 1;
else
NAND_FFS_curFreeLumpNo = 1;
continue;
}
else
{
if (NAND_readLumpStructure(NAND_FFS_curFreeLumpNo, 2) != NULL)
{
/* marked
// set this lump "USED" in lumpMapTable
result = NAND_FFS_curFreeLumpNo;
NAND_FFS_lumpMapTable[NAND_FFS_curFreeLumpNo/8] |= (1 << (NAND_FFS_curFreeLumpNo%8));
if ( (NAND_FFS_curFreeLumpNo+NAND_LumpNum) < NAND_TotalLumpNum)
NAND_FFS_curFreeLumpNo += NAND_LumpNum;
else
NAND_FFS_curFreeLumpNo = (NAND_FFS_curFreeLumpNo+1) % NAND_LumpNum;
break;
*/
// set this lump "USED" in lumpMapTable
result = NAND_FFS_curFreeLumpNo;
NAND_FFS_lumpMapTable[NAND_FFS_curFreeLumpNo/8] |= (1 << (NAND_FFS_curFreeLumpNo%8));
if ( (NAND_FFS_curFreeLumpNo+1) < NAND_TotalLumpNum)
NAND_FFS_curFreeLumpNo += 1;
else
NAND_FFS_curFreeLumpNo = 1;
break;
}
else
{
/*
if ( (NAND_FFS_curFreeLumpNo+NAND_LumpNum) < NAND_TotalLumpNum)
NAND_FFS_curFreeLumpNo += NAND_LumpNum;
else
NAND_FFS_curFreeLumpNo = (NAND_FFS_curFreeLumpNo+1) % NAND_LumpNum;
*/
if ( (NAND_FFS_curFreeLumpNo+1) < NAND_TotalLumpNum)
NAND_FFS_curFreeLumpNo += 1;
else
NAND_FFS_curFreeLumpNo = 1;
}
}
}
if (i == NAND_TotalLumpNum)
{
NAND_FFS_Errno = ERROR_DISK_FULL;
return NAND_END_LUMP;
}
return result;
}
/**** added by chilong 01/18/2002 ****/
/* marked by chilong 01/18/2002
int NAND_findFreeLump(void)
{
struct NAND_diskLump *lumpPtr = NULL;
int block;
int i;
int result;
int nthLumpEntry;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_findFreeLump]");
SprintStringLn(NAND_FFS_DebugString);
#endif
block = NAND_FFS_findLeastErasedNonFullBlock(&nthLumpEntry);
if (block != -1)
{
// this block has the least erase count and unoccupied lumps
if (nthLumpEntry == NAND_LumpNum - 1)
NAND_FFS_Block[block] = NAND_FB_FULL;
// added by chilong 01/18/2002
NAND_FFS_lumpMapTable[(block*NAND_LumpNum+nthLumpEntry)/8] |=
1 << ((block*NAND_LumpNum+nthLumpEntry)%8);
// added by chilong 01/18/2002
return (NAND_LumpNum * block + nthLumpEntry); // first free lump in the block
}
// no empty lump found
// the block is full
// NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
NAND_FFS_Block[block] = NAND_FB_FULL;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " no free lump!");
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_Errno = ERROR_DISK_FULL;
return NAND_END_LUMP;
}
marked by chilong 01/18/2002 */
/*************************************************************
Function: NAND_findFreeLumpByAdjLump
Description:
find a free lump in the same block as the specific lump
Input:
lump - the specific lump
Output:
the lump number
NAND_END_LUMP if not found
**************************************************************/
/* marked by chilong 12/20/2001 temporarily
int NAND_findFreeLumpByAdjLump(int lump)
{
int block;
int nThEntry;
struct NAND_diskLump *lumpPtr;
int i;
int result;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_findFreeLumpByAdjLump] lump = %d", lump);
SprintStringLn(NAND_FFS_DebugString);
#endif
// if a block can only hold one lump, there is no adjacent lump
if (NAND_LumpNum <= 1)
return NAND_END_LUMP;
// find the flash block in which the specific lump resides
NAND_lump2Block(lump, &block, &nThEntry);
if (block == -1 || nThEntry == -1)
{
// errno set by NAND_lump2Block()
return NAND_END_LUMP;
}
// read the block into buffer
if (NAND_FFS_readBlock(block, (unsigned char **)&lumpPtr) == -1)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " block invalid");
SprintStringLn(NAND_FFS_DebugString);
#endif
// errno set by NAND_FFS_readBlock()
return NAND_END_LUMP;
}
if (lumpPtr == NULL)
{
NAND_FFS_Errno = ERROR_FLASH_BLOCK_READ;
return NAND_END_LUMP;
}
// check the lumps in the block
for (i = 0; i < NAND_LumpNum; i++)
{
if (lumpPtr->type == NAND_LUMP_TYPE_FREE)
{
result = block * NAND_LumpNum + i;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " free lump = %d", result);
SprintStringLn(NAND_FFS_DebugString);
#endif
if (i >= (NAND_LumpNum - 1))
{
// the last lump in the block => block will be full
// NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
NAND_FFS_Block[block] = NAND_FB_FULL;
}
return result;
}
lumpPtr = (struct NAND_diskLump *)((unsigned long)lumpPtr + NAND_LUMP_SIZE);
}
// the block is full
// NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
NAND_FFS_Block[block] = NAND_FB_FULL;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " no adjacent free lump");
SprintStringLn(NAND_FFS_DebugString);
#endif
return NAND_END_LUMP;
}
marked by chilong 12/20/2001 temporarily */
/*************************************************************
Function: NAND_checkLumpNum
Description:
check if the lump address is valid
Input:
lump - the specific lump
Output:
0 lump ok
-1 lump invalid
**************************************************************/
/* marked by chilong 12/20/2001 temporarily
int NAND_checkLumpNum(int lump)
{
int block;
if (lump == -1)
return -1;
// find the block holding this lump and the entry number of this lump in the block
block = lump / NAND_LumpNum;
// check if the block is valid
// if there is error, errno will be set by NAND_FFS_checkBlock()
return (NAND_FFS_checkBlock(block));
}
marked by chilong 12/20/2001 temporarily */
/*************************************************************
Function: NAND_lump2Block
Description:
convert lump to block and entry
Input:
lump - the specific lump
Output:
block the block number
nthEntry the entry number in the block
both equal to -1 if error
**************************************************************/
void NAND_lump2Block(int lump, int *block, int *nthEntry)
{
*block = lump / NAND_LumpNum;
*nthEntry = lump % NAND_LumpNum;
// check if the block is valid
if (NAND_FFS_checkBlock(*block) == -1)
{
*block = -1;
*nthEntry = -1;
// errno set by NAND_FFS_checkBlock()
return;
}
return;
}
/*************************************************************
Function: NAND_readLumpStructure
Description:
read the data structure of a lump
Input:
lump - the specific lump
lumpType - 0 = get any lump
1 = get only the starting lump
2 = get only the free lump
Output:
the pointer to the lump structure
Note:
If the lump is in cache, the cache content is used.
If the lump is not in cache, the corresponding frames
are read from flash and the cache is kept inact.
**************************************************************/
struct NAND_diskLump *NAND_readLumpStructure(int lump, int lumpType)
{
int frameNum;
int i;
int block;
int nthEntry;
struct NAND_diskLump *base = NULL;
unsigned char *status;
int frame;
#ifdef NAND_FFS_USE_CACHE
int cacheNum;
#endif
/**** added by chilong 01/18/2002 ****/
if (NAND_checkLump(lump) == -1)
return NULL;
/**** added by chilong 01/18/2002 ****/
NAND_lump2Block(lump, &block, &nthEntry);
if (block == -1 || nthEntry == -1)
{
// errno set by NAND_lump2Block()
return NULL;
}
#ifdef NAND_FFS_USE_CACHE
///* marked by chilong 01/25/2002
cacheNum = NAND_FFS_searchBlockInCache(block);
if (cacheNum != -1)
{
base = (struct NAND_diskLump *)((unsigned long)NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE);
// check lump type
switch (lumpType)
{
//
//case 1:
// if (base->type != NAND_LUMP_TYPE_START)
// return NULL;
// break;
//
case 2:
if (base->type != NAND_LUMP_TYPE_FREE)
return NULL;
break;
default:
break;
}
return base;
}
// marked by chilong 01/25/2002 */
/* marked by chilong 01/25/2002
#ifdef NAND_FFS_CACHE_DEBUG
cacheNum = NAND_FFS_putBlockInCache(block, 1, 1);
#else
cacheNum = NAND_FFS_putBlockInCache(block, 1);
#endif
if (cacheNum != -1)
{
base = (struct NAND_diskLump *)((unsigned long)NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE);
// check lump type
switch (lumpType)
{
//
//case 1:
// if (base->type != NAND_LUMP_TYPE_START)
// return NULL;
// break;
//
case 2:
if (base->type != NAND_LUMP_TYPE_FREE)
return NULL;
break;
default:
break;
}
return base;
}
else
{
// unknown error
return NULL;
}
marked by chilong 01/25/2002 */
#endif
frameNum = ( (sizeof(struct NAND_diskLump) - 1) / NFLASH_FRAME_SIZE) + 1;
//frame = lump * NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
frame = (NAND_FFS_START_BLOCK*NAND_FLASH_BLOCK_SIZE + lump*NAND_LUMP_SIZE) / NFLASH_FRAME_SIZE;
/**** modified by chilong 01/15/2002 ****/
// chilong: we point "base" to NAND_FlashAccessBuffer2 because
// we collaborate this function with NAND_findfreeLump()
// in NAND_FFS_write_r()
status = NAND_FlashAccessBuffer2;
base = (struct NAND_diskLump *)NAND_FlashAccessBuffer2;
/**** modified by chilong 01/15/2002 ****/
for (i = 0; i < frameNum; i++)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "Read frame %d", frame);
SprintStringLn(NAND_FFS_DebugString);
#endif
if (NAND_FFS_fshFrameRead(frame, status) == -1)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "Read frame %d failed!", frame);
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_Errno = ERROR_FRAME_READ;
return NULL;
}
// check lump type
switch (lumpType)
{
/* marked by chilong 12/24/2001
case 1:
if (base->type != NAND_LUMP_TYPE_START)
return NULL;
break;
marked by chilong 12/24/2001 */
case 2:
if (base->type != NAND_LUMP_TYPE_FREE)
return NULL;
else
return base;
break;
default:
break;
}
frame++;
status += NFLASH_FRAME_SIZE;
}
return base;
}
/**** added by chilong 01/12/2002 ****/
/*************************************************************
Function: NAND_checkLump
Description:
check if the lump address is valid
Input:
lump - the specific lump
Output:
1 lump address ok
0 lump address out of bound
**************************************************************/
int NAND_checkLump(int lumpNo)
{
int block, nThEntry;
/**** added by chilong 01/18/2002 ****/
if (NAND_checkBadLump(lumpNo) == -1)
{
/**** added by chilong 01/19/2002 ****/
NAND_FFS_lumpMapTable[lumpNo/8] |= (1 << (lumpNo % 8));
/**** added by chilong 01/19/2002 ****/
return -1;
}
/**** added by chilong 01/18/2002 ****/
// chilong: NAND_FFS_checkBlock is invoked insided NAND_lump2Block
NAND_lump2Block(lumpNo, &block, &nThEntry);
if (block == -1 || nThEntry == -1)
{
// errno set by NAND_lump2Block()
return -1;
}
return 0;
}
/**** added by chilong 01/12/2002 ****/
#endif // #ifdef NAND_FLASH_DISK_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -